From: Garrett Smith on
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
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
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
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
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.
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9 10
Prev: IE problem with iframe reload
Next: IE's vertical scroll bar