On Thu, Jul 10, 2008 at 12:29:57AM -0400, Bob Rogers wrote: > From: "Patrick R. Michaud" <[EMAIL PROTECTED]> > Date: Wed, 9 Jul 2008 18:49:53 -0500 > > On Wed, Jul 09, 2008 at 04:46:19PM -0400, Bob Rogers wrote: > > Not true. The compiler always knows when it's compiling a closure. So > > if, at the point of definition, the emitted code does: > > foo_closure = newclosure foo_sub > > set_hll_global 'foo', foo_closure > > then the compiler doesn't have to treat calls to "foo" specially. > > Yes; because I think that is what the code means. Indeed, I think you > yourself have already suggest that making closures in a loop requires > newclosure anyway [0]. Or are you saying that this case is different?
I think misread what you originally wrote, not seeing the difference between 'foo_sub' and the global 'foo'. Sorry about that. > Shouldn't > for 1..10 -> $x { > sub foo() { say $x; } > push(@foos, \&foo); > } > produce the same result as > for 1..10 -> $x { > my $foo = sub { say $x; }; > push(@foos, $foo); > } > modulo global namespace mangling (and broken Perl 6 syntax)? And if > not, why not? Yes, the two examples above would be the effectively the same, but neither of them are the same as my original. Perl 6 recognizes taking a closure at the point where a sub is referenced (used as an rvalue), so in the first example we would do the newclosure at the &foo reference inside the push() call, the second example we would do the newclosure as part of the "my $foo" assignment. But according to Synopsis 4 [1], if we simply define foo and call it directly (as opposed to taking a reference), we don't take that snapshot of its lexical scope. (I'm making the leap that "takes a snapshot" in the Synopsis means "newclosure" in Parrot.) > Also, we can't do this exactly at the point of definition, because > sub calls can lexically occur before the definition of the thing > they're calling. So it has to be moved higher in the block somehow. > > Eh? Can't do what at the point of definition? Do you have an example? By "this" I meant "take a newclosure and store it in the symbol table". The following is valid Perl 6: my $x = 'hello'; foo(); sub foo() { say $x; } At the point of the foo() call, we have to have already stored an entry in the symbol table for 'foo', thus if we wait until the sub declaration to do that, it's too late. So, we have to move the newclosure+store sequence to a point earlier in the block than where the sub declaration itself occurs. > From: "Patrick R. Michaud" <[EMAIL PROTECTED]> > ...would we also have to generate code to restore the previous > value of 'foo' upon exiting the sub? (Think recursive calls here.) > > sub bar($x) { > sub foo() { say $x; } > if ($x > 0) { bar($x-1); } > foo(); > } > > No. AFAIK, "sub foo() { ... }" always mangles the global definition of > foo. So in Perl 5, the first call wins; in Perl 6, it might be the last > call, but I don't really know. Okay, I wasn't aware of this for Perl 5, so perhaps Perl 6 has similar semantics. But in my head it doesn't seem to match what I read in Synopsis 4 at [1], particularly where S04 says my sub bar { print $x } # not cloned yet (Again I'm making the leap that 'cloning' in the synopsis is what we mean by 'newclosure' in Parrot.) > To summarize, I am not arguing that relying on "autoclose" is > necessarily wrong, and that we should therefore get rid of it. > [...] I don't exactly understand what "autoclose" is (even after reading the other thread) -- my impression is that it refers to invoking or taking a snapshot of an inner sub's lexical environment even when its outer context hasn't been invoked yet. If this limited understanding of "autoclose" is correct, then I don't think my examples are relying on it; but if the examples I'm giving do make use of the "autoclose" feature you keep referring to, then I guess I need to learn more about "autoclose" to be able to talk intelligently about it. Pm [1] http://dev.perl.org/perl6/doc/design/syn/S04.html#When_is_a_closure_not_a_closure