Why isn't FunctionExpression a PrimaryExpression?
ES3 (and ES5) defines these grammar productions:
MemberExpression :
PrimaryExpression FunctionExpression MemberExpression [ Expression ] MemberExpression . IdentifierName new MemberExpression Arguments
PrimaryExpression :
this Identifier Literal ArrayLiteral ObjectLiteral ( Expression )
FunctionExpression :
function
Identifieropt ( FormalParameterList ) { FunctionBody } Does anybody know or see a good reason why FunctionExpression shouldn't be move as a RHS of PrimaryExpression? MemberExpression is the only occurrence of either PrimaryExpression or FunctionExpression on the RHS of a grammar rule.
Function expressions were added in ES3. Were they just added at the wrong place in the grammar?
(sorry about any duplicates like this that show up. I seem to have had posting delays yesterday that resulted in duplicate postings)
On Oct 19, 2011, at 8:16 AM, Allen Wirfs-Brock wrote:
ES3 (and ES5) defines these grammar productions:
MemberExpression :
PrimaryExpression FunctionExpression MemberExpression [ Expression ] MemberExpression . IdentifierName new MemberExpression Arguments
PrimaryExpression :
this Identifier Literal ArrayLiteral ObjectLiteral ( Expression )
FunctionExpression :
function
Identifieropt ( FormalParameterList ) { FunctionBody }
Does anybody know or see a good reason why FunctionExpression shouldn't be move as a RHS of PrimaryExpression? MemberExpression is the only occurrence of either PrimaryExpression or FunctionExpression on the RHS of a grammar rule.
Function expressions were added in ES3. Were they just added at the wrong place in the grammar?
Thanks for raising this, I keep forgetting to.
Oddly enough, SpiderMonkey always had them (prior to ES3 even being drafted) as PrimaryExpressions. No one can observe the difference, as you note. Either way, one can write
var fun_member = function () {}.member;
On aesthetic grounds, I would prefer the grammar to make function expressions primary.
On Oct 19, 2011, at 2:53 PM, Brendan Eich wrote:
On Oct 19, 2011, at 8:16 AM, Allen Wirfs-Brock wrote:
Function expressions were added in ES3. Were they just added at the wrong place in the grammar?
Thanks for raising this, I keep forgetting to.
Oddly enough, SpiderMonkey always had them (prior to ES3 even being drafted) as PrimaryExpressions. No one can observe the difference, as you note. Either way, one can write
var fun_member = function () {}.member;
On aesthetic grounds, I would prefer the grammar to make function expressions primary.
Good, I want to make that change because for semantic specification purposes FunctionExpression works better as PrimaryExpression.
I just wanted to make sure, before I make the change, that there wasn't some grammatical subtlety I was overlooking
On Oct 19, 2011, at 3:29 PM, Allen Wirfs-Brock wrote:
On Oct 19, 2011, at 2:53 PM, Brendan Eich wrote:
On Oct 19, 2011, at 8:16 AM, Allen Wirfs-Brock wrote:
Function expressions were added in ES3. Were they just added at the wrong place in the grammar?
Thanks for raising this, I keep forgetting to.
Oddly enough, SpiderMonkey always had them (prior to ES3 even being drafted) as PrimaryExpressions. No one can observe the difference, as you note. Either way, one can write
var fun_member = function () {}.member;
On aesthetic grounds, I would prefer the grammar to make function expressions primary.
Good, I want to make that change because for semantic specification purposes FunctionExpression works better as PrimaryExpression.
I just wanted to make sure, before I make the change, that there wasn't some grammatical subtlety I was overlooking
Toy grammar (| is meta, other punctuators after the : are concrete):
E: ME ME: PE | FE | ME [ E ] | ME . ID | ... PE: ( E ) | ...
and there's no way that ME -> FE would be reduced where ME -> PE -> FE was not possible, and there are no PE occurrences on the RHS of a production whose LHS is not ME, then FE can move "down" one precedence level from being the sole RHS part of ME, to being the sole RHS of PE.
(Lotta abbreviation there, sorry.)
Trivial search shows PrimaryExpression occurs in only one RHS, as the sole RHS part produced from MemberExpression.
One concern might be that we probably cannot make arrow notation (if we introduce it) a primary expression, and it might be confusing if they have different precedence.
I also think it is easier to parse for the human reader when he sees
(function f() { ... })()
instead of
function f() { ... }()
especially when this occurs as a statement. (Mh, actually, could we even distinguish between function declerations and expression statements starting with a function expr in LALR(1), without heavy grammar transformation?)
On Oct 20, 2011, at 12:31 AM, Andreas Rossberg wrote:
One concern might be that we probably cannot make arrow notation (if we introduce it) a primary expression, and it might be confusing if they have different precedence.
We absolutely cannot and the strawman specifies the grammar fully:
strawman:arrow_function_syntax
AssignmentExpression : ArrowFunctionExpression ...
ArrowFunctionExpression : ArrowFormalParameters_opt Arrow AssignmentExpression ArrowFormalParameters_opt Arrow ArrowBodyBlock_opt
ArrowFormalParameters : ( FormalParameterList_opt ) ( this Initialiser_opt ) ( this Initialiser_opt , FormalParameterList )
Arrow : one of -> or =>
Arrow function expressions must be low precedence, unparenthesized on the right of assignment operators.
I also think it is easier to parse for the human reader when he sees
(function f() { ... })()
instead of
function f() { ... }()
especially when this occurs as a statement. (Mh, actually, could we even distinguish between function declerations and expression statements starting with a function expr in LALR(1), without heavy grammar transformation?)
The grammar currently uses a lookahead restriction to disambiguate in favor of function declaration:
12.4 Expression Statement
Syntax
ExpressionStatement : [lookahead ∉ {{, function}] Expression ;
NOTE An ExpressionStatement cannot start with an opening curly brace because that might make it ambiguous with a Block. Also, an ExpressionStatement cannot start with the function keyword because that might make it ambiguous with a FunctionDeclaration.
On Oct 20, 2011, at 12:31 AM, Andreas Rossberg wrote:
(Mh, actually, could we even distinguish between function declerations and expression statements starting with a function expr in LALR(1), without heavy grammar transformation?)
To answer this question, there's no way to disambiguate without a lookahead restriction or massive duplication of the expression sub-grammar. You'd need
ExpressionStatement: ExpressionNoFunctionNoLeftCurlyAtFront
and ExpressionNoFunctionNoLeftCurlyAtFront would produce any expression except those starting with 'function' or '{'. No win in duplicating so much grammar. We'd rather use lookahead restrictions as the spec does currently, or parametric productions as an alternative (would be nice to unduplicate the -NoIn productions).
BTW there's still a de-facto standard lurking about on the web that expects eval("function(){...}") to parse. I'm not sure where different engines stand on this.
On 10/20/2011 09:44 AM, Brendan Eich wrote:
BTW there's still a de-facto standard lurking about on the web that expects eval("function(){...}") to parse. I'm not sure where different engines stand on this.
No engine supports. Gecko temporarily regressed to support it again at one point (after having deliberately disabled it), but that bug's been fixed. I haven't heard any complaints about sites breaking (not surprising if everyone but us, and only for some releases, had correct behavior).
On Nov 1, 2011, at 11:37 AM, Jeff Walden wrote:
On 10/20/2011 09:44 AM, Brendan Eich wrote:
BTW there's still a de-facto standard lurking about on the web that expects eval("function(){...}") to parse. I'm not sure where different engines stand on this.
No engine supports. Gecko temporarily regressed to support it again at one point (after having deliberately disabled it), but that bug's been fixed. I haven't heard any complaints about sites breaking (not surprising if everyone but us, and only for some releases, had correct behavior).
Ok, great news. Thanks,
On 10/19/2011 08:16 AM, Allen Wirfs-Brock wrote:
Does anybody know or see a good reason why FunctionExpressionshouldn't be move as a RHS of PrimaryExpression? MemberExpressionis the only occurrence of either PrimaryExpressionor FunctionExpressionon the RHS of a grammar rule.
As you note, the two grammars are equivalent, so this is a purely aesthetic choice. I agree that putting FunctionExpression inside PrimaryExpression is more pleasing.
Waldemar
ES3 (and ES5) defines these grammar productions:
MemberExpression :
PrimaryExpression FunctionExpression MemberExpression [ Expression ] MemberExpression . IdentifierName new MemberExpression Arguments
PrimaryExpression :
this Identifier Literal ArrayLiteral ObjectLiteral ( Expression )
FunctionExpression :
function Identifieropt ( FormalParameterList ) { FunctionBody }
Does anybody know or see a good reason why FunctionExpression shouldn't be move as a RHS of PrimaryExpression? MemberExpression is the only occurrence of either PrimaryExpression or FunctionExpression on the RHS of a grammar rule.
Function expressions were added in ES3. Were they just added at the wrong place in the grammar?