On 8/3/07, Patrick R. Michaud <[EMAIL PROTECTED]> wrote: > On Fri, Aug 03, 2007 at 03:37:39PM -0700, Bob Rogers wrote: > > A naive PIR implementation of this loop is included as the second > > attachment. It fails miserably, because PIR can't distinguish between > > the different scopes for "$i" and "$n". > > > > 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; > > } > > > > [...] > > > > ## Return n closures, each with lexical references to "I" and "N'. > > .sub make_closures_loop > > .param pmc n > > .lex "$n", n > > .lex "$i", $P42 > > [...] > > > > .sub internal_make_closures_loop_0 :outer('make_closures_loop') > > find_lex $P42, "$i" > > find_lex $P43, "$n" > > [...] > > This seems wrong to me -- shouldn't $i be scoped to the internal > loop instead of the outer one? In other words, I think the PIR > code should read: > > .sub make_closures_loop > .param pmc n > .lex "$n", n > ... > > and then > > .sub internal_make_closures_loop_0 :outer('make_closures_loop') > .lex "$i", $P42 > find_lex $P43, "$n" > ...
No, this is different. Your code puts the scope of $i inside the anonymous sub. In other words, it's this: for (1..$n) { push(@result, sub { my $i = ...; print "Called sub $i out of $n.\n"; }); } Except there's way to initialize $i in this case. (Initializing it from $_ inside the anonymous sub just moves the problem to a different variable.) > Otherwise, the reason that PIR isn't able to distinguish the > scopes is because in PIR you're actually defining them to be > in the same scope. I believe that's exactly Bob's point. > However, I must confess that I still haven't grokked all of the > ramifications of lexicals and closures in PIR yet -- and I may > even be interpreting the p5 translation incorrectly. It just > looks to me as though the "naive translation" isn't being faithful > to the original p5 source, and so perhaps that's causing the > problem you're seeing. Again, I believe this is what Bob was saying: it's not possible to be faithful to the original p5 source without creating a separate subroutine for every loop body. And there are reasons why that's a bad idea (even if that's what they are in Perl 6): - It introduces extra overhead in terms of the compiled code - It's extra work for the compiler – introducing an extra pass for lexical analysis The alternative (which Bob is suggesting) is to reintroduce push_pad/pop_pad so you can create new lexical scopes without using subroutines for loop bodies. His suggestion seems reasonable to me. We won't run into this particular problem with Tcl, but I think most languages will. -- Matt Diephouse http://matt.diephouse.com