Function Syntax

Brendan Eich brendan at
Wed May 11 09:53:23 PDT 2011

On May 11, 2011, at 9:39 AM, Douglas Crockford wrote:

> We have observed that one of the world's best capability theorists and practitioners, intending to to write solid code with capability discipline, was tripped up by completion value leakage. I think it is a real problem, and I think it requires either some sort of declaration saying that no completion value should be returned from the function, or an explicit return as we have now.

Let's quote Mark fully, ok? I am pretty sure it is ok with Mark to cite his words in full (from private correspondence):

On May 3, 2011, at 1:43 PM, Mark S. Miller wrote:

> In an earlier version of E, it was everywhere the case that returning an implicit last value was syntactically a bit more convenient than ensuring that no last value was returned. Although I took more pains to avoid accidental leakage than I think we can expect of the typical JS programmer ;), even in my own code, the desire for brevity led to several security holes which MarcS caught.
> To fix this, current E has two function definition syntaxes, stylistically used very much like Smalltalk's distinction between methods and blocks. The method-like case is used for named functions, for methods, and for anonymous functions which were really thought of as first class values, whose lifetimes might exceed that of their creating context. For these, the briefer syntax no longer returns a value. The block-like syntax is used almost exclusively for control abstractions, as in the arguments to, for example, the higher order array methods. Outside the code defining new control abstractions, these blocks were rarely passed as first class values; and the control abstractions themselves AFAIK never leak them.
> Under this discipline, the block-like syntax really feels like a generalization of conventional blocks, as they do in Smalltalk. E, being an expression language, already treated actual blocks as expressions with values, so treating these block-like functions this way seemed natural. Since switching to this discipline, I am not aware any of any further leakage bugs of that nature.

Several observations:

1. E is an expression language. JS would need opt-in syntax to make a sub-language (e.g. arrow function bodies) an expression language, and you'd still have plausible objections that with statements on the outside and expressions on the inside, programmers would not mind the gap and make both capability-leak and undefined-return bugs.

2. Based on (1), we don't know why it became conventional (but not mandatory) in E that "blocks were rarely passed as first class values; and the control abstractions themselves AFAIK never leak them." The E experience is suggestive but mainly due to (1), curse JS's Java/C patrimony, inconclusive.

3. Blocks as implicitly quoted code could be like zero-argument lambdas, with break, continue, return, |this|, and |arguments| referred to any outer function or loop/switch statement. This suggests something like the Ruby-ish syntax Isaac sketched recently, mooted by various people in the past:{|x| x * 2 }) // YAY!


3a. Basis case is {}, an object initialiser. Patchable by requiring {||}, but ugh.

3b. The objection raised repeatedly when we discussed lambdas here, that return unwinding an outer function, or throwing an error if the outer function call has already returned, is as big a hazard and source of confusion as -- or bigger than! -- any completion-return downside.

3c. The use of {| (possibly with space in between) is an unambiguous extension, but formal parameters inside |...| delimiters creates a problem for We would need the default value expression to be parenthesized if its precedence were | (bitwise-or) or looser.

Other than these, AFAICT blocks as lambdas offering shorter function-like syntax are pretty good. Should we reconsider them?


More information about the es-discuss mailing list