--- Matthijs van Duin <[EMAIL PROTECTED]> wrote:
> On Wed, Mar 19, 2003 at 03:46:50PM -0500, Dan Sugalski wrote:
> 
> >>They should be though, if a variable was hypothesized when the 
> >>continuation was taken, then it should be hypothesized when that 
> >>continuation is invoked.
> >
> >Should they? Does hypotheticalization count as data modification (in
> 
> >which case it shouldn't) or control modification (in which case it 
> >should),
> 
> Isn't that the whole point of hypotheses in perl 6?  You talk about 
> "successful" and "unsuccessful" de-hypothesizing, and about abormals
> exits etc..  you seem to have a much complexer model of hypotheses 
> than what's in my head.

The complex model is right -- in other words, if hypotheses are to be a
first-class part of the language then they must interoperate with all
the other language features.

So there's several ways out of a sub. What does a hypo do in all these
cases?

let $x       - Declares a hypothesis. I think this should be a verb.
               (Which is to say, a function instead of a storage
class.)
               (This in turn suggests that primitive types can't be 
               hypothesized, although arrays thereof could be.)

fail         - Pretty strongly suggests that the hypo is ignored. 
               Also suggests continuation/backtracking behavior. Do we
               really know what fail does? See discard, below.

discard $x   - (suggested) Obvious keyword for failing one single
               hypothesis.

keep $x      - Suggests the value is made permanent. This should be 
               a verb. C<keep> with no args should just keep every 
               hypo in the current <fillintheSCOPE>.

return       - This is unclear. On the one hand, it's a transfer of 
               control and I think that C<let> and C<keep> are data,
               not control, modifiers. On the other hand, it's one of 
               the normal ways to leave a block, and could be argued
               either way.

               (Also: remember the bad old days of C<my> vs. C<local>.
               I propose that hypos fail by default -  to keep the 
               distinction clear in the minds of newbies.)

throw        - Exceptions unwind the call stack. If "let" is a 
               control action, it should undo. If let is a data
               action, it should not. To me, C<let> is an explicit
               action taken against a variable, and should not be
               undone by this. (Of course, if unwinding the call stack
               causes the variable to go out of scope, it's not an
               issue.)

continuation: goto
             - Again: continuations are transfers of control, not 
               data. If "let" is a control action, continuations
               will have to know if they are transferring "back up 
               the stack" or if they are transferring to some new,
               never-before-seen (on the stack) place. I think that
               C<let> should be a data action, in which case this
               doesn't affect the hypothesis. 

generators: yield
             - Same issues, although the argument can be made that 
               since you can resume a generator, the hypo should 
               be confined to the extant-but-inactive scope.


> To me, what 'let' does is temporize a variable except it doesn't get 
> restored if you leave the scope, but only if you use a continuation
> to go back to a point where it wasn't hypothesized yet.

Yes and no.

I agree it shouldn't get restored, see above. However, continuations
don't touch data. So a global variable that has been hypo'ed should
(IMO) remain so after the continuation. 

Frankly, if you mix the two, it's YOUR job to understand the
ramifications.

> When the last continuation taken *before* the hypothesis is gone, so
> is the old version and thus the hypothesized variable becomes 
> permanent.

I disagree. Proposal and acceptance should be explicit actions.

> The behavior regarding coroutines followed naturally from this, and
> so does the behavior inside regexen if they use the "continuation"
> semantics for  backtracking -- which is what I'm suggesting.
> 
> This leave only behavior regarding preemptive threads, which is
> actually very easy to solve:  disallow hypothesizing shared 
> variables -- it simply makes no sense to do that.  Now that 
> I think of it, temporizing shared variables is equally bad news,
> so this isn't something new.

Why?

If you constrain hypotheses to the thread (making it a control action
instead of a data action) this could be a way to get cheap MUXing.
Hypothesize all the new values you wish, then pay once to get a mux,
then keep all the data values while you've got the mux. Shrinks your
critical region:

