From: Garrett Smith on 24 May 2010 14:29 On 5/24/2010 7:30 AM, Ry Nohryb wrote: > On May 24, 3:35 pm, "Dmitry A. Soshnikov"<dmitry.soshni...(a)gmail.com> > wrote: >> On 24.05.2010 16:44, Ry Nohryb wrote: >>> On May 24, 1:00 am, "FAQ server"<javascr...(a)dotinternet.be> wrote: >> >>>> The term function statement has been widely and wrongly used to >>>> describe a ` FunctionDeclaration `. This is misleading because in >>>> ECMAScript, a ` FunctionDeclaration ` cannot appear as a Statement. >> >>> You're misleading, and your screwed-up FAQ too: >> >>> 12.5: The if Statement: Syntax: if ( Expression ) Statement >> >>> javascript: f(); if (0) function f () { alert("Declaration, Smith, DE- >>> CLA-RA-TION") }; >> >>> Safari, Chrome, Opera, IE: "Declaration, Smith, DE-CLA-RA-TION" >>> Mozillas: TypeError: f is not a function. >> >>> (...) >> >>> etc, etc. >> >> Well, all excluding Mozilla are wrong. > > No, no one but Smith is wrong : his statement is obviously false: "in > ECMAScript, a ` FunctionDeclaration ` cannot appear as a Statement" is > FALSE. > No, no one but Jorge Chamorro is wrong (and only apparently now that an actual claim was made). A Statement cannot begin with "function". Any implementation that allows for such production is providing a syntax extension. >> Mozilla is right only because of section 16 of the ECMA-262-3. > > All of them are fully compliant. Providing a syntax extension is not a conformance violation.
From: John G Harris on 24 May 2010 15:04 On Mon, 24 May 2010 at 07:30:46, in comp.lang.javascript, Ry Nohryb wrote: <snip> >No, no one but Smith is wrong : his statement is obviously false: "in >ECMAScript, a ` FunctionDeclaration ` cannot appear as a Statement" is >FALSE. <snip> If he changed it slightly to "in ECMAScript a FunctionDeclaration cannot appear everywhere that a Statement can appear." then it would be completely accurate and true. John -- John Harris
From: kangax on 24 May 2010 15:35 On 5/24/10 10:07 AM, Richard Cornford wrote: > On May 24, 2:35 pm, Dmitry A. Soshnikov wrote: [...] >> And I think for some it would be convenient to >> define functions in the declaration view. > <snip> > > How much difference in 'convenience' would there be? You can evaluate > a function expression conditionally and assign the result to a > variable, so whatever the job is it can be done with existing syntax. > So the difference in convenience is that between writing - x = > function(n){ ... }; - and - function x(n){ ... } -, which doesn't seem > that much. The difference in convenience becomes more apparent once we "zoom out" from `x = function(){}` vs `function x(){}` comparison. Take a look at something like `addListener` abstraction, and one of the possible ways to implement it. As you're well aware of, forking function definition based on certain condition is an extremely common scenario when it comes to cross-browser scripting: var addListener, docEl = document.documentElement; if (isHostMethod(docEl, 'addEvenListener')) { addListener = function () { /* ... */ }; } else if (isHostMethod(docEl, 'attachEvent')) { addListener = function (){ /* ... */ }; } Specifics aside, what we're dealing with here is this: var addListener; if (/* ... */) { addListener = function () { }; } else if (/* ... */) { addListener = function () { }; } The inconvenience in this case is that we need to first define `addListener` variable before assigning function object to it. Knowing how variable declaration works in ECMAScript (i.e. that `addListener` is "hoisted"), we could shorten this version like this: if (/* ... */) { var addListener = function () { }; } else if (/* ... */) { addListener = function () { }; } - but this just has too much chance of looking like a mistake (or confuse reader of the code), and is a pattern I would rather stay away from. The benefit of function statements becomes even more apparent once we bring the subject of function identifiers into a picture. To aid in debugging/profiling (IIRC, you found this argument bogus last time I've heard :)), `addListener` could be given an identifier like so: var addListener; if (/* ... */) { addListener = function addListener() { }; } else if (/* ... */) { addListener = function addListener() { }; } I personally know libraries that follow such pattern (their authors are also well aware of NFE bugs in IE). Note that some of the NFE issues are "worked around" here by using same identifiers for variable (to assign function to) and actual function. Now, if we were to utilize function statements in a previous example, the snippet becomes rather elegant: if (/* ... */) { function addListener() { } } else if (/* ... */) { function addListener() { } } I've seen another pattern, like this: function addListener() { /* ... */} if (/* ... */) { addListener = function () { /* ... */ } } - but it only solves the identifiers problem partially. And on a related note, implementations that extend function objects with "name" property (such as Mozilla) usually populate that property with identifier of a function during its declaration. var f = function g(){}; f.name; // "g" function h(){} h.name; // "h" In those implementations there's an added cost of not having "proper" `name` value (if that matters, for whatever reason) when using expressions instead of declarations. All in all, I don't particularly find function statements to be an amazing boon, but I can see how they are useful; I would take them any day if not for complete uselessness in context of general web, where backwards compatibility issues would probably render them to be more of a danger than a convenience. I'm curious how committee is going to handle these issues, as "block functions" appear to be scheduled for ES harmony, and are already on the list of proposals (not just in strawman section) :) � <http://wiki.ecmascript.org/doku.php?id=harmony:proposals> -- kangax
From: Garrett Smith on 24 May 2010 16:33 On 5/24/2010 12:04 PM, John G Harris wrote: > On Mon, 24 May 2010 at 07:30:46, in comp.lang.javascript, Ry Nohryb > wrote: > > <snip> >> No, no one but Smith is wrong : his statement is obviously false: "in >> ECMAScript, a ` FunctionDeclaration ` cannot appear as a Statement" is >> FALSE. > <snip> > > If he changed it slightly to > > "in ECMAScript a FunctionDeclaration cannot appear everywhere that a > Statement can appear." > > then it would be completely accurate and true. > How about: | in ECMAScript a FunctionDeclaration is not a Statement; it cannot | appear everywhere that a Statement can.
From: Asen Bozhilov on 24 May 2010 17:14
Dmitry A. Soshnikov wrote: > By the way, I have any idea why they didn't standardized Function > Statements in the 5th edition? > > That strange phrase from the spec /"ExpressionStatement cannot start > with the *function* keyword because that might make it ambiguous with a > FunctionDeclaration"/ is really strange -- because how then Mozilla > distinguishes FD from FS? Easy I guess, by the context of the source > code position. For what to write it in the spec (including 5th edition), > if it is easy to distinguish? And I think for some it would be > convenient to define functions in the declaration view. FunctionStatement does not provide any syntactical differences with FD. But provides differences during instantiation stage. Function Declarations are instated on entering on execution context, but Function Statements during evaluation of the statement in which they are defined. That provides a confusion in the readers of the code. For example: if (true) { function F(){ //... } } else { function F(){ //... } } F(); Which function will be invoked? Yes, you know the answer, but that example can be extended and code in these statement can be increased. When you read the code you will be need to see parent statement to catch that function is actually FS. That break readability of the code and does not provide any benefits comparing with FunctionExpression there can be assigned reference on variable. Actually if I modify that example to use FunctionExpression the readability problem is gone away and I think maintaining is better. var F; if (true) { F = function () { //... } } else { F = function () { //... } } When I need FunctionStatement behavior I always use FunctionExpression. That I do for readability and for unexpected behavior which can be provided by extension on the language. These extensions can be treat in different way in different implementations. |