Perhaps ignore my earlier message -- this one is more coherent. On Fri, Aug 03, 2007 at 03:37:39PM -0700, Bob Rogers wrote: > sub make_closures_loop { > # Return $n closures, each with lexical references to $i and $n. > my $n = shift; > > my @result; > for (1..$n) { > my $i = $_; > push(@result, sub { print "Called sub $i out of $n.\n"; }); > } > return @result; > } > > Currently, the only way to get a distinct binding for each "$i" in > PIR is to factor the loop body out into a separate lexical sub. This is > far from ideal, not least because it is not transparent to the HLL user.
Factoring the loop body out into a separate lexical sub is _exactly_ how Chip described to me that the above needed to be done. Or, phrased differently, every lexical scope ends up requiring its own parrot sub (with appropriate :outer pragmas), and the compiler can optimize out such subs when it determines that there aren't any new lexicals being declared within the loop body (which somewhat comes down to keeping track of whether the loop body contains any "my" declarations). I'm not sure why this separate lexical sub has to be visible to the HLL user -- the compiler ought to be able to make it appear as though the sub isn't present. (But I also bet that we can come up with an example that makes it really hard to do that.) > Parrot should do better, IMHO. The easiest way, it seems, would be > to resurrect the push_pad and pop_pad instructions in some form. [...] I'd like for Parrot to be able to do better, yes, but I'm not yet enough of an expert on closure handling to be able to refute Chip's reasons for designing things this way. I also found the push_pad and pop_pad model somewhat easier to grasp conceptually, but I recall Chip was fairly certain that they wouldn't handle things in the generic case. FWIW, the perl6 compiler currently treats _every_ block as a new lexical scope, and generates a separate Parrot sub for each. At some point we will add an optimization so that blocks can be inlined when the compiler determines that it's safe to do so (based in part on the absence of any lexical declarations within the block). Hope this helps somewhat more than my previous message... :-) Pm