return when desugaring to closures

Brendan Eich brendan at
Thu Oct 16 15:33:37 PDT 2008

On Oct 16, 2008, at 1:20 PM, Waldemar Horwat wrote:

> I don't think you can come up with a consistent "shift" or "greedy"  
> notion.

Funny, yacc has had one for decades, used to resolve dangling-else.

> The one you may be thinking of will happily accept code such as
> let (a = 5) x + = 2;
> yet the Firefox code gives a syntax error for it despite it being  
> parsable by your "grammar".

Cut the misattribution of your ideas to me, based on misinterpretation  
of your "experiment". Here's what's going on:

Firefox (SpiderMonkey, shown here via its REPL) throws an error:

js> y = {}
[object Object]
js> let (a = 5) x + = 2
typein:2: SyntaxError: invalid assignment left-hand side:
typein:2: let (a = 5) x + = 2
typein:2: ......................^

This is an error required by ES3, but it is not a syntax error  
according to the ES3 grammar -- it is an error due to semantic  
checking done in the spec by PutValue:

11.13.1 Simple Assignment ( = )
The production AssignmentExpression : LeftHandSideExpression =  
AssignmentExpression is evaluated as follows:
1. Evaluate LeftHandSideExpression.
2. Evaluate AssignmentExpression.
3. Call GetValue(Result(2)).
4. Call PutValue(Result(1), Result(3)).
5. Return Result(3).

8.7.2 PutValue (V, W)
1. If Type(V) is not Reference, throw a ReferenceError exception.
2. Call GetBase(V).
3. If Result(2) is null, go to step 6.
4. Call the [[Put]] method of Result(2), passing GetPropertyName(V)  
for the property name and W for the value.
5. Return.
6. Call the [[Put]] method for the global object, passing  
GetPropertyName(V) for the property name and W for the
7. Return.

SpiderMonkey historically used SyntaxError, not ReferenceError, and  
throw at compile-time. This pre-dates ES1. Another example not  
involving let expressions:

js> a + b = c
typein:1: SyntaxError: invalid assignment left-hand side:
typein:1: a + b = c
typein:1: ......^

 From ES3 chapter 16:

An implementation may treat any instance of the following kinds of  
runtime errors as a syntax error and therefore
report it early:
• Improper uses of return, break, and continue.
• Using the eval property other than via a direct call.
• Errors in regular expression literals.
• Attempts to call PutValue on a value that is not a reference (for  
example, executing the assignment statement

You may object that we should throw ReferenceError not SyntaxError --  
that is not entirely clear from the chapter 16 wording, but it is at  
most a bug unrelated to our disagreement, and it doesn't prove any  
claim that primary expressions ending in assignment expressions are  
ambiguous or unusable.

>> So what's the real problem?
> I said it already.  The problem is that you don't have a valid  
> grammar.

You have not demonstrated that claim.

>  This one is invalid, so the code of the Firefox implementation is  
> effectively the specification, and it's hard to reason about that.

It's easy, you can do it ;-).

> Other examples:  What does the following do?
> for (a = let (b = c) b in d) ...

SyntaxError because no ; after first expression in for (;;) loop head.

> vs.
> for (a = let (b = c) b in d;;) ...

Valid syntax.

> vs.
> for (a = let (b = c) b in d in d) ...

SyntaxError because no ; after first expression in for (;;) loop head.

Yes, you can chain in (relational) expressions within an  
AssignmentExpression. No, users are not flummoxed, or as far as we can  
tell in over two years even bothered, by this. Yes, it can be  
specified unambiguously.

-------------- next part --------------
An HTML attachment was scrubbed...

More information about the Es-discuss mailing list