-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 4/14/2010 11:30 AM, David Herman wrote: >>> function foo(...) { f->(...); g->(...); } >> [snip] >> Of course, and I certainly understand how continuations reify the >> frame(s), and how traditional continuations preserve the stack, but I >> don't follow how to preserve the stack when you have broken the >> continuations apart into separate autonomous single-frame >> continuations. > > Single-frame continuations capture a single frame. That's all there is to it-- there's nothing else to preserve. You suspend a single frame, save it in a data structure, and when it comes time to resume it, you place it back on the top of your current stack. > > If the frame is on top of some larger continuation, you *cannot* and *must not* save any of the rest of that continuation. That's the whole point of single-frame continuations. They aren't *supposed* to save the rest of the continuation. If you did, they wouldn't be single-frame continuations any more. They'd be full continuations. Exactly, I'm glad we are on the same page about that, I was hoping there wasn't some crazy magic be suggested. > > If, for the sake of diagnostics, you would like to capture some diagnostic information for e.g. better stack trace information, your VM can certainly take a snapshot of the current full stack (basically, save a stack trace) at the point of suspending the continuation, and carry that around in case an exception gets thrown later on when the continuation is resumed. > > But beyond that, I still don't know what you mean by "preserve the stack." My assertion is that with the proper API, libraries (that understands the call structures) can reconstruct a call stack (collectively using the individual continuations) to make it easy to debug. But due to the complexity and difficulty of demonstrating how this work, I am now convinced that this could and should be a separate API/function rather be integrated into the core semantics of the continuations. Obviously explaining the call stack API needs more effort. I still think it is valuable, but I am fine with it being separate no longer considered for the core semantics. It can be discussed sometime in the future as an extension. > [snip] >>> Earlier in this thread, I demonstrated a simple single-frame >>> semantics and shown how generators could pretty easily be layered >>> on top of it... >> >> Sorry, I thought you were suggesting that it was difficult to >> understand my specification of the semantics and code translation and >> need it be more clearly written. Your example of the generator library >> provides neither. > > My example of the generator library was not the proposed semantics. See > > https://mail.mozilla.org/pipermail/es-discuss/2010-March/010866.html Oops, my apologies, I didn't realize you were referring to that email, yes that is clear. > > I wrote: > >> semantics of <expr> "->" <arg-list>: >> >> 1. Evaluate the LHS expression and then the argument expressions >> 2. Let *k* be the current function continuation (including code, stack frame, and exception handlers). >> 3. Exit the current activation. >> 4. Call the LHS value with the argument values followed by *k*. >> 5. Return the result of the call. >> >> semantics of calling *k* with argument *v* (defaults to the undefined value): >> >> 1. Create a new function activation using the stack chain from the point of capture. >> 2. Reinstall the function activation's exception handlers from the point of capture (on top of the exception handlers of the rest of the stack that has called *k*). >> 2. Use *v* as the completion of the point of capture. >> 3. Continue executing from the point of capture. > > I thought this was reasonably clear, or at least, at the time you sounded like you thought it was clear. Indeed, and with the shift in syntax (taking a single value), and API (generator style), I like this. > Alternatively, I could sketch it out as a rough reduction rule, operational-semantics-style: > > S(A(f->(v1, ..., vn))) > ----> S(f(v1, ..., vn, function (x) A(x))) > > As I suggested in my blog post, this has the problem that the call to `f' loses the catch and finally blocks of A. In my post I suggested the alternative: > > S(A(f->(v1, ..., vn))) > ----> S(A(let (result = f(v1, ..., vn, function (x) A(x))) { return result })) > > But, as Waldemar pointed out, this is wrong, too. In fact, I'm about at the point where I don't believe a feature based on function calls will be workable, due to `finally'. I don't see any way of ensuring the invariant (expected by ES programmers) that a `finally' block will be executed at most once per activation while at the same time having *both* the continuation *and* the function called via -> be protected by the same `finally' block. > > I've described the issue here: > > http://calculist.blogspot.com/2010/04/single-frame-continuations-for-harmony.html > Don't you preserve this invariant by enforcing single-shot continuations? Not sure why the -> syntax gets in the way of that. >> 1. The biggest problem with the semantics you propose is that it fails >> to provide a means for resuming a continuation with a thrown error. > > I agree it's an omission, but disagree that it's the biggest problem. It's fixable in a couple different ways. Your suggestion is one; another is to represent a continuation as an object with both `send' and `throw' methods, a la generators. Yes, that sounds great to me. And actually that makes easier to add a function in the future for call stack preservation. > > IMO, the biggest problem is `finally'. I have doubts whether it's surmountable at all, at least with a form like `->' (as opposed to something like `yield'). > >> 2. I am opposed to the notion of appending the continuation resume >> function on to the list of arguments. > > I pretty much agree with this point. But the bigger fish to fry is the basic control flow story. Cool, then I think we are mostly in agreement on how -> could work. > > It still might be possible to sketch a simple semantics based on a `yield'-like construct. But I wouldn't be surprised if it ended up looking a lot like JS 1.7 / Python generators. > If that approach is still of interest, I'll throw out some ideas on the other thread. - -- Kris Zyp SitePen (503) 806-1841 http://sitepen.com -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkvKgm0ACgkQ9VpNnHc4zAwyYgCgo85mlMR6fMgIHYUmnz5NLnEY jq4AoLKjifUrRmVmn0cTO00ajdvH1Gdl =UCau -----END PGP SIGNATURE----- _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss