Closing parenthesis in function's definition followed by its call

186 views
Skip to first unread message

Johannes Baagoe

unread,
Apr 19, 2010, 9:55:31 PM4/19/10
to
Should it be

(function foo() { /*...*/ })();

or

(function foo() { /*...*/ }());

(note the place of the closing parenthesis) ?

Both are AFAICT syntactically correct and indeed equivalent, but
I would tend to prefer the latter: since we are warning the future
reader "Beware! This function is not only defined / declared but also
called right away!", why not make it quite clear where the scope of
that warning ends?

Same question for

var foo = (function() { /*...*/ })();

vs.

var foo = (function() { /*...*/ }());

etc.

It doesn't matter much when `foo` is called with an empty list
of arguments, but I believe it would make cases where its arguments
are complex much clearer - any editor that matches opening and closing
parentheses would immediately show the various parts of the construct.

Are there better arguments in favour of the former ?

--
Johannes

nick

unread,
Apr 20, 2010, 1:05:47 AM4/20/10
to
On Apr 19, 9:55 pm, Johannes Baagoe <baa...@baagoe.com> wrote:

> Same question for
>
>   var foo = (function() { /*...*/ })();
>
> vs.
>
>   var foo = (function() { /*...*/ }());

Those shouldn't need the extra parentheses...

var foo = function() { /*...*/ }();

...should be valid.

But nobody ever does that, which makes me think some old(ish) browsers
might be more picky, especially after reading this:

https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Functions
#Function_constructor_vs._function_declaration_vs._function_expression

"Some JavaScript engines, not including SpiderMonkey, incorrectly
treat any function expression with a name as a function definition"

-- Nick

Garrett Smith

unread,
Apr 20, 2010, 2:20:09 AM4/20/10
to
nick wrote:
> On Apr 19, 9:55 pm, Johannes Baagoe <baa...@baagoe.com> wrote:
>
>> Same question for
>>
>> var foo = (function() { /*...*/ })();
>>
>> vs.
>>
>> var foo = (function() { /*...*/ }());
>
> Those shouldn't need the extra parentheses...
>
> var foo = function() { /*...*/ }();
>
> ...should be valid.
>
> But nobody ever does that, which makes me think some old(ish) browsers
> might be more picky, especially after reading this:
>

The Grouping operator merely provides is a hint at an idiom. Some omit it.

> https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Functions
> #Function_constructor_vs._function_declaration_vs._function_expression
>
> "Some JavaScript engines, not including SpiderMonkey, incorrectly
> treat any function expression with a name as a function definition"
>

That in and of itself is not a true statement. Moreover, it is
unsupported by the example that follows.

| Note: Some JavaScript engines, not including SpiderMonkey, incorrectly
| treat any function expression with a name as a function definition.
| This would lead to zero being defined, even with the always-false if
| condition. A safer way to define functions conditionally is to define
| the function anonymously and assign it to a variable:
|
| if (0) {
| var zero = function() {
| document.writeln("This is zero.");
| }
| }

The paragraph makes a statement about a function expression with a name
being treated as a function definition. That would be a true statement
if it had been rewritten as:

| Some JavaScript engines, not including SpiderMonkey, incorrectly

| parse any function expression with an identifier as a function
| declaration.

However, even at that, it is still unsupported by the example.

The FunctionExpression in the example does not have an identifier. It is
an anonymous function expression.

The value of `zero` can be expected to be undefined following the block
after the `if` statement. For example:

if (0) {
var zero = function() {
document.writeln("This is zero.");
}
}
alert(typeof zero);

- can be expected to elert "undefined".

So I'm afraid MDC is a bad source of information here. Unfortunately,
the Edit feature is non-functional in Firefox with or without javascript
enabled.

I am now getting:

| Service Unavailable
|
| The service is temporarily unavailable. Please try again later.

Hopefully they can fix the errors on MDC. That is pitiful.
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/

Thomas 'PointedEars' Lahn

unread,
Apr 20, 2010, 8:53:04 AM4/20/10
to
Johannes Baagoe wrote:

> Should it be
>
> (function foo() { /*...*/ })();
>
> or
>
> (function foo() { /*...*/ }());
>
> (note the place of the closing parenthesis) ?
>
> Both are AFAICT syntactically correct and indeed equivalent, but
> I would tend to prefer the latter: since we are warning the future
> reader "Beware! This function is not only defined / declared but also
> called right away!", why not make it quite clear where the scope of
> that warning ends?

