
Again, though, you never want to muck with continuations directly! They're too wild. You get an expert to use them in the bowels of an implementation of something else.
[Christian]
Maybe with one exception: With careful coding, you can use a continuation at the head of a very deep recursion and use it as an early break if the algorithm fails. The effect is the same as bailing out with an exception, despite the fact that no "finally" causes would be obeyed. It is just a incredibly fast jump out of something if you know what you are doing.
You don't need continuations for this, though; e.g., in Icon I've done this often, by making the head of the deep recursion a co-expression, doing the recursion via straight calls, and then doing a coroutine resumption of &main when I want to break out. At that point I set the coexp to &null, and GC reclaims the stack frames (the coexp is no longer reachable from outside) when it feels like it <wink>. This is a particularly simple application of coroutines that could be packaged up in a simpler way for its own sake; so, again, while continuations may be used fruitfully under the covers here, there's still no reason to make a poor end user wrestle with them.
... Well, I admit that the continuation approach is slightly too much for the coroutine/generator case,
It's good that you admit that, because generators alone could have been implemented with a 20-line patch <wink>. BTW, I expect that by far the bulk of your changes *still* amount to what's needed for disentangling the C stack, right? The continuation implementation has been subtle, but so far I've gotten the impression that it requires little code beyond that required for stacklessness.
... How about "amb"? :-) (see "teach youself schem in fixnum days, chapter 14 at http://www.cs.rice.edu/~dorai/t-y-scheme/t-y-scheme-Z-H-15.html#%_chap_14)
That's the point at which I think continuations get insane: it's an unreasonably convoluted implementation of a straightforward (via other means) backtracking framework. In a similar vein, I've read 100 times that continuations can be used to implement a notion of (fake) threads, but haven't actually seen an implementation that wasn't depressingly subtle & long-winded despite being just a feeble "proof of concept". These have the *feeling* of e.g. implementing generators on top of real threads: ya, you can do it, but nobody in their right mind is fooled by it <wink>.
About my last problems: The hard decision is: - Either I just stop and I'm ready already, and loops are funny.
OK by me -- forgetting implementation, I still can't claim to know what's the best semantic here.
- Or I do the hidden register search, which makes things more complicated and also voidens the pushback trick partially, since then I would manage all stack stuff in one frame.
Bleech.
- Or, and that's what I will do finally: For now, I will really just correct the loops.
Well, that *is* a change to Python again, but no semantic change. The internal loop counter will no longer be an integer object, but a mutable integer box. I will just create a one-element integer array and count with its zero element. This is correct, since the stack value isn't popped off, so all alive stack copies share this one element.
Ah, very clever! Yes, that will fly -- the continuations will share a reference to the value rather than the value itself. Perfect!
As a side effect, I save the Object/Integer conversion, so I guess it will be faster. *and* this solution does not involve any other change, since the stack layout is identical to before.
Right, no downside at all. Except that Guido will hate it <wink>. there's-a-disturbance-in-the-force-ly y'rs - tim