{: is synchronized($mux)
  keep all;
}

OTOH, if you are really using threads well, then your app may construct
a hypothesis based on user input, and the math and visualizer and gui
threads may all need to work in that hypothetical space.

> >(Which makes continuations potentially more expensive as you need to
> >then save off more info so on invocation you can restore the 
> >hypothetical state)
>
> Actually, I think 'let' can handle this.. it's only invocation of 
> continuations that will become more expensive because it needs to
> deal with the hypothesized variables

Only true if hypo is a control action. See above - make it a data
action.

> >What about co-routines, then? And does a yield from a coroutine
> > count as normal or abnormal exit for pushing of hypothetical 
> > state outward, or doesn't it count at all?
> 
> Your terminology gets rather foreign to me at this point.  Assuming a
> co-routine is implemented using continuations, their behavior follows
> directly from the description above, and I think the resulting
> behavior looks fine.  

> I don't see why people would hypothesize 
> variables inside a co-routine anyway.

My experience has been that when anyone says "I don't see why anyone
would ...", Damian immediately posts an example of why. Unless it's
Damian, in which case Simon, Larry, or Dan usually counterpost.

As such, I've become accustomed to substutiting "I don't see why anyone
would want to." with "Sounds okay to me." -- I learn less, but my head
doesn't hurt as much. :-)

> >I hypotheticalize the variables. I then take a continuation. Flow 
> >continues normally, exits off the end normally, hypothetical values 
> >get pushed out. I invoke the continuation, flow continues, exits 
> >normally. Do I push the values out again?
> 
> If it ends normally, the variable isn't de-hypothesized at all. 
> Also, the continuation was created *after* you hypothesized the 
> variable, so when you invoke it nothing will happen to the variable.

I think the point is that the "hypothetical values get pushed out"
means that end-of-scope := acceptance-of-hypothesis. Regardless, the
hypos get pushed out. The continuation resumes *IN THE LIFESPAN* of the
hypothesis.

If "let" is a control action, then the hypothesis is re-engaged.
If "let" is a data action, it isn't. 

I vote for isn't. (Which means you're writing questionable code. But
you didn't know, so I'll forgive you.)

Aside: FYI, the new ISO C ('99) standard allows dynamically declared
array sizing, but prohibits "goto" from crossing into or outo the
lifespan of such a variable (goto within, or goto outside, but no
crossing the lines). We could make such a rule for hypotheticals, but
frankly I think that would be lame.

> >How? Successfully or unsuccessfully? Does it even *count* as an exit
> >at all if there's a pending continuation that could potentially exit
> >the hypotheticalizing block later?
> 
> You're making 0% sense to me, apparently because your mental model of
> hypothesizing differs radically from mine.

Matthijs: Think about closures.

Dan: Does it count as an exit when a closure exits? Continuations, as I
think you've pointed out a long time ago, translate into scratchpadding
the stack. (stackpads?)


> >No. Honestly I still don't see the *point*, certainly not in regards
> >to regular expressions and rules. The hypothetical issues need 
> >dealing with in general for threads, coroutines, and continuations, 
> >but I don't see how any of this brings anything to rules for the 
> >parsing engine.
> >
> >The flow control semantics the regex/parser needs to deal with are 
> >small and simple. I just don't see the point of trying to make it 
> >more complex.
> 
> More complex ?!
> 
> What I'm suggesting is a simple definition of hypothetical variables
> which makes backtracking easy to do using continuation in the 
> general case, and therefore automatically also by rules.
> 
> Rules can then probably be optimized to *avoid* explicitly use
> continuation to the point where they have the speed you demand,
> while still keeping up appearances of the simple continuation-based 
> backtracking semantics.

So, stop talking about rexen. When everyone groks how continuations
should work, it'll fall out. (And if you reimplement the rexengine
using continuations and outperform Dan's version by 5x or better, then
we'll have another Geek Cruise to Glacier Bay and strand Dan on an
iceberg. :-)


=Austin

Reply via email to