Incidentally, that is what Douglas Crockford recommends and the way his
argument goes, too, as you can see starting at about 00:29:27 h of "Act III:
Function the Ultimate" (when he starts talking about closures).¹ Contrary
to other of his opinions, I find the reasoning sound in this case, and have
rewritten function expression calls on occasion. I have tested the result
with various browsers and have observed no negative effects so far.

¹ <http://developer.yahoo.com/yui/theater/video.php?v=crockonjs-3>

> Same question for
>
> var foo = (function() { /*...*/ })();
>
> vs.
>
> var foo = (function() { /*...*/ }());

Currently I am using such assignments more often than one of the statements
above, although to real properties (which become methods), seldom to
variables.



> etc.
>
> It doesn't matter much when `foo` is called with an empty list
> of arguments, but I believe it would make cases where its arguments
> are complex much clearer - any editor that matches opening and closing
> parentheses would immediately show the various parts of the construct.

Full ACK.

> Are there better arguments in favour of the former ?

I don't think so.


PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee

Jorge

unread,
Apr 20, 2010, 9:11:39 AM4/20/10
to

I prefer the former, for as soon as I see a () my "attention: function
call" flag gets set, and I expect the function itself to stand by the
left hand side of the (), often neatly enclosed in its own parens. A
trailing ()) is not so neat and tidy. It's asymmetric and awful. This
is one of the rare cases in which Crockford's arguments have not
convinced me.
--
Jorge.

Johannes Baagoe

unread,
Apr 20, 2010, 10:59:00 AM4/20/10
to
Thomas 'PointedEars' Lahn :
> Johannes Baagoe :

>> var foo = (function() { /*...*/ })();
>>
>> vs.
>>
>> var foo = (function() { /*...*/ }());

> Currently I am using such assignments more often than one of the
> statements above, although to real properties (which become methods),
> seldom to variables.

<rant>

If I were to teach elementary programming these days (perhaps
fortunately for the students, I don't any longer), I would 1. use
javascript - or rather, ECMASCript in whatever version seems the most
reasonable, probably still 3rd - as "first" language, and 2. only
introduce function *declarations* at the very end of the course, as a
kind of afterthought - "You can also do it that way, and it may even
help older programmers who don't know better", or something like that.

This exposes the student from the very start to the idea that functions
are very, very important animals, quite as important as numbers and
strings, and that they can be assigned, stored in objets (in which
case we call them "methods" rather than "properties", but that hasn't
necessarily to be a big deal), passed as arguments to other functions
or even to themselves, etc.

Which is a most important notion if the student is ever to do
functional programming, lambda calculus, about any kind of maths, and
even philosophy or linguistics, where a functional view of language -
words and sentences as procedures, that is, parametrised behaviour
triggered by events - is a useful contrast to the more traditional
view of language as a representation of the world.

</rant>

--
Johannes

Johannes Baagoe

unread,
Apr 20, 2010, 1:04:51 PM4/20/10
to
nick :
> Johannes Baagoe :

>>   var foo = (function() { /*...*/ })();
>>
>> vs.
>>
>>   var foo = (function() { /*...*/ }());

> Those shouldn't need the extra parentheses...
>
> var foo = function() { /*...*/ }();
>
> ...should be valid.
>
> But nobody ever does that, which makes me think some old(ish) browsers
> might be more picky, especially after reading this:
>
> https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Functions
> #Function_constructor_vs._function_declaration_vs._function_expression
>
> "Some JavaScript engines, not including SpiderMonkey, incorrectly treat
> any function expression with a name as a function definition"

Quite, but even assuming correct implementations, I would still add the
parentheses (second version), as a help to myself, to programmers who
are new to javascript, and even to old javascript hands who recognise
the idiom. When one sees "(function", it means "this function is
going to be called right away - its body ends at the closing brace
that matches the first opening brace, and the entire construct ends
at the closing parenthesis that matches this one".

It is especially important if the result is not a Function, like

var two = (function() {return 2;}());

Taking all that trouble be pointless in this case, but since
javascript's scope of variables are functions, not blocks, and since
the usual way to provide other languages' notion of static variables
is closures, it is very often a useful idiom - one that must be
taught to anybody who starts on javascript, especially when coming
from other languages with a C-style syntax.

--
Johannes

Jorge

unread,
Apr 20, 2010, 1:21:03 PM4/20/10
to
On Apr 20, 7:05 am, nick <nick...@fastmail.fm> wrote:
>
> "Some JavaScript engines, not including SpiderMonkey, incorrectly
> treat any function expression with a name as a function definition"

LOL. And these engines are made by Microsoft and are called JScript
and are the ones used in each and every Internet Explorer, up to and
including the current, latest one.

And they manage miraculously to not only screw up the function
expression, but the function declaration too. Wonders of software
engineering.
--
Jorge.

Johannes Baagoe

unread,
Apr 20, 2010, 1:31:10 PM4/20/10
to
Jorge :
> nick :

>> "Some JavaScript engines, not including SpiderMonkey, incorrectly treat
>> any function expression with a name as a function definition"

> LOL. And these engines are made by Microsoft and are called JScript and
> are the ones used in each and every Internet Explorer, up to and
> including the current, latest one.
>
> And they manage miraculously to not only screw up the function
> expression, but the function declaration too. Wonders of software
> engineering.

In a sort of lame defence (why on earth am I trying to excuse Microsoft?),
it may be argued that function expressions with a name are a Really Bad
Idea from the beginning, and that anyone who uses them deserves... well,
some terrible fate.

--
Johannes

Jorge

unread,
Apr 20, 2010, 1:37:42 PM4/20/10
to
On Apr 20, 7:31 pm, Johannes Baagoe <baa...@baagoe.com> wrote:
>
> In a sort of lame defence (why on earth am I trying to excuse Microsoft?),
> it may be argued that function expressions with a name are a Really Bad
> Idea from the beginning, and that anyone who uses them deserves... well,
> some terrible fate.

Huh ?
How so ?
--
Jorge.

Garrett Smith

unread,
Apr 20, 2010, 4:05:31 PM4/20/10
to
Johannes Baagoe wrote:
> Garrett Smith :
>> Johannes Baagoe :

>>>> nick :
>
>>>>> "Some JavaScript engines, not including SpiderMonkey, incorrectly
>>>>> treat any function expression with a name as a function definition"
>
>>> In a sort of lame defence (why on earth am I trying to excuse
>>> Microsoft?),
>
>> If you're asking me to guess, I would say that you have probably
>> mistaken "function definition" with "function declaration".
>
> I hope not. I talk about a function expression with a name. As I
> understand it, that is a realisation of
>
> FunctionExpression :
> function Identifier opt ( FormalParameterList opt ) { FunctionBody }
>
> in which the optional Identifier (the "name") exists.
>
>> I suggest you to and read the ECMA-262 specification for "Function
>> Definition".
>
> I have, just in case, but I didn't need to: my memory was quite accurate.
>

Then what is wrong with an implementation treating a FunctionExpression
as a Function Definition? And if the answer is nothing (which is the
correct answer) then why insist Microsoft got that wrong?

Johannes Baagoe

unread,
Apr 20, 2010, 3:38:41 PM4/20/10
to
Stefan Weiss :

> Didn't you say (in a different thread) that you "quite liked" Jorge's
> loop() function? That's a named function expression, too. It doesn't
> have to be - you could just call loop() separately from its definition -
> but the way you're using it on
>
> http://baagoe.com/en/RandomMusings/javascript/time.js
>
> it's still a named function expression.

Touché. You are right about that one. I shall correct the matter forthwith.

> Do you deserve a terrible fate now? ;-)

Well, yes: having to confess that my behaviour does not always match my
words :) And publicly, too.

--
Johannes

Stefan Weiss

unread,
Apr 20, 2010, 4:14:11 PM4/20/10
to
On 20/04/10 21:12, Johannes Baagoe wrote:
> Stefan Weiss :
>> and when you want to recurse from inside a function expression.
>
> What is wrong with
>
> var fact = function(n) {
> if (n > 0) {
> return n * fact(n - 1);
> } else {
> return 1;
> }
> };
>
> ?

It works, of course, but it makes the recursion dependent on a
(potentially unrelated) variable from an outer scope. I don't think the
implementation of a function should need to care about which variable it
will be assigned to. And then there are the "self-executing" functions
from your original examples, which run before their result is assigned
to a variable:

var foo = (function () {
// what if I want to recurse here?
})();

BTW, I prefer this style of parenthesis placement, but I think both are
fine as long as the intention is clear.


--
stefan

Johannes Baagoe

unread,
Apr 20, 2010, 3:12:31 PM4/20/10
to
Stefan Weiss :

> Names for function expressions are useful in at least
> two cases: for debugging/profiling,

That could indeed be the case with some debuggers/profilers, I would
consider them less than satisfactory. But see below.

> and when you want to recurse from inside a function expression.

What is wrong with

var fact = function(n) {
if (n > 0) {
return n * fact(n - 1);
} else {
return 1;
}
};

?

> The only alternative for the second case would be arguments.callee,
> which (I think) has recently been deprecated.

