On Wed, 2004-09-01 at 17:00, Larry Wall wrote:

> : Let's get concrete:
> : 
> :     rule foo { a $x:=(b*) c }
> :     "abbabc"
> : 
> : So, if I understand Parrot and Perl 6 correctly (heh, fat chance), a
> : slight modification to the calling convention of the closure that
> : represents a rule (possibly even a raw .Closure) could add a pad that
> : the callee is expected to fill in with any hypotheticals defined during
> : execution.
> 
> Okay, except that hypotheticality is an attribute of a variable's
> value, not of the pad it's in.

Yes, I think I got that part, and perhaps I was being unclear or am
still missing something. Here's what I was saying, a slightly different
way:

As you enter a rule, you establish a new, free-floating pad. It *is*
stored on the current pad stack (so that its variables are available to
the rule and its closures), but, more importantly, it is part of the
rule's state because it is stored in C<$0>

When you bind a hypothetical it goes into this pad.

When you unbind a hypothetical (fail/backtrack) it is deleted from this
pad (its value doesn't just get undef).

When you return from the rule (and this is the key), you return C<$0>,
which, along with other state, contains a reference to this pad (and the
pad, of course contains a circular reference to C<$0>). The caller can
now do one of two things:

      * Push this pad onto its stack. Pro: simple and fast
      * Copy each variable from this pad in a "smart" way, searching up
        the pad stack for a candidate variable to replace, and
        defaulting to storing it in the inner-most pad as a new lexical.

I think the second one is the one you are describing (and described in
A5). The first is, IMHO, the cleaner solution, but I'm not suggesting
anything really, just pointing out the options.

My real point is that if you just establish such a free-floating
"hypopad" (sounds like something Dr. McCoy would use) in the rule, then
you get all of the hypothetical/backtracking behavior that you want,
regardless of how the caller integrates the variables with its scope. It
also keeps rules from having to search up through existing scope levels
themselves, keeping their complexity constrained to what they know best:
matching regular expressions and grammars. Perl's calling conventions
manage all of the extra complexity on return, and that's probably where
stack-walking code should go anyway.

> : Essentially every close-paren triggers binding, and every back-track
> : over a close-paren triggers clearing.
> 
> Yes, that's essentially correct.  My quibble was simply that it may be
> hard to keep track of what to clear out in the case of calling a
> failure continuation.

I'm not sure if that's going to be true or not, as thinking in terms of
failure continuations hurts my brain ;-) Still, I'm 99% sure that what I
describe above puts all of the "what to clear" state in the pad that you
return. Nice and easy.

A side point to Dan: In reading P6&PE, I don't see an op for deleting an
entry from a pad. At least for this, and I think for some other things
that aren't coming to mind right now, it's probably going to be needed.
If it's already there, but just not in P6&PE, cool and thanks! ;-)

-- 
â 781-324-3772
â [EMAIL PROTECTED]
â http://www.ajs.com/~ajs

Reply via email to