Bob Rogers wrote:
> Allison Randal wrote:

The proposal starts off talking about Perl 5's 'local' and Perl 6's 'temp'. They are lexical in nature (though they're more feature-rich than simple lexicals). They only exist within a specific lexical scope, and "roll back" on exiting that scope.

They do "roll back" on block exit, but that is a statement about
lifetime, not scope.  The whole point of dynamic binding is that such
bindings are visible outside of the sub where they are bound, which by
definition makes them "not lexical" in scope.  Do you disagree?

The whole point of 'temp' and 'local' is that the bindings aren't visible outside the scope where they're defined (whether that scope is a sub, block, etc).

Why would dynamic binding only apply to globals? Perl 5's 'local' doesn't apply to lexicals, but Perl 6's 'temp' will.

Because I have been assuming that these language constructs *always*
introduce a new binding, which is trivial for lexicals, as I've already
said:  Just allocate a new register and you're done.  The extra
mechanism is only needed for globals because only global bindings are
potentially visible outside the compilation unit that creates the
binding (but I've said that, too).

Also not a valid assumption for 'temp' and 'local'.

   But then, prompted by your response, I took another look at S04 and
found the following statement near the end of the first section:

            C<temp> and C<let> temporize or hypotheticalize the value or
            the variable depending on whether you do assignment or
            binding.

This could mean that "temp" and "let" might not always create new
bindings, which would mean that a "rollback" mechanism could indeed be
needed for lexicals.  I assume this statement can be defactored into the
following four:

            C<temp> temporizes the value if you do assignment.
            C<temp> temporizes the variable if you do binding.
            C<let> hypotheticalizes the value if you do assignment.
            C<let> hypotheticalizes the variable if you do binding.

But I'm not at all sure what "assignment" vs "binding" means here, since
it appears to refer to syntax that is not shown.  I'm also unsure that I
understand the difference between temporizing/hypotheticalizing values
vs. variables; is this a question of morphing a PMC vs. replacing it in
its container?

To put it in Parrot terms: An assignment passes the value of one PMC to an existing PMC and lets the receiving PMC decide what to do with the value. A binding replaces the PMC stored in the namespace or lexical pad with another PMC.


A more explicit phrasing of my comment about "local value" is: "In the case of a global variable shared across threads, this proposal would make it possible to have a version of the variable local to one specific thread, so changes to that variable within that thread do not affect the variable's value in the other threads." I consider this to be the most interesting idea put forth in the proposal.

For the record, the concept is far from original.  That's essentially
how dynamic bindings behaved on the Lisp Machine of yore, though the
mechanism proposed is different.

   Besides, dynamic binding is not supposed to be interesting; it's
supposed to be cheap, simple, and boring, so that it can be used to
implement the *really* interesting stuff.  ;-}

Aye, but it's a new idea for Parrot.

   However, your use of the phrase "a version of the variable" makes me
wonder if I understand you properly.  Does this mean "a variable
binding"? If so, why avoid this well-established terminology?

Just being explicit. Many a conversation has gone wrong because two people are using the same words to mean different things.

And in
any case, I still don't understand in what sense such a variable could
be "shared across threads" if the binding is not?  It seems to me that
sharing only the variable name is not sharing the variable.

The variable is still shared if you can "unbind" it at some point and then have access to the shared value. The shared value is stored somewhere in thread.

Could you be more specific about the proposed implementation?  What
issues do you have with it?  Is it worth fixing, or should I give up?

Mainly, I don't see the proposal as it stands as a solution for 'temp' and 'local'. Dynamic binding as you define it (what I'm calling thread-locals), is a completely different problem. The proposal needs a description of the problem it is solving, instead of describing one problem and solving a different one.

Also, the particular implementation suggested -- the Location class hierarchy of abstract and instantiable classes, the stack of stored values -- is more heavy weight than the underlying concept merits. I see thread-locals as a feature to integrate into the sharing architecture of the core concurrency model.

So yeah, the proposal is worth working on, if you're interested in pushing the idea to the next level. If you're not interested in going there, you have raised an interesting idea, so many thanks!

As a compiler
writer, the only thing I find "unhelpful" about Parrot in terms of
scoping is its lack of dynamic binding.

That would be useful information. What are the practical problems you're working on that would be made easier with thread-locals? How will the feature be used by HLLs? How will it be used in Parrot's internal code (compiler tools, etc)?

Allison

Reply via email to