From: "Patrick R. Michaud" <[EMAIL PROTECTED]> Date: Tue, 23 Sep 2008 03:45:37 -0500
I've put together a draft with my ideas and design for (re-)implementing lexicals in Parrot -- now available at http://www.pmichaud.com/perl6/lexical.txt . It's a first draft and might be a bit confusing in places, but overall I think it's a far cleaner design than the current implementation but also handles the vast bulk of what we need (or can be made to do so easily). Anyway, comments greatly appreciated. Pm Just a few: 1. In the translation of your Perl 6 example in "Runtime part 3: Closures and cloning", I notice that you do "get_global 'bar'" twice: .sub 'foo' ## bind inner sub 'bar' to current lexical environment $P0 = get_global 'bar' capture_lex $P0 ## ['bar' updated by side-effect] ## my $x = 1 $P1 = new 'Int' $P1 = 1 .lex '$x', $P1 ## return &bar $P2 = get_global 'bar' ## [updated 'bar' refetched] ## clone 'bar', preserving current lexical environment $P2 = clone $P2 ## [new 'bar' copy created] .return ($P2) .end Is this just an artifact, or is there something I'm missing? In any case, this looks like it has a race condition. If another copy of 'foo' is running concurrently, the other copy's "capture_lex" might happen before our "capture_lex" and "clone". Perhaps it would be better to suggest the following as the standard idiom: $P2 = get_global 'bar' ## [original 'bar'] $P2 = clone $P2 ## [new 'bar' copy created] capture_lex $P2 ## [copy updated] This "clone/capture_lex" combination acts as a drop-in replacement for "newclosure", and avoids capturing the outer context in a global (so that it could be garbage-collected sooner). 2. Compilers often know how many contexts outward to look when resolving a lexical reference; it might be useful to add another integer parameter to find_lex in order to support this optimization. 3. Since the whole context is captured, all of the :outer sub variables are preserved from GC for the life of all closures made for inner subs. That could be avoided if the LexPad stored the PMCs directly and not just their register indices. Doing so would require that the :outer sub also do store_lex and find_lex on lexical variables, and not just the inner ones. (That could be a drawback or a feature, depending on your point of view.) -- Bob Rogers http://rgrjr.dyndns.org/