David L. Nicol wrote:
> "Randal L. Schwartz" wrote:
> >
> > I think we need a distinction between "looping" blocks and
> > "non-looping" blocks. And further, it still makes sense to
> > distinguish "blocks that return values" (like subroutines and map/grep
> > blocks) from either of those. But I'll need further time to process
> > your proposal to see the counterarguments now.
>
> In the odd parallel universe where most perl 6 flow control is handled
> by the throwing and catching of exceptions, the next/last/redo controls
> are macros for throwing next/last/redo exceptions. Loop control
> structures catch these objects and throw them again
> if they are labeled and the label does not match a label the loop control
> structure recognizes as its own.
The more I think about this, and about why I like the way perl does
it currently, the more I think it would be a Bad Idea to unify the
various block types as I (and others) have previously suggested.
And it all boils down to the scope of returns, including non-local
returns (last and die).
It is hard to argue that perl's current setup is not powerful.
sub foo {
eval {
for (...) {
# all these go to different places:
last;
die;
return;
}
};
}
sub foo {
# and these as well:
last;
die;
return;
}
for (...) {
eval {
foo();
};
}
to give but two possible combinations.
In a nutshell, there are different kinds of blocks, and their
escape mechanisms are triggered by different keywords.
By unifying the block types, and making the keywords work across
all of them, I'm afraid we would lose this ability to jump up
through the layers of scope to "the right place".
The issue we've been struggling with is essentially the fact that
map/grep blocks don't have a similar early-exit mechanism.
One approach is to make them the same as one of our other block
types (sub, loop, eval); another is to add a new keyword to
implement the early exit.
Most folks seem to think that a grep block is more like a loop
block, and so want to use C<last>; I have been more of the
opinion that a grep block is more like a sub, and so should use
C<return>. In the other camp, C<yield> has been suggested; but
the conflation of that with its thread-related semantics may not
be a such good idea.
--
John Porter
We're building the house of the future together.