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