Allison wrote:
> As I was talking to Damian, he came up with a compelling semantic
> argument why we would want C<else> blocks to follow, which is a question
> that needed to be faced since we rejected C<continue>.
Specifically, the semantic argument with that idea is that CAPITAL blocks
attach automatic behaviours to a surrounding scope, but the C<ELSE> behaviour
is specifically *not* associated with the surrounding block. Or rather:
specifically associated with the *not* of the surrounding scope.
Either way, that would make embedded C<ELSE>s seem highly counter-intuitive to me.
> And the discussion of scope led to (what I think is) an interesting
> tidbit on NAMED blocks...
Which I presume was that the proposed usage:
while $result.get_next() -> $next {
# do something with $next...
ELSE {
if $next eq "xyz572" {
print "We defined this value, $next, as false for obscure purposes.";
print "No loop was executed. Just wanted to let you know.";
}
}
}
would actually be a (very subtle and nasty) bug!
The construct:
-> $next {...}
is, of course, an anonymous subroutine declaration. Hence C<$next> is a parameter,
the binding of which only occurs when the subroutine is invoked (i.e. on each
iteration). However, if the C<while> condition fails, the subroutine *isn't*
invoked, so C<$next> isn't bound, so the nested C<ELSE> block (even if it were
fired off separately) wouldn't work as expected.
This leads me to conclude that a normal (trailing, un-nested) C<else> is a
much more reasonable construct for a C<while> -- and at least arguable for a C<for>.
The argument in its favour is simply that it eliminates two not-unusual -- but
very annoying -- constructions involving repeated tests. Namely:
if (some_test) {
while (some_test) {
...
}
}
else {
...
}
and the more error prone (because it assumes C<some_test> is idempotent):
while (some_test) {
...
}
unless (some_test) {
...
}
And it replaces them with a very DWIMish alternative:
while (some_test) {
...
}
else {
...
}
I haven't seen those annoying constructions used as often with C<for> loops,
but I imagine they might well occur more frequently in Perl 6, where lazy
iterators will make C<for> loops the preferred choice in a far wider range of
circumstances.
> And something just feels right about C<else> blocks on loops. It fits in
> with that Perlish pattern of allowing structures that feel so natural
> you wonder why no other language ever allowed them.
Yes. That's one of Larry's greatest talents: doing the obvious-in-hindsight. :-)
Damian