> What happens if you don't supply a function but another type, or none?

The simplest thing is to specify it as a runtime error if the argument to shift 
is not callable. You're right that there's an overhead to constructing a new 
function. But it gives you flexibility that's otherwise a pain for the 
programmer. More below.

> Would 42 still be "returned" by shift? Or is it actually the returned value 
> in k, that gets a send method augmented to it?

I don't understand this question-- do you mean whatever value the handler 
function (in the example, function(k) { return k }) returns? Then no, there's 
no augmentation or mutation here. The continuation is represented as an object 
with three methods:

- send(v): pushes the suspended activation back onto the stack and uses v as 
the result of the shift expression

- throw(v): pushes the suspended activation and throws v from the shift 
expression

- close(): pushes the suspended activation and performs a return (running any 
relevant finally blocks first)

(This is all just what JS 1.7 generators do.)

A simpler representation for captured continuations is just a function. But as 
Kris pointed out in an earlier thread, this is inconvenient for the "throw" and 
"close" cases.

> It'd be cleaner if it was just shift()

You might think so, since the semantics seems simpler-- but it would lead to 
uglier programs. You're not affording the writer of the function doing the 
shift any ability to specify what to do after the shift, and you're not giving 
them the ability to communicate any data to the caller. This requires them to 
coordinate with clients to save any additional action in some side-channel, 
e.g.:

    // library
    function gen(thenWhat) {
        ...
        thenWhat.action = function() { ... /* do more stuff */ ... };
        let received = shift();
        ...
    }

    // client
    var k = gen({ action: function() { } });

> But maybe I'm knifing an entire API here I don't know about :) Otherwise the 
> send method seems redundant.

I'm not sure what the send method has to do with it-- it sounds like I may not 
have explained clearly enough. The semantics of shift is to capture and pop the 
current activation, reify it as an object with the three methods I describe 
above (send, throw, close) and call the handler function with this reified 
activation object as its argument. It's then up to the program to decide 
when/whether to continue the captured function by calling its methods.

Note that this means that when you use the shift operator, the handler function 
is executed immediately, whereas the rest of the captured function is suspended 
and not continued until some later time. This is the opposite of patterns like 
event callbacks and CPS, where the code in the callback is called at some later 
time, but the rest of the current function is continued immediately.

Dave

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to