From: Allison Randal <[EMAIL PROTECTED]>
   Date: Sun, 26 Nov 2006 18:14:28 -0800

   Bob Rogers wrote:
   > 
   >    - Overall, I want the implementation of dynamic binding to be tied in 
   >    more closely with the implementation of globals and lexicals. 
   >    Particularly lexicals. They're already operating under the same scope 
   >    constraints as locals. They already have storage for named variables 
   >    relevant to a particular scope, and the mechanism for handling scopes 
   >    within scopes.
   > 
   > I'm afraid I don't follow you, particularly the "operating under the
   > same scope constraints" part.  It seems to me that lexical variables are
   > orthogonal to dynamic/global variables, and dynamic binding is purely a
   > feature of globals.  And lexicals are necessarily simpler, because all
   > possible references are available to the compiler.  So nested scopes are
   > handled by the compiler simply by using a different register.  Globals
   > and dynamic bindings, because they must be visible to code in multiple
   > compilation units, must necessarily use different mechanisms.

   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?

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

   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?

   My apologies if these are Perl 6 FAQs, or the answers turn out to be
irrelevant to Parrot; I figure I ought to know in order to understand
what mechanisms Parrot needs to provide.

   >    - I like the idea of "thread locals": global variables shared across 
   >    threads, but with a local value in one particular thread. I'll have to 
   >    mull that one over some more. It seems fundamentally different from 
   >    "scope locals", to the point of deserving a different way of 
interacting 
   >    with the feature (perhaps more closely tied to the concurrency model 
   >    than to variable storage).
   > 
   > By "local value" I assume you mean "local binding," which (in the
   > version I posted) would indeed be per-thread.  But in what sense are
   > "global variables shared across threads"?  Without the binding, all you
   > have is the name, which isn't terribly variable.
   >
   >    And "scope locals" -- aren't all variables local to their scope by
   > definition, even if that scope happens to be universal?
   > 
   > So I'm pretty sure I must be misunderstanding something . . .

   Your proposal mixes two ideas. One is the idea of 'local'/'temp', the 
   other is thread-level dynamic bindings. (I called these two concepts 
   "scope locals" and "thread locals", but "scoped locals" is probably a 
   better term for the first set.)

Perhaps, but I did mix them deliberately.  After considering several
alternatives, I decided that it was most useful to define "dynamic
scope" as being thread-local.

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

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

   While I'm not accepting the currently proposed implementation, this idea 
   is likely to make it in. Possibly as a lightweight use of STM, possibly 
   as part of the new concurrency model(s), or possibly as a variation on 
   scoped locals.

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?

   >    - We keep adding hacks to get around the fact that Parrot doesn't
   >      handle scopes smaller than a compilation unit particularly well. If we
   >    tackled that quirk, dynamic binding would likely fall out more 
   >    naturally, not to mention exception handlers, lexical variables, etc.
   > 
   > I'm afraid I don't follow this, either.  "Scope" is mostly an HLL
   > concept; what would Parrot need to do to support them better?  Or are
   > you talking about debugger annotation for variable lifetime?

   It's true that scope is an HLL concept, but the whole idea of Parrot is 
   to provide tools for implementing HLLs. Parrot's concept of scope is 
   still quite primitive, and not very helpful to compiler writers.

   Allison

Then I'm still in the dark -- or perhaps just lucky.  As a compiler
writer, the only thing I find "unhelpful" about Parrot in terms of
scoping is its lack of dynamic binding.  Hence, the patch.

                                        -- Bob

Reply via email to