block lambda revival, now with semantics

Brendan Eich brendan at
Sun May 22 21:17:32 PDT 2011

Only a couple of TODOs: [[Call]]

When the [[Call]] internal method for a block-lambda object B is called with a list of arguments, the following steps are taken:

Let funcCtx be the result of establishing a new execution context for function code using the value of B‘s [[FormalParameters]] internal property, the passed arguments List args, and the this value given by the ThisBinding component of the execution context in B‘s [[Context]] internal property.
Let result be the result of evaluating the StatementList or EmptyStatement that is the value of B‘s [[Code]] internal property.
Exit the execution context funcCtx, restoring the previous execution context.
If result.type is normal and result.value is empty then return (normal, undefined, empty).
Else if result.type is break, continue, or return and B‘s [[Context]] internal property has already exited, throw a TypeError exception.
Else if result.type is break or continue and has already exited, throw a TypeError exception.
Else return the Completion value result.
TODO: forbid var in block-lambdas (yeah!)

11.2.3 Function Calls


TODO: Process Completion return type

The production CallExpression : CallExpression [no LineTerminator here] BlockArguments is evaluated evaluated in exactly the same manner, except that BlockArguments is evaluated instead of Arguments in step 3. 

In other words, a block-lambda's [[Call]] internal method must return a Completion in order to attempt to break, continue, or return in the enclosing switch/loop/function. One way to do this: uncatchable internal Completion exceptions for (break, empty, target), (continue, empty, target), and (return, value, empty) thrown by the relevant statements. The uncatchable part is ugly and this looks like an unnecessary change at the statement-grammar level, since Completion type works there already to solve the same problem.

The issue is that within an expression, results are values, not Compietions. There's a bit of magic in the spec by which an exception thrown from sub-expression evaluation is caught by the statement level and packaged up into a (throw, value, empty) completion. Block-lambdas are the first way by which an expression can complete with break, continue, or return.

We could make all expression evaluation in the spec return a union of Reference and Completion types. Explicitness seems best. I'll let this one marinate.

The first TODO proposes to ban var from occurring within block-lambdas. This seems better than contorting the spec to hoist var bindings across block-lambda boundaries. Who is with me? ;-)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list