I think I just provided another and possibly better alternative.

--
Johannes

Johannes Baagoe

unread,
Apr 20, 2010, 3:28:58 PM4/20/10
to
Garrett Smith :
> Johannes Baagoe :
>>> nick :

>>>> "Some JavaScript engines, not including SpiderMonkey, incorrectly
>>>> treat any function expression with a name as a function definition"

>> In a sort of lame defence (why on earth am I trying to excuse
>> Microsoft?),

> If you're asking me to guess, I would say that you have probably


> mistaken "function definition" with "function declaration".

I hope not. I talk about a function expression with a name. As I
understand it, that is a realisation of

FunctionExpression :
function Identifier opt ( FormalParameterList opt ) { FunctionBody }

in which the optional Identifier (the "name") exists.

> I suggest you to and read the ECMA-262 specification for "Function
> Definition".

I have, just in case, but I didn't need to: my memory was quite accurate.

--
Johannes

Stefan Weiss

unread,
Apr 20, 2010, 2:38:49 PM4/20/10
to
On 20/04/10 20:08, Johannes Baagoe wrote:
> Jorge :
>> Johannes Baagoe :

>>> In a sort of lame defence (why on earth am I trying to excuse
>>> it may be argued that function expressions with a name are
>>> a Really Bad Idea from the beginning, and that anyone who uses them
>>> deserves... well, some terrible fate.
>
>> Huh ?
>> How so ?
>
> var fibonacci = (function() {
> var a = 1; var b = 1;
> return function() {
> a = b - a;
> return b += a;
> };
> }());
>
> is fine.
>
> var fibonacci = (function fib() {
> var a = 1; var b = 1;
> return function() {
> a = b - a;
> return b += a;
> };
> }());
>
> or
>
> var fibonacci = (function() {
> var a = 1; var b = 1;
> return function fib() {
> a = b - a;
> return b += a;
> };
> }());
>
> or (even worse)
>
> var fibonacci = (function fib() {
> var a = 1; var b = 1;
> return function fib() {
> a = b - a;
> return b += a;
> };
> }());
>
> are useless and confusing - what is fib ?

Well, don't write useless and confusing code, then :)

The returned inner function in your examples doesn't need a name, so you
don't give it one. Names for function expressions are useful in at least
two cases: for debugging/profiling, and when you want to recurse from
inside a function expression. The only alternative for the second case


would be arguments.callee, which (I think) has recently been deprecated.

Even if it hasn't: making use of the arguments object has a noticeable
performance penalty in modern browsers.


--
stefan

Garrett Smith

unread,
Apr 20, 2010, 2:37:17 PM4/20/10
to
Johannes Baagoe wrote:
> Jorge :
>> nick :
>
>>> "Some JavaScript engines, not including SpiderMonkey, incorrectly treat
>>> any function expression with a name as a function definition"
>
That behavior, as descriped, is not incorrect.

>> LOL. And these engines are made by Microsoft and are called JScript and
>> are the ones used in each and every Internet Explorer, up to and
>> including the current, latest one.
>>

The behavior described is not incorrect.

>> And they manage miraculously to not only screw up the function
>> expression, but the function declaration too. Wonders of software
>> engineering.
>
> In a sort of lame defence (why on earth am I trying to excuse Microsoft?),

If you're asking me to guess, I would say that you have probably

mistaken "function definition" with "function declaration".

I would also speculate that the author(s) of that (badly written) MDC
page may have had the same mistake (or similar lazy, muddled thinking).

Microsoft may have related bugs, but they are described neither in this
thread nor on MDC.

The MDC page and the responses on this thread (including yours) are an
exhibition of misunderstanding of the specification. How ironic, and
hypocritical now, when the responses on this thread call out Microsoft
for exhibiting a misinterpretation of the specification.

I suggest you to and read the ECMA-262 specification for "Function
Definition".

[...]

VK

unread,
Apr 20, 2010, 2:01:27 PM4/20/10
to
On Apr 20, 5:55 am, Johannes Baagoe <baa...@baagoe.com> wrote:
> Should it be
>
>   (function foo() { /*...*/ })();
>
> or
>
>   (function foo() { /*...*/ }());
>
> (note the place of the closing parenthesis) ?

From the pretty-print point of view I might like the second better as
a fully enclosed construct, without emty parenthesis pending on the
right side. From the other side provokes to try function foo() { /
*...*/ }() which is not correct without an expression context. By its
nature the question is dangerously close to "same line vs. next line
bracket placement" and similar rwar topics :-) so I would just suggest
to use either w/o attacking each other :-)
Please note the different named function handling in IE and other UAs:
in IE

(function foo() { /*...*/ })()

is equivalent (with some subtle details) to:

function foo() { /*...*/ };
foo();

so foo is created and remains in the namespace - the standard test I'm
periodically running to monitor possible changes is at the end of the
post. For the fairness sake IE's behavior equals to Netscape 3.x -4.x:
so the guys went out of business first and then decided that it should
work in some other way.
This is why for FunctionExpression only anonymous functions are
normally used.

> Same question for
>
>   var foo = (function() { /*...*/ })();
>
> vs.
>
>   var foo = (function() { /*...*/ }());
>
> etc.

Same answer as above I guess with the same named functions warning.
Also here parenthesis are not necessary, unlike in the first case:
expression context implied by the function position in right side of
the assignment.

Also note that:

function foo() { /*...*/ }
and
var foo = function foo() { /*...*/ };

are not equal by their internal organization.
In the first case we get one dispid in the name table for
"foo" (spitting 3 times over the shoulder let's say *foo - dispid is
not a *pointer but functionally is a relative of it).
In the second case you get 2 dispids: one for the anonymous function,
the other one for "foo".

So in the first case:
look for foo -> get pointer to the function -> get the function

in the second case:
look for foo -> get pointer to anonymous -> look for anonymous -> get
pointer to the function -> get the function

It is true at least for IE - thus sufficient do not endorse function
assignments as the only way of coding. Yet it is in a big fashion
right now, especially among programmers certified in other languages.
In my office I lock such attempts right away, here I would assign it
to yet another rwar topic :-)


FunctionExpression discrepancies test:

<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type="text/javascript">

(function foo(){/*NOP*/}())


function demo() {
window.alert(typeof foo);
}


window.onload = function() {
window.setTimeout('demo()',10)
}
</script>
</head>

<body>
<h1>Demo</h1>
</body>
</html>

Johannes Baagoe

unread,
Apr 20, 2010, 2:54:52 PM4/20/10
to
Stefan Weiss :
>>> Johannes Baagoe :

>>>> function expressions with a name are a Really Bad Idea

> The returned inner function in your examples doesn't need a name, so you


> don't give it one.

It seems that we agree, after all.

--
Johannes

Johannes Baagoe

unread,
Apr 20, 2010, 2:08:04 PM4/20/10
to
Jorge :

> Johannes Baagoe :

>> In a sort of lame defence (why on earth am I trying to excuse

>> it may be argued that function expressions with a name are
>> a Really Bad Idea from the beginning, and that anyone who uses them
>> deserves... well, some terrible fate.

> Huh ?
> How so ?

var fibonacci = (function() {

or

or (even worse)

--
Johannes

Stefan Weiss

unread,
Apr 20, 2010, 2:04:37 PM4/20/10
to
On 20/04/10 19:31, Johannes Baagoe wrote:
> In a sort of lame defence (why on earth am I trying to excuse Microsoft?),
> it may be argued that function expressions with a name are a Really Bad
> Idea from the beginning, and that anyone who uses them deserves... well,
> some terrible fate.

Why? The only disadvantage I see are the problems with Microsoft's
botched implementation.

Didn't you say (in a different thread) that you "quite liked" Jorge's
loop() function? That's a named function expression, too. It doesn't
have to be - you could just call loop() separately from its definition -
but the way you're using it on

http://baagoe.com/en/RandomMusings/javascript/time.js

it's still a named function expression.

Do you deserve a terrible fate now? ;-)


--
stefan

VK

unread,
Apr 20, 2010, 5:11:19 PM4/20/10
to
On Apr 20, 10:01 pm, VK <schools_r...@yahoo.com> wrote:
> Also note that:
>
>  function foo() { /*...*/ }
> and
>  var foo = function foo() { /*...*/ };

A copy-past error, please read:

function foo() { /*...*/ }
and
var foo = function() { /*...*/ };

Johannes Baagoe

unread,
Apr 20, 2010, 5:34:15 PM4/20/10
to
Stefan Weiss :
>Johannes Baagoe :

>> var fact = function(n) {
>> if (n > 0) {
>> return n * fact(n - 1);
>> } else {
>> return 1;
>> }
>> };

> It works, of course, but it makes the recursion dependent on a


> (potentially unrelated) variable from an outer scope. I don't think the
> implementation of a function should need to care about which variable it
> will be assigned to.

Good point. One can enclose them in yet another function, though,
but I'm not sure that makes things clearer.

> And then there are the "self-executing" functions from your original
> examples, which run before their result is assigned to a variable:

> var foo = (function () {
> // what if I want to recurse here?
> })();

You are right, I can't. If I want to define 21! inline using neither
named function expressions nor function declarations, the best I have
come up with is

((function() {
return fact = function(n) {return n > 0 ? n * fact(n - 1) : 1;};
}())(21));

which is hardly a model of legibility.

So there may legitimate uses for named function expressions after all.
The trouble is that their formal definition is so badly ambiguous
that I immediately object on aesthetic if not on sound theoretical
grounds, but I admit that if the implementations always get it right,
it becomes little more than a matter of taste. (Of course, if MDC
doesn't lie, some implementations *don't* get it right, which gives
rather more weight to my theoretical pretexts.)

--
Johannes

Jorge

unread,
Apr 20, 2010, 5:56:52 PM4/20/10
to
On Apr 20, 8:37 pm, Garrett Smith <dhtmlkitc...@gmail.com> wrote:
> (...)

> The MDC page and the responses on this thread (including yours) are an
> exhibition of misunderstanding of the specification. How ironic, and
> hypocritical now, when the responses on this thread call out Microsoft
> for exhibiting a misinterpretation of the specification.
> (...)

The JScript named function expressions BUG (a BUG that's been in each
and every Microsoft Internet Explorer since IE3 up to the greatest and
latest IE8, for **11**YEARS** now, and still counting) can hardly be
considered a "misinterpretation of the specification" wrt to "Chapter
13. Function definitions" of ES-262, 3rd edition, for in the very
first page of that chapter you can read:

"NOTE The Identifier in a FunctionExpression can be referenced from
inside the FunctionExpression's FunctionBody to allow the function to
call itself recursively. However, unlike in a FunctionDeclaration, the
Identifier in a FunctionExpression cannot be referenced from and does
not affect the scope enclosing the FunctionExpression."

How can one possibly misinterpret that ?

If you want to talk hypocritical : loud applause for you.
--
Jorge.

Garrett Smith

unread,
Apr 20, 2010, 6:38:42 PM4/20/10
to
Johannes Baagoe wrote:
> Stefan Weiss :
>> Johannes Baagoe :
>
[...]

> You are right, I can't. If I want to define 21! inline using neither
> named function expressions nor function declarations, the best I have
> come up with is
>
> ((function() {
> return fact = function(n) {return n > 0 ? n * fact(n - 1) : 1;};
> }())(21));
>
> which is hardly a model of legibility.
>

Or design.

Syntactially, it could do without the excess grouping operator and
certainly can do without creating a global identifier within a function.

However if the goal is to write a factorial function, it would be best
to focus on that; so changing the syntax would miss the point.

A factorial function should consider input > 170, i.e. throw a
RangeError, utilize a user-defined `BigNumber`, etc.

> So there may legitimate uses for named function expressions after all.
> The trouble is that their formal definition is so badly ambiguous
> that I immediately object on aesthetic if not on sound theoretical
> grounds, but I admit that if the implementations always get it right,
> it becomes little more than a matter of taste. (Of course, if MDC
> doesn't lie, some implementations *don't* get it right, which gives
> rather more weight to my theoretical pretexts.)
>

The formal grammar for FunctionExpression, with optional Identifier, can
be easily understood.

MDC published misinformation there, unfortunately. I do not know why you
cannot see that; I have explained it well enough twice now. If there is
any part of my explanation that was confusing, or that you thought was
wrong, please specify.

Jorge

unread,
Apr 20, 2010, 6:38:51 PM4/20/10
to
On Apr 20, 8:08 pm, Johannes Baagoe <baa...@baagoe.com> wrote:
> (...)

> are useless and confusing - what is fib ?

I'd just repeat what Stefan has told you already. To recapitulate:

1.- They're not used much due to the named function expressions BUG in
Microsoft's Internet Explorers (in ALL of them).
2.- The function's name is defined inside the function, where it's
safer (and faster too) than in the enclosing scope.
3.- (function functionName () {}).name is === "functionName". So you
can get it from the outside, if you ever need to.

Plus a 4th point of my own:

4.- It's a pity but it's the truth that this BUG and the many others,
long-standing JScript BUGS that Microsoft has been careful not to fix
ever, have had the (intended) effect of spoiling what would have been
otherwise a much nicer language to work with, and with which the web
as a platform could have developed much better and much faster. But as
-unfortunately- that was against Microsoft's own interests, this is
what they've gifted us. It's just another gem of Microsoft's legacy
for the WWW: a functional language with the lambdas badly broken. Make
no mistakes: it's not by coincidence.
--
Jorge.

Johannes Baagoe

unread,
Apr 20, 2010, 6:39:08 PM4/20/10
to
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.

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

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.

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.

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

On the other hand, if the "Identifier opt" part in the definition of
FunctionExpression were removed, there would be no ambiguity at all.

Which explains my perhaps excessive dislike of named function expressions.

--
Johannes

VK

unread,
Apr 20, 2010, 6:46:51 PM4/20/10
to
On Apr 21, 1:56 am, Jorge <jo...@jorgechamorro.com> wrote:
> "NOTE The Identifier in a FunctionExpression can be referenced from
> inside the FunctionExpression's FunctionBody to allow the function to
> call itself recursively. However, unlike in a FunctionDeclaration, the
> Identifier in a FunctionExpression cannot be referenced from and does
> not affect the scope enclosing the FunctionExpression."
>
> How can one possibly misinterpret that ?

Easily: please see my post in this thread. NN3 - NN4 did *exactly*
what IE did and does. So the hypocrisy is on some core Mozilla team
members who for years programmed exactly what IE programmed, then
failed and went off the business, then did a new interpretation of the
rule, then started from the scratch with a new browser - so anyone who
managed to stay on the market w/o a break became a standard violator.

For my narrow mind the whole relevant paragraph is bloody idiotic, but
is definitely because of my regular lack of IQ points. Because for me
(expression)
means "do whatever needed to evaluate the expression and return the
result". In this aspect
(function foo(){/*whatever*/}())
is no different: it means "create foo, execute it, set the expression
value to the function return value".

This IE's behavior is won't-fix anyway, so not a bug but a peculiarity
(aka a feature), so interesting for a theoretical discussion only.
From this theoretical point of view I'd like to grasp - and be
merciful on my weak mind - why
var bar = (function foo(){/*whatever*/}())
window.alert(typeof foo); // function
pisses some Mozilla people off for year while
var a = (b = 1);
window.alert(a);
window.alert(b); // 1
keeps them relaxed?


Johannes Baagoe

unread,
Apr 20, 2010, 8:06:07 PM4/20/10
to
Jorge :

[named function expressions]

> 1.- They're not used much due to the named function expressions BUG
> in Microsoft's Internet Explorers (in ALL of them).

That may the case for many people, but it has nothing whatsoever to
do with *my* dislike of named function expressions. I hate them
because their syntax sucks. Bugs in Microsoft products are of no
concern to me, since I don't use them.

> 2.- The function's name is defined inside the function, where it's
> safer (and faster too) than in the enclosing scope.

Where that is a concern, I use a function declaration.

> 3.- (function functionName () {}).name is === "functionName".
> So you can get it from the outside, if you ever need to.

I don't, since I don't use named function expressions. If I want to
use a function more than once, either I declare it, or I assign its
expression to a variable.

> Plus a 4th point of my own:

> 4.- [...] Microsoft has been careful not to fix ever, have had the
> (intended) effect [...] Microsoft's own interests, [...] Make no


> mistakes: it's not by coincidence.

I couldn't care less about Microsoft. On the other hand, I don't
speculate on nefarious motives and intents, either.

--
Johannes

VK

unread,
Apr 20, 2010, 8:06:42 PM4/20/10
to
On Apr 21, 2:46 am, VK <schools_r...@yahoo.com> wrote:
> This IE's behavior is won't-fix anyway, so not a bug but a peculiarity
> (aka a feature), so interesting for a theoretical discussion only.
> From this theoretical point of view I'd like to grasp - and be
> merciful on my weak mind - why
>  var bar = (function foo(){/*whatever*/}())
>  window.alert(typeof foo); // function
> pisses some Mozilla people off for year while
>  var a = (b = 1);
>  window.alert(a);
>  window.alert(b); // 1
> keeps them relaxed?

Or for that matter:

<script type="text/javascript">
var a = ( (b = 1) + 1 );
window.alert(a); // 2
window.alert(b); // 1

function f() {
var c = ( (d = 1) + 1 );
}

f();

window.alert(typeof c); // undefined
window.alert(typeof d); // number
</script>

and it is OK but FunctionExpression is a matter of some silly rwar for
years? I mean since when (expression parenthesis) became contextually
dependent visibility scope regulators in JavaScript? Did I miss some
important events?

Garrett Smith

unread,
Apr 20, 2010, 8:18:38 PM4/20/10
to
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)

<https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Functions#section_15>


> 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.

ExpressionStatement
ExpressionStatement
[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 :
PrimaryExpression
FunctionExpression
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
FormalParameterList
properties.
 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.
[...]

Stefan Weiss

unread,
Apr 20, 2010, 8:32:11 PM4/20/10
to
On 21/04/10 02:06, VK wrote:
> On Apr 21, 2:46 am, VK <schools_r...@yahoo.com> wrote:
>> This IE's behavior is won't-fix anyway, so not a bug but a peculiarity
>> (aka a feature), so interesting for a theoretical discussion only.

That they've decided not to fix it doesn't make it any less a bug. You
can call it a feature, if you want, but don't get upset when others
don't agree with you.

>> From this theoretical point of view I'd like to grasp - and be
>> merciful on my weak mind - why
>> var bar = (function foo(){/*whatever*/}())
>> window.alert(typeof foo); // function
>> pisses some Mozilla people off for year while
>> var a = (b = 1);
>> window.alert(a);
>> window.alert(b); // 1
>> keeps them relaxed?

Because one works as specified, and the other doesn't.

> Or for that matter:
>
> <script type="text/javascript">
> var a = ( (b = 1) + 1 );
> window.alert(a); // 2
> window.alert(b); // 1
>
> function f() {
> var c = ( (d = 1) + 1 );
> }
>
> f();
>
> window.alert(typeof c); // undefined
> window.alert(typeof d); // number
> </script>
>
> and it is OK but FunctionExpression is a matter of some silly rwar for
> years? I mean since when (expression parenthesis) became contextually
> dependent visibility scope regulators in JavaScript? Did I miss some
> important events?

You may have missed what happens when you assign to an undeclared
identifier: it becomes a property of the global object. Are you asking
why 'c' was kept local and 'd' wasn't, or are you asking why people
think that's a good thing?


--
stefan

Garrett Smith

unread,
Apr 20, 2010, 8:39:10 PM4/20/10
to
Garrett Smith wrote:
> Johannes Baagoe wrote:
>> Garrett Smith :
>>
[...]

> | or FunctionExpression : function Identifier (
> FormalParameterListopt ) { FunctionBody } create a property of the
> variable object whose name
> is the Identifier in the FunctionDeclaration or FunctionExpression,

Sorry about the formatting. I apparently hit Thunderbird's "send"
keyboard shortcut. I do not recall what that is, but seem to have hit it
while typing, 'cause it got sent.

The full production for JScriptFunction is found in the document
MS-ES3.pdf, linked from the Resources section of the FAQ.

[snip]

RobG

unread,
Apr 20, 2010, 10:58:40 PM4/20/10
to
On Apr 20, 3:05 pm, nick <nick...@fastmail.fm> wrote:

> On Apr 19, 9:55 pm, Johannes Baagoe <baa...@baagoe.com> wrote:
>
> > Same question for
>
> >   var foo = (function() { /*...*/ })();
>
> > vs.
>
> >   var foo = (function() { /*...*/ }());
>
> Those shouldn't need the extra parentheses...
>
>     var foo = function() { /*...*/ }();
>
> ...should be valid.
>
> But nobody ever does that, which makes me think some old(ish) browsers
> might be more picky, especially after reading this:
>
> https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Functions
> #Function_constructor_vs._function_declaration_vs._function_expression
>
> "Some JavaScript engines, not including SpiderMonkey, incorrectly

> treat any function expression with a name as a function definition"

That article seems quite confused, e.g.

| A function declaration also creates a variable
| with the same name as the function name. Thus,
| unlike those defined by function expressions,
| functions defined by function declarations can be
| accessed by their name in the scope they were
| defined in:
|
| 1. function x() {}
| 2. alert(x); // outputs x serialized into a string

Which is may well be confusing as function expressions exhibit exactly
the same behaviour:

var x = function(){};
alert(x); // outputs x serialized into a string

It goes on with:

| The following example shows how function
| names are not related to variables functions
| are assigned to. If a "function variable"
| is assigned to another value, it will still
| have the same function name:
|
| 1. function foo() {}
| 2. alert(foo); // alerted string contains function name "foo"
| 3. var bar = foo;
| 4. alert(bar); // alerted string still contains function name
"foo"

Of course it does, it's a serialisation of the function declaration so
naturally includes the name. Named function expressions behave exactly
the same:

var x = function y(){};
alert(x); // shows function y() {}


The article seems to be a collection of thoughts about functions,
rather than a structured tutorial about functions. I would not
recommend it to anyone trying to learn ECMAScript.


--
Rob

Garrett Smith

unread,
Apr 20, 2010, 11:41:14 PM4/20/10