Generalize do-expressions to statements in general?

Mark Miller erights at
Tue Jul 14 00:48:59 UTC 2015

On Mon, Jul 13, 2015 at 6:53 PM, Isiah Meadows <impinball at> wrote:

> To be perfectly honest, though, I'm not entirely sure the specifics of the
> do-expression proposal, since Google is failing me here (can't find a thing
> giving more detail than this mailing list). And as for what my proposal
> here is, I forgot to mention that expression statements would be explicitly
> prohibited as the body of a do-expression.
> As for yours, I like it too, except if we keep adding all these extra
> parentheses, we might as well make JavaScript into a Lisp...(well, except
> LispyScript <> kinda has...) ;)
> In all seriousness, I like your idea as well, but the parsing would have
> to take into account a similar distinction between expressions and other
> statements. And that problem with objects vs blocks would result in a
> similar situation we previously ran into with the same ambiguity (in
> reverse)
> <> in
> arrow function syntax. The other issue is that your proposal, because of
> that ambiguity, would likely bring a break in backwards compatibility, one
> that is definitely not worth it:
> ```js
> // Is this a block or object literal?
> let foo = ({ bar: 1 });
> ```

It is an object literal. My proposal is not technically ambiguous, at least
for this case, since I am not proposing we change the current meaning of
"({", "(function", or "(class" at all. So, under this proposal, these three
(and the damn sloppy "let" would need to be called out as special cases.
This is necessary so that this proposal does not change the meaning of
programs that are already syntactically legal.

However, there is a human-factors ambiguity, i.e., a violation of the
principle of least surprise. For "(function" and "(class", the semantic
difference is subtle and would very rarely trip anyone up. Having reduced
the practical hazard to only one special case, we simply need to teach
that, when you wanted to say "({...})" meaning a block, just remove the
curies and say instead "(...)".

With a bit of lookahead, we can even include labeled statements, since an
expression cannot currently begin with <identifier>":". So your flip side
of your example becomes

let foo = (bar: 1);

where "bar: 1" is therefore a labeled statement. I admit this seems weird,
but perhaps that's only because we're not yet used to it.

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

More information about the es-discuss mailing list