Google Groups

Re: Closing parenthesis in function's definition followed by its call

dhtml Apr 20, 2010 5:18 PM
Posted in group: comp.lang.javascript
Johannes Baagoe wrote:
> Garrett Smith :
>> Then what is wrong with an implementation treating a FunctionExpression
>> as a Function Definition?
> Nothing at all, a FunctionExpression *is* a Function Definition.
>> And if the answer is nothing (which is the correct answer) then why
>> insist Microsoft got that wrong?
> Apparently, MDC got at least *its* wording wrong : what "Some
> JavaScript engines, not including SpiderMonkey" *may* do wrong (I
> can't figure out whether it is true) is not to "incorrectly treat
> any function expression with a name as a function definition",
> but to incorrectly treat any function expression with a name as a
> function *declaration*.
> MDC's bone of contention is this:
>   if (0) {
>      function zero() {
>         document.writeln("This is zero.");
>      }
>   }
> According to MDC, we have a function *expression*, which means that
> zero is undefined unless defined elsewhere. js bears that out.

Actually that is a FunctionStatement, an allowed syntax extension.

The documentation there uses "function statement" in two ways:
1) Parenthetically, as an alternative for FunctionDeclaration (wrong)
2) To mean the syntax extension "FunctionDeclaration" (right)


> At least V8 (Chrome) considers it a function *declaration*, i.e.,
> zero is a function.

The function declaration (function  statement)
Edit section

> I am not sure myself - understanding the specs requires more than
> I am willing to spend on the problem, after having given it a try
> both in 3rd and 5th ed. If someone can explain it in plain words to
> an ordinarily stupid programmer like me, I shall be very grateful.
> In any case, someone is wrong. It may be Microsoft (that was Jorge's
> assumption, I have no personal opinion on the subject, not being
> a Microsoft costumer), in which case Chrome is just as wrong. It
> may be Mozilla. If I understood the specs, I would know, but I don't.

Microsoft has a well known bug with named function expressions. There
are many posts in the archives, but Juriy's article explains it in one
place (that is also linked from the FAQ).

> But for exactly that reason, I think whoever is wrong has at least a
> "lame excuse", lamer, to be sure, in the case of people who get paid
> to get it right than in mine. Namely that the specs are horrible:
>   FunctionDeclaration :
>     function Identifier ( FormalParameterList opt ) { FunctionBody }
>   FunctionExpression :
>     function Identifier opt ( FormalParameterList opt ) { FunctionBody }
> mean that when the FunctionExpression has its optionalIdentifier, there
> is nothing in its syntax to differentiate it from a FunctionDeclaration.
> That is a syntactic ambiguity of about the worst sort imaginable.

Not at all. The ECMAScript specification has no provision for
FunctionDeclaration to appear where a Statement may appear.

However, an ExpressionStatement may appear where a Statement is allowed.
A FunctionExpression is an ExpressionStatement. Therefore, a
FunctionExpression may appear where a Statement is allowed.

> How is it resolved? Well... happy reading of the specs :)

| Statement
|     Block
|     VariableStatement
|     EmptyStatement
|     ExpressionStatement
|     IfStatement
|     IterationStatement
|     ContinueStatement
|     BreakStatement
|     ReturnStatement
|     WithStatement
|     LabelledStatement
|     SwitchStatement
|     ThrowStatement
|     TryStatement

FunctionDeclaration is not on that list.

ExpressionStatement is.

     [lookahead {{, function}] Expression

An ExpressionStatement can't start with "{" because that would create
ambiguity to determine if it is a block or an object literal and it
can't start with "function" because that could it ambiguous with a
FunctionDeclaration (s 12.4).

A MemberExpression is a Left-Hand-Side Expression.

MemberExpression :
     MemberExpression [ Expression ]
     MemberExpression . Identifier
     new MemberExpression Arguments

A FunctionExpression is an MemberExpression.

A FunctionDeclaration is not an Expression; it is a SourceElement.

Spidermonkey adds FunctionStatement. JScript adds FunctionDeclaration,
however, JScript also has JScriptFunction.

In JScript, upon entering an execution context, each
FunctionExpression's identifier and each FunctionDeclaration's
identifier, and all identifiers in a JScript FunctionBindingList of a
JScriptFunction are added as properties of the containing Variable object.

| For each FunctionDeclaration or FunctionExpression in the code, in
| source text order, do one of the following depending upon the form of
| the FunctionDeclaration or FunctionExpression:
|  * If the production is of the form
|   FunctionDeclaration : function ( FormalParameterListopt )
|      { FunctionBody }
| or
|   FunctionExpression : function ( FormalParameterListopt )
|      { FunctionBody }
| do nothing.
| * If the production is of the form
|  FunctionDeclaration : function Identifier ( FormalParameterListopt )
|    { FunctionBody }
|  or FunctionExpression : function Identifier (
FormalParameterListopt ) { FunctionBody } create a property of the
variable object whose name
is the Identifier in the FunctionDeclaration or FunctionExpression,
whose value is the result
returned by creating a Function object as described in 13, and whose
attributes are determined
by the type of code. If the variable object already has a property with
this name, replace its value
and attributes. Semantically, this step must follow the creation of
 If the production is of the form FunctionDeclaration : JScriptFunction
or FunctionExpression :
JScriptFunction perform the following steps:
1. Let func be the result returned by creating a Function object as
described in 13.
2. Process the FunctionBindingList element of the JScriptFunction as
described in 13 and using func
and the attributes for the current type of code as processing arguments.
comp.lang.javascript FAQ: