On Wed, Sep 24, 2008 at 10:11:07PM -0400, Bob Rogers wrote:
> 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]
>         [...]
>         ## 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?

It's just an artifact of how I was originally thinking code generation
might look -- you're correct, we only need it once.

>    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]

That's a valid approach also (and one I also considered that the
design should support -- taking a clone prior to capture_lex).  
I _hadn't_ thought of the concurrency angle, though, and I agree
there could be a race condition here.  However, the way I described
it (capture_lex then clone) is the way that Synopsis 4 currently
describes the bindings to take place, so I went with that.  
It'll be interesting to see how that plays with concurrency.

>    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.

I agree it could be a useful optimization, but I'll leave that
decision to Allison and others.  I'm just trying to get something
that works for Perl 6.  :-)

>    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.)

Given the way that code generation is currently working in PCT and
Perl 6, I'm finding that register mapping of lexicals has _very_ limited
utility, at least for languages (such as Perl 6) where binding is a
much less common operation than assignment.  So converting LexPads to
store PMCs instead of register mapping might indeed be an improvement.
It would probably also help with things like iterating over LexPads 
(which we can't seem to do at the moment).

Pm

Reply via email to