Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Closing parenthesis in function's definition followed by its call

218 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
to
RobG wrote:
> On Apr 20, 3:05 pm, nick <nick...@fastmail.fm> wrote:
>> On Apr 19, 9:55 pm, Johannes Baagoe <baa...@baagoe.com> wrote:
>>
[...]

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

That output depends on the behavior of host method `alert`, and the
implementation-dependent behavior for Function.prototype.toString.

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

That bug was knowingly and deliberately included in ECMAScript 262,
edition 5.

The bug is that the spec says Function.prototype.toString must return a
FunctionDeclaration. Instead, implementations mostly, for user-defined
functions, return a representation of a function, either as a
FunctionExpression or a FunctionDeclaration.

When a function has no identifier, it cannot be considered as a
production for FunctionDeclaration and so the string "function(){}", as
returned by implementations, is not a representation of a
FunctionDeclaraton. I proposed the specification to change to allow
FunctionExpression. I did not see a thoughtful, reasonable response to
that; EOD[1].

[...]

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

It needs some organizational work and technical corrections.

[1]<https://mail.mozilla.org/pipermail/es-discuss/2009-September/009820.html>

Lasse Reichstein Nielsen

unread,
Apr 21, 2010, 1:19:34 AM4/21/10
to
Johannes Baagoe <baa...@baagoe.com> writes:

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

It's worth noticing that the above is not valid ECMAScript. The
content of the if match either FunctionDeclaration or
FunctionExpression, but neither is allowed at that point
(FunctionDeclaration because it is not a Statement, but only a
SourceElement, i.e., it can only occur directly inside a function body
or at top-level, and FunctionExpression because a StatementExpression
may not start with "function").

I.e., it's an ECMAScript extension that Mozilla allows it - as a
"FunctionStatement".
The other browsers that also allow it are also extending ECMAScript,
but probably interpret it slightly differently.

The real problem with IE isn't that it allows the above, but that
this code:
var foo = function bar() { ... };
also leaks "bar" as a variable in the surrounding scope. No other
browser does so.
(I still prefer to use named function expressions for recursion, but
one does have to consider the name in both the internal and external
scope).

...


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

Neither are wrong in extending the syntax to allow your code above.
It's simply an extension, like so many others.

IE is wrong in its implementation of named FunctionExpressions, which
are fully defined in the specification and not subject to "extensions".

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

Correct. That's why they are not allowed at the same places: An
ExpressionStatement may not begin with "function", which means that
a FunctionDeclaration cannot be mistaken for a FunctionExpression,
since the latter is not valid at that point.

> That is a syntactic ambiguity of about the worst sort imaginable.

Oh, this is pretty simple.
Try figuring out how to distinguish divisions, end-of-line comments
and RegExp literals. :)



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

Done.

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

There would also be no easy way to make recursive function expressions.
Using arguments.callee sucks (both performance-wise and readability-wise).

/L
--
Lasse Reichstein Holst Nielsen
'Javascript frameworks is a disruptive technology'

VK

unread,
Apr 21, 2010, 5:25:00 AM4/21/10
to
> > 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?

"when you assign to an undeclared identifier: it becomes a property of

the global object" - right

And when you execute an undeclared named function: it has to be first
created so becomes a property of the global object just like above.
One cannot execute something w/o having it first.
My point being is that JavaScript has function-level scope visibility,
not expression-level scope visibility. This way (expression) doesn't
affect the scope, only {function} does.
It was decided to make an exception for FunctionExpression - fine, but
why it is called obvious and natural - remains a mystery to me.

Jorge

unread,
Apr 21, 2010, 7:00:00 AM4/21/10
to
On Apr 21, 2:06 am, Johannes Baagoe <baa...@baagoe.com> wrote:
> 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.

Neither do I.

But as so many people have wasted countless hours in trying to spot,
comprehend and devise workarounds for each and every of Microsoft's
Internet Explorer BUGS, because they (thought they) had to, even
today, when you browse this group's archive, you'll see that most of
the regulars equate one's knowledge of JS to one's knowledge of
Microsoft IE's bugs (*) and workarounds and its many other -countless-
bizarre behaviours. It's pitiful. And it's been a severe drag in
moving the web forward. And still is.

As a consequence, whenever you post code with a named function
expression, some cleverer regular jumps in to "correct" it.

(*)E.g.: most regulars here assume `window` to be a host object. LOL.
--
Jorge.

Johannes Baagoe

unread,
Apr 21, 2010, 8:48:15 AM4/21/10
to
Garrett Smith :
> Johannes Baagoe :

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

Of course. 51090942171709440000 is much more efficient.

But that isn't the point. I try to figure out whether there are cases
where function expressions need be named, or at least are better named.
My starting position is (or was) "No, named functions are creatures
of the darkness - their syntax sucks by mixing two notions in a way
that is bound create to confusion, for no benefit at all". (And Microsoft
has *nothing* to do with the matter, I didn't suspect that *other*
objections to named function expressions were part of a holy war.)

However, as Stefan Weiss and others rightly point out, there appears
to be at least one case where names for function expressions are
definitely useful: when the function expression calls itself. There
are alternatives, but they are not clearly better, and in the case
of my rather quixotic attempt above, clearly worse.

--
Johannes

Scott Sauyet

unread,
Apr 21, 2010, 9:34:17 AM4/21/10
to
Johannes Baagoe wrote:
> [ ... ] I try to figure out whether there are cases

> where function expressions need be named, or at least are better named.
> My starting position is (or was) "No, named functions are creatures
> of the darkness - their syntax sucks by mixing two notions in a way
> that is bound create to confusion, for no benefit at all". (And Microsoft
> has *nothing* to do with the matter, I didn't suspect that *other*
> objections to named function expressions were part of a holy war.)
>
> However, as Stefan Weiss and others rightly point out, there appears
> to be at least one case where names for function expressions are
> definitely useful: when the function expression calls itself. There
> are alternatives, but they are not clearly better, and in the case
> of my rather quixotic attempt above, clearly worse.

The holy war you mentioned is important here, though. Although named
function expressions are very useful, some Microsoft bugs make them
much less useful than they should be in this case.

The article by kangax [1] explains the issues in detail. But in
brief, here's some IE results:

typeof g; // "function"
var f = function g(){};
f === g; // false
f.expando = 'foo';
g.expando; // undefined

the reference g escapes the function, and appears even before the
declaration, and f and g are not two separate references to the same
function, but two distinct functions!

I'm not sure of the rationale that deprecated arguments.callee, but
that was the other alternative in these cases; I'm not sure what we're
left with now besides terrible hacks like the one you presented and
rejected.

-- Scott
____________________
[1] http://yura.thinkweb2.com/named-function-expressions/

Johannes Baagoe

unread,
Apr 21, 2010, 9:35:14 AM4/21/10
to
Lasse Reichstein Nielsen :
> Johannes Baagoe :

>> MDC's bone of contention is this:
>>
>> if (0) {
>> function zero() {
>> document.writeln("This is zero.");
>> }
>> }

> It's worth noticing that the above is not valid ECMAScript.


> The content of the if match either FunctionDeclaration or
> FunctionExpression, but neither is allowed at that point
> (FunctionDeclaration because it is not a Statement, but only a
> SourceElement, i.e., it can only occur directly inside a function body
> or at top-level, and FunctionExpression because a StatementExpression
> may not start with "function").

Aha. Now that, I understand. It did seem curious to define functions
conditionally in this `#ifdef`-like way.

> I.e., it's an ECMAScript extension that Mozilla allows it - as a
> "FunctionStatement".

> The other browsers that also allow it are also extending ECMAScript, but
> probably interpret it slightly differently.

I see that 5th ed. addresses the problem: (12)

NOTE Several widely used implementations of ECMAScript are known to
support the use of FunctionDeclaration as a Statement. However there
are significant and irreconcilable variations among the implementations
in the semantics applied to such FunctionDeclarations. Because of
these irreconcilable difference, the use of a FunctionDeclaration
as a Statement results in code that is not reliably portable among
implementations.

IOW, avoid, unless for personal use or strictly controled intranets.
Even there, it is hard to see any real benefit. If different functions
are needed according to flags (say, various versions of an `assert`
function for debugging), assign them to the same variable in conditions
at the start of the code.

[Very clear explanation of when "function foo() {}" is a function
declaration, and when it is a function expression - many thanks !]

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

> There would also be no easy way to make recursive function
> expressions. Using arguments.callee sucks (both performance-wise
> and readability-wise).

One could assign the function to a variable in the enclosing scope,
but I have to agree that it useful to be able simply to name the
function for the benefit of its internal scope.

--
Johannes

Richard Cornford

unread,
Apr 21, 2010, 9:56:53 AM4/21/10
to
Lasse Reichstein Nielsen wrote:
>> MDC's bone of contention is this:
>>
>> if (0) {
>> function zero() {
>> document.writeln("This is zero.");
>> }
>> }
<snip>

> The real problem with IE isn't that it allows the above, but
> that this code:
> var foo = function bar() { ... };
> also leaks "bar" as a variable in the surrounding scope.
> No other browser does so.

That is the problem, but it is not the full extent of the problem. The
function that is referred to by the 'leaked' - bar - is not the same
function object as the one that will be referred to by - foo - following
the evaluation of - foo = function bar() { ... }; -, and - bar - will
exist and refer to its (second/other) function from variable
instantiation onwards. That is, bar exists prior to the evaluation of
the function expression that creates the function object that is
assigned to - foo -, and exists unconditionally (independently of
whether the - foo = function bar() { ... }; - ever actually gets
executed.

> (I still prefer to use named function expressions for recursion,
> but one does have to consider the name in both the internal and
> external scope).

<snip>

Which presumably includes taking into account that if code in the body
of the - foo = function bar() { ... }; - function refers to - bar - and
it is the function object that was created as a result of evaluating the
function expression that is executed, the - bar - references will be
referees to the other function object (the one previously crated during
variable instantiation). I.E. in that context - (bar !=
arguments.callee) - would be true (with implications for the respective
scope chains employed), and any initial call to - bar - would not
actually be recursion.

Richard.

Richard Cornford

unread,
Apr 21, 2010, 9:56:55 AM4/21/10
to
VK wrote:

> On Apr 21, 1:56 am, Jorge 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.

No thank you.

> NN3 - NN4 did *exactly* what IE did and does.

No they didn't. For a start function expressions were introduced into
JavaScript(tm) in version 1.2 (possibly even 1.3), which means that
Netscape Navigator 3 could not treat function expressions the same way
as JScript does, as it had none to treat in any way. Netscape Navigator
4 did not create 2 distinct function objects in association with
evaluating a named function expression, so that is not "*exactly* what
IE did" either.

> So the hypocrisy is ... .

Evident.

> For my narrow mind the whole relevant paragraph is bloody idiotic,
> but is definitely because of my regular lack of IQ points.

It is your problems with achieving a rational thought process that is
the problem.

> Because for me (expression) means "do whatever needed to evaluate
> the expression and return the result".

Which is far too imprecise to be of any use to anyone.

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

They might. The creation of the additional function object really isn't
that sensible/useful a thing to be doing.

> 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

What do you imagine pissed them off? Finding that - (foo !== bar) - is
true in JScript when - typeof - both - foo - and - bar - is still
'function' seems like a good reason.

> var a = (b = 1);
> window.alert(a);
> window.alert(b); // 1
>keeps them relaxed?

Well, in that case - (a !== b) - is false.

Richard.

Richard Cornford

unread,
Apr 21, 2010, 9:56:52 AM4/21/10
to
VK wrote:
>>> 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?
>
> "when you assign to an undeclared identifier: it becomes a property
> of the global object" - right
>
> And when you execute an undeclared named function: it has to be
> first created

Evaluating a function expression should result in the creation of a
function object, which then must then 'exist' and have some
manifestation that occupies memory somewhere on the computer.

> so becomes a property of the global object

Not so. The creation of any object (function or otherwise) does not
necessitate the creation of, or assignment to, properties of the global
object.

> just like above.

The above case shows a function declaration in the global execution
context, which will result in the creation of a property of the global
object, as the global object is used as the Variable object for the
global execution context. A function declaration in a function execution
context will result in the creation of a property of the function
execution context' Variable object (which is never the global object).

Function expressions, as opposed to declarations, need not result in the
creation of any properties of any objects at all. And the IE/JScript bug
that results in named function expressions being additionally processed
as function declarations causes the additional function that is created
to be assigned to a property of the Variable object of the execution
context in which the expression is located, which will only be the
global object for the global execution context.

> One cannot execute something w/o having it first.

True, but "having" something does not require that it be assigned to a
property of any object in javascript, and so certainly does not require
that it "becomes a property of the global object".

> My point

You have a point?

> being is that JavaScript has function-level scope
> visibility, not expression-level scope visibility.
> This way (expression) doesn't affect the scope, only
> {function} does.

That is not a point, it is a poorly/vaguely worded statement of fact.

> It was decided to make an exception for FunctionExpression -
> fine,

It wasn't.

> but why it is called obvious and natural -

Who called it that? Why the code you posted does what it does is obvious
("natural" is a slightly perverse term to attempt to apply computer
code); just a matter of understanding the scoping rules for the language
being used.

> remains a mystery to me.

It won't be alone.

Richard.

Richard Cornford

unread,
Apr 21, 2010, 9:57:00 AM4/21/10
to
Scott Sauyet wrote:
<snip>

> I'm not sure of the rationale that deprecated arguments.callee,

In what sense deprecated? The - arguments.callee - property is still
available in ES5, just not in ES5 'strict' mode. It has yet to be
established that ES5 'strict' mode is a suitable/viable language variant
for general purpose browser scripting work, and in the event that it
doesn't turn out to be viable it won't be that widely used and so could
not then form the basis for any ES6+. Thus the future of -
arguents.callee - is probably independent of the future of ES5 'strict',
necessitating any genuine attempt to deprecate it to be associated with
some full ES6+ rather than just an opt-in variant.

> but that was the other alternative in these cases; I'm not sure
> what we're left with now besides terrible hacks like the one you
> presented and rejected.

Mostly inner function declarations probably. If JScript is going to
(additionally) process named function expressions as declarations anyway
then the way back to consistent behaviour might by to deliberately go
for function declarations instead.

Richard.

Richard Cornford

unread,
Apr 21, 2010, 9:56:58 AM4/21/10
to
Johannes Baagoe wrote:
> Garrett Smith :
>> Johannes Baagoe :
>
>>> 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;};
^^^^
As that - fact - is undeclared there is a side effect of creating a
property of the global object and assigning the function to that, in
which case why not a global declared global - fact - function
declaration? The effect would be the same and the code would be simpler.
Of course declaring - fact - as a function local variable in the
surrounding function would work fine, and without the long-term global
side effect. But then, why not an inner function declaration, as in:-

((function() {
function fact(n){


return n > 0 ? n * fact(n - 1) : 1;
}

return fact;
}())(21));

- or the simpler:-

(function(x) {
function fact(n){


return n > 0 ? n * fact(n - 1) : 1;
}

return fact(x);
}(21));

>>> }())(21));
>>>
>>> which is hardly a model of legibility.
>
>> Or design.
>
> Of course. 51090942171709440000 is much more efficient.
>
> But that isn't the point. I try to figure out whether there
> are cases where function expressions need be named,

Which I think must require an example situation where a named function
expression couldn't be replaced with an inner function declaration (that
there be a good reason for not doing so), or a very good argument
against function declarations.

> or at least are better named. My starting position is (or
> was) "No, named functions are creatures of the darkness -
> their syntax sucks by mixing two notions in a way
> that is bound create to confusion, for no benefit at all".

> (And Microsoft has *nothing* to do with the matter, I didn't
> suspect that *other* objections to named function expressions
> were part of a holy war.)

Don't mistake (the better informed) objections to JScript's handling of
named function expressions for a "holy war". What JScript does is hugely
problematic as it appears to 'work' under most circumstance (apparently
you can call a named function expression recursively using its name) but
what actually happens is not what most would think is happening, and so
there is a potential for really unrecognisable bugs to be introduced in
JScript, infrequently but just at the point were scope chain structures
are getting complex.

Of course efficiency and memory use-wise, creating two function objects
in association with the evaluation of any named function expression
isn't such a good idea either, but for most web page scripts that is
hardly going to be noticeable.

> However, as Stefan Weiss and others rightly point out, there
> appears to be at least one case where names for function
> expressions are definitely useful: when the function expression
> calls itself.

Which would be fine if they always did call themselves.

> There are alternatives, but they are not clearly better,

It is not better when the code you write does the same thing in all
javascript environments instead of doing something unique in just one of
them?

> and in the case of my rather quixotic attempt above, clearly
> worse.

At least your example would behave the same under JavaScript(tm) and
JScript.

Richard.

Richard Cornford

unread,
Apr 21, 2010, 9:56:56 AM4/21/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?

As I am responsible for that construct's use in browser scripting I
should probably say something about the positioning of the parenthesise.
There was no reason (good or otherwise) for the 'choice' of putting the
parenthesise round the function expression rather than the whole call
expression. It was probably a case of the thinking about parenthesise
stopping at the point of having something that 'worked', and then the
form of the first examples being re-produced without this aspect being
questioned.

There would have been some influence from structures such as:-

function doSomething(x){
// code that does some 'set-up' on the first
// invocation that does not need to be repeated.

/* Replace the global function with a new one that does the actual
work, and call that function so that the work gets done along
with the 'set-up' on the first invocation of - doSomething -.
*/
(doSomething = function(n){
// code that does whatever without repeating the 'set-up'.
})(x);
}

- which were not uncommon at the time (at least in some circles), and
where - (x = function(){ ... }()); - is not a viable substitute
(though - ((x = function(){ ... })()); - would have been fine). Today I
would probably split the last statement above into two and have a simple
assignment of the function followed by an explicit call to -
doSomething - as a second statement. (Experience having had the effect
of prompting a bias towards code readability over the convolutions that
some label "elegance" these days).

So, parenthesise around the whole call expression; why not?

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

> etc.

Again; why not?

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

I don't think that works as an argument. Wouldn't such an editor's
ability to match parenthesises make sorting out the scope of complex
arguments fairly simple in any case, given that the call surrounds the
arguments with a pair of them?

> Are there better arguments in favour of the former ?

Better? Are there any real arguments for the former, beyond habit,
fashion, etc? Not that those can be entirely dismissed as oft-used
structures can become easily recognised/understood by virtue of their
familiarity.

Richard.

Ry Nohryb

unread,
Apr 21, 2010, 10:14:48 AM4/21/10
to
On Apr 20, 11:34 pm, Johannes Baagoe <baa...@baagoe.com> wrote:
> (...)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));

(function (fact) {


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

})()(21)

Note how clearly and unequivocally "()()" reveals two consecutive
function calls, much more than a muddy "())())".
And "fact" was a global in yours.
--
Jorge.

Scott Sauyet

unread,
Apr 21, 2010, 10:30:44 AM4/21/10
to
Richard Cornford wrote:

> Scott Sauyet wrote:
>> I'm not sure of the rationale that deprecated arguments.callee,
>
> In what sense deprecated? The - arguments.callee - property is still
> available in ES5, just not in ES5 'strict' mode. [ ... ]

I suppose that the only sense in which it's deprecated is just that:
there is a suggestion that some strict mode of operations is in some
way better; that mode does not include arguments.callee. I haven't
paid close attention yet to strict mode. But I did assume that it was
intended as the basis for a newer specification that was considered in
some way superior.

I'm curious as to the rationale for leaving arguments.callee out of
strict mode, though. Do you have any pointers to the reasons behind
this?


>> but that was the other alternative in these cases; I'm not sure
>> what we're left with now besides terrible hacks like the one you
>> presented and rejected.
>
> Mostly inner function declarations probably. If JScript is going to
> (additionally) process named function expressions as declarations anyway
> then the way back to consistent behaviour might by to deliberately go
> for function declarations instead.

Yes, and this does solve the basic problem that the other solutions
were often addressing:

var fact = function(n) {


return n > 0 ? n * fact(n - 1) : 1;
}

var g = fact;
fact = null; // g now does not work.


With inner functions, we're ok:

var fact = (function() {
function f(n){
return n > 0 ? n * f(n - 1) : 1;
}
return f;
}());
var g = fact;
fact = null; // g still works.


I suppose that is what we have available. But these still seems more
elegant and more immediately comprehensible:

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

or

var fact = function(n) {
return n > 0 ? n * arguments.callee(n - 1) : 1;
}

I'll probably continue to use the latter format unless I find a need
to use strict mode or someone can explain what's wrong with
arguments.callee.

--
Scott

Ry Nohryb

unread,
Apr 21, 2010, 10:31:42 AM4/21/10
to
On Apr 21, 4:14 pm, Ry Nohryb <jo...@jorgechamorro.com> wrote:
> On Apr 20, 11:34 pm, Johannes Baagoe <baa...@baagoe.com> wrote:
>
> > (...)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));
>
> (function (fact) {
>   return fact= function (n) {
>     return n > 0 ? n * fact(n - 1) : 1;
>   };
>
> })()(21)


Of course it would still be much better to use a named FE, Microsoft
permitting :

(function fact (n) {


return n > 0 ? n * fact(n - 1) : 1;

})(21)


I find both of them truly beautiful and legible rather than "hardly a
model of legibility".
--
Jorge.

Richard Cornford

unread,
Apr 21, 2010, 11:04:26 AM4/21/10
to
Scott Sauyet wrote:
> Richard Cornford wrote:
>> Scott Sauyet wrote:
>>> I'm not sure of the rationale that deprecated arguments.callee,
>>
>> In what sense deprecated? The - arguments.callee - property is
>> still available in ES5, just not in ES5 'strict' mode. [ ... ]
>
> I suppose that the only sense in which it's deprecated is just
> that: there is a suggestion that some strict mode of operations
> is in some way better; that mode does not include arguments.callee.
> I haven't paid close attention yet to strict mode. But I did
> assume that it was intended as the basis for a newer specification
> that was considered in some way superior.

Very much intended as the basis for newer specification (with an
intention to define new 'syntactic sugar' only in terms of strict mode
code (rather than written algorithms)), and considered, in some sense,
'superior' by its creators. However, the dearth of actual browser
scripting experience among the members of the ECMA committee (their
being mostly language experts and implementers) suggests a need to test
their creation against its ability to solve browser-scripting problems
before accepting it as 'superior'.

> I'm curious as to the rationale for leaving arguments.callee out
> of strict mode, though. Do you have any pointers to the reasons
> behind this?

Well, - arguments.callee - is pretty redundant in a correct ES5
implementation as named function expressions (or at least the function
objects resulting from their evaluation) can call themselves recursively
by name.

>>> but that was the other alternative in these cases; I'm not sure
>>> what we're left with now besides terrible hacks like the one you
>>> presented and rejected.
>>
>> Mostly inner function declarations probably. If JScript is going to
>> (additionally) process named function expressions as declarations
>> anyway then the way back to consistent behaviour might by to
>> deliberately go for function declarations instead.
>
> Yes, and this does solve the basic problem that the other solutions
> were often addressing:
>
> var fact = function(n) {
> return n > 0 ? n * fact(n - 1) : 1;
> }
> var g = fact;
> fact = null; // g now does not work.

I am never convinced that solving the problem of people later writing
code that screws something up is a problem worth solving. The potential
for writing code that screws things up always will far exceed any
ability to defend against it, so if someone wants to do that they will
manage it one way or another, and if they didn't want to they will (or
should) observe that they have broken something and so go back an change
their code so that it works correctly in context.

> With inner functions, we're ok:
>
> var fact = (function() {
> function f(n){
> return n > 0 ? n * f(n - 1) : 1;
> }
> return f;
> }());
> var g = fact;
> fact = null; // g still works.
>
>
> I suppose that is what we have available. But these still seems more
> elegant and more immediately comprehensible:
>
> var fact = function f(n)
> return n > 0 ? n * f(n - 1) : 1;
> }
>
> or
>
> var fact = function(n) {
> return n > 0 ? n * arguments.callee(n - 1) : 1;
> }
>
> I'll probably continue to use the latter format unless I find a need
> to use strict mode or someone can explain what's wrong with
> arguments.callee.

The main argument against - arguments.callee - is - arguments -. It has
been observed that there are implementations that do not create an -
arguments - object if your code does not refer to - arguments -(after
all, you cannot tell the difference in those cases so the required
behaviour is still there). This is more efficient at runtime (as it is
one fewer object to create/set-up for each function call), and so might
be a good thing to encourage.

Richard.

Johannes Baagoe

unread,
Apr 21, 2010, 11:22:23 AM4/21/10
to
Scott Sauyet :

> I'm not sure what we're left with now besides terrible hacks like
> the one you presented and rejected.

At this point, I would say:

1. Declare the functions when there is no good reason for using
function expressions. (Mere pursuit of cuteness does not qualify as
a good reason, except for recreational purposes.)

Thus, Richard Cornford's

(function(x) {
function fact(n) {


return n > 0 ? n * fact(n - 1) : 1;
}

return fact(x);
}(21));

2. If function declarations are undesirable (e.g., for didactic
reasons), assign the inner function to a variable in the outer
function's scope:

(function(x) {
var fact = function(n) {


return n > 0 ? n * fact(n - 1) : 1;
}

return fact(x);
}(21));

> [1] http://yura.thinkweb2.com/named-function-expressions/

Very interesting, thanks a lot.

--
Johannes

Johannes Baagoe

unread,
Apr 21, 2010, 11:58:26 AM4/21/10
to
Richard Cornford :
>>> Johannes Baagoe :

>>>> 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;};
> ^^^^
> As that - fact - is undeclared there

Ooops! I wonder how long I shall continue to make that mistake again
and again. Allowing undeclared variables is bad IMHO, but making
them *global* by default is even worse. It is one of the things I still
hate in javascript, with semicolon insertion and a few others.

> But then, why not an inner function declaration, as in:-
>
> ((function() {
> function fact(n){
> return n > 0 ? n * fact(n - 1) : 1;
> }
> return fact;
> }())(21));
>
> - or the simpler:-
>
> (function(x) {
> function fact(n){
> return n > 0 ? n * fact(n - 1) : 1;
> }
> return fact(x);
> }(21));

Why not, indeed.

>> I try to figure out whether there are cases
>> where function expressions need be named,

> Which I think must require an example situation where a named function
> expression couldn't be replaced with an inner function declaration (that
> there be a good reason for not doing so), or a very good argument
> against function declarations.

I do have an argument against function declarations : use function
expressions from the very beginning in order to expose students to
the notion of functions as first-class objects, and don't confuse
them with another, more traditional approach at the same time.

Whether it qualifies as "good" is of course debatable, not to mention
"very good". Outside of introductory courses in either javascript or
general programming, it is a non-starter.

--
Johannes

Richard Cornford

unread,
Apr 21, 2010, 12:31:51 PM4/21/10
to
Johannes Baagoe wrote:
> Richard Cornford :
>>>> Johannes Baagoe :
>
>>>>> 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;};
>> ^^^^
>> As that - fact - is undeclared there
>
> Ooops! I wonder how long I shall continue to make that mistake
> again and again.

I am still making it from time to time after 9 years of full time
javascript programming. One of the things that JSLint is good for is
that it spots undeclared global property assignments so they are not
that difficult to find and fix.

> Allowing undeclared variables is bad IMHO, but making
> them *global* by default is even worse.
> It is one of the things I still
> hate in javascript, with semicolon insertion and a few
> others.

I assume you mean automatic semicolon insertion (and thinking it a bad
thing that should be abandoned in favor of having the complier complain
about syntax errors). Letting people get into the habit of omitting
semicolons is a bad thing, particularly in the context of this
discussion where:-

(function(){ ... }()) //<-- omitted semicolon
(function(){ ... }())

- has the second parenthesised function expression call turn into an
argument for a call to the first parenthesised function expression
call's result. A (probable) runtime error while the script loads, as the
syntax is fine (and so no automatic semicolon insertion happens between
the two).

<snip>


>>> I try to figure out whether there are cases
>>> where function expressions need be named,
>
>> Which I think must require an example situation where a named
>> function expression couldn't be replaced with an inner function
>> declaration (that there be a good reason for not doing so), or
>> a very good argument against function declarations.
>
> I do have an argument against function declarations : use function
> expressions from the very beginning in order to expose students to
> the notion of functions as first-class objects, and don't confuse
> them with another, more traditional approach at the same time.

Reasonable, but maybe a fact that could be gotten across in a less
dogmatic way.

> Whether it qualifies as "good" is of course debatable, not to mention
> "very good". Outside of introductory courses in either javascript or
> general programming, it is a non-starter.

In reality, most courses in 'javascript' are actually (bad) courses in
browser scripting for the web. In that context not gaining a familiarity
with function declarations would probably be a bad thing. In the context
of an introductory (functional?) programming course that happened to
employ javascript I can see your point.

Richard.

Scott Sauyet

unread,
Apr 21, 2010, 1:02:50 PM4/21/10
to
Richard Cornford wrote:
> Scott Sauyet wrote:

>>    var fact = function(n) {
>>      return n > 0 ? n * fact(n - 1) : 1;
>>    }
>>    var g = fact;
>>    fact = null; // g now does not work.
>
> I am never convinced that solving the problem of people later writing
> code that screws something up is a problem worth solving. The potential
> for writing code that screws things up always will far exceed any
> ability to defend against it, so if someone wants to do that they will
> manage it one way or another, and if they didn't want to they will (or
> should) observe that they have broken something and so go back an change
> their code so that it works correctly in context.

I agree to some degree. But I do believe that reasonable precautions
should be taken. The difficulty lies in determining what might be
reasonable; one person's constant bugaboo is another's ridiculous edge
case.

In fact, a problem much like this bit a friend of mine badly. He of
course didn't simply set the original function to null. He was
building a dynamic environment for the evaluation of various
mathematical functions. He had a variable that represented the
function currently being built by the user, constantly replacing its
value with "new Function(...)" using the code supplied. When the user
was done building and testing the function, it was added to her
environment to be used in building more complex functions. This was
easy to do by creating a new named reference that pointed to the value
of the test function. Then he would reuse the variable that
originally pointed to the function under construction. That worked
fine until he started to allow them to use recursive functions. It
worked fine everywhere but in IE. I helped him figure out why it was
broken, but I don't know how -- or even if -- he ever fixed it.

I'm not saying that his experience is enough of a reason to find a
general solution to the more general issue. But I do think that
there's often not a simple variant of "Then don't do that," that will
answer such questions.

--
Scott

Garrett Smith

unread,
Apr 21, 2010, 2:21:37 PM4/21/10
to
Richard Cornford wrote:
> Johannes Baagoe wrote:
>> Garrett Smith :
>>> Johannes Baagoe :
>>
>>>> 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;};
> ^^^^
> As that - fact - is undeclared there is a side effect of creating a

Mentioned yesterday.

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

Johannes Baagoe

unread,
Apr 21, 2010, 3:11:53 PM4/21/10
to
Ry Nohryb :

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

Sure, if you don't object to variables (`fact`, in this case) that are
global in the inner function. Stefan Weiss did, so I tried something
else. Personally, I find your proposal fine, except that I don't
understand the `fact` in the first line.

> Note how clearly and unequivocally "()()" reveals two consecutive
> function calls, much more than a muddy "())())".

I'm not sure, I find

(function () {


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

}()(21))

at least as clear.

> And "fact" was a global in yours.

Yes, that makes you the third contributor who (quite rightly) points
that out, and I've just noticed that the first to point it out points
out that he pointed it out. I think I have got it by now :)

--
Johannes

Johannes Baagoe

unread,
Apr 21, 2010, 3:16:39 PM4/21/10
to
[supercede]

Ry Nohryb :

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

Sure, if you don't object to variables (`fact`, in this case) that are


global in the inner function. Stefan Weiss did, so I tried something else.
Personally, I find your proposal fine, except that I don't understand the
`fact` in the first line.

> Note how clearly and unequivocally "()()" reveals two consecutive


> function calls, much more than a muddy "())())".

I'm not sure, I find

(function () {
var fact = function(n) {


return n > 0 ? n * fact(n - 1) : 1;
}

return fact;
}()(21))

at least as clear.

> And "fact" was a global in yours.

Yes, that makes you the third contributor who (quite rightly) points that

Johannes Baagoe

unread,
Apr 21, 2010, 3:20:27 PM4/21/10
to
Johannes Baagoe :

> I don't understand the `fact` in the first line.

Got it. Perhaps not the clearest way to declare a local variable, though.

--
Johannes

Garrett Smith

unread,
Apr 21, 2010, 7:24:34 PM4/21/10
to
Richard Cornford wrote:
> 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?
>
> As I am responsible for that construct's use in browser scripting I

The only way for that to be true would be for nobody else to be capable
of realizing the possibility of such constructs.

I used anonymous-and-immediately-invoked-function and long before I had
ever heard of anyone else doing that.

Johannes Baagoe

unread,
Apr 21, 2010, 8:18:16 PM4/21/10
to
Garrett Smith :
> Richard Cornford :

>> As I am responsible for that construct's use in browser scripting

> I used anonymous-and-immediately-invoked-function and long before I had


> ever heard of anyone else doing that.

It seems extremely likely that several persons have invented that
construct independently, like in many other cases.

The earliest (2002-03-01 12:24:33 +0100) *published* occurrence that
I know (Richard Cornford provided it last time the subject arose) is
"Gosha"'s (my indentation)

document.images[0].onclick=(
function (o){return function(){o.handler()}}
)(this)

http://groups.google.fr/group/comp.lang.javascript/msg/53a87649e279a012

--
Johannes

Johannes Baagoe

unread,
Apr 21, 2010, 8:33:36 PM4/21/10
to
Johannes Baagoe :

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

Actually, if we weren't playing games, there would be two cases.

1. 21! is the only factorial we need.

In that case, we may want to prevent the factorial function from
becoming global, since it only serves once.

This might serve - it is IMHO clearer than all other proposed
solutions, and quite as efficient :

var fact21 = (function() {
function fact(n) {


return n > 0 ? n * fact(n - 1) : 1;
};

return fact(21);
}());

However, nothing beats

var fact21 = 51090942171709440000; // factorial(21), a.k.a. 21!

2. 21! is not the only factorial we need.

In that case, the pedestrian

function fact(n) {


return n > 0 ? n * fact(n - 1) : 1;
}

var fact21 = fact(21);

is likely to be the easiest to understand and maintain.

It assumes however that we can be sure that `fact` is always being
called with a small enough positive integer. Above 21, it won't return
an exact result due to floating point rounding, more than 170 will
return Infinity, and anything but a positive integer won't make sense
unless we take the trouble to implement the Gamma function. Therefore,
an actual, production factorial function may be much more complicated.

--
Johannes

David Mark

unread,
Apr 21, 2010, 9:16:39 PM4/21/10
to
Johannes Baagoe wrote:
> Garrett Smith :
>> Richard Cornford :
>
>>> As I am responsible for that construct's use in browser scripting
>
>> I used anonymous-and-immediately-invoked-function and long before I had
>> ever heard of anyone else doing that.
>
> It seems extremely likely that several persons have invented that
> construct independently, like in many other cases.
>

Very likely. But typically (and certainly in this case) one person can
claim credit for popularizing an approach. Those who did it in a vacuum
notwithstanding.

Richard Cornford

unread,
Apr 21, 2010, 9:17:10 PM4/21/10
to
Garrett Smith wrote:
> Richard Cornford wrote:
>> 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?
>>
>> As I am responsible for that construct's use in browser
>> scripting I
>
> The only way for that to be true

The only way?

> would be for nobody else to be
> capable of realizing the possibility of such constructs.

That is not a relevant consideration as someone (completely
independently) realising the possibility today could not then become
responsible for something that has already happened.

The possibly has existed since the introduction of function expressions
to javascript, late last century. But you would be hard pressed to find
a single example of an immediate call to an anonymous function
expression in javascript published prior to 2003, and the very few that
do exist are not being used the same ways as that construct is commonly
used these days (that is, those that do exist are directly influenced by
pure functional programming ideas, not any attempt to achieve 'private'
scopes).

Then, from about 2004 there is an exponential growth in/spread of the
use of such contracts to the point where by about the end of 2008 you
would be hard pressed to consider yourself a javascript programmer
without understanding, and almost certainly having used, the construct.
The same period also sees a similar growth/spread in the understanding
of closures in the same audience. These are almost certainly not
unrelated.

Thus any action(s) that get the ball rolling towards the current state
happed in a window around 2003 - 2004. Considering that I posted the
first (to the best of my knowledge) example of using an immediate call
to an anonymous function expression intended to achieve some notion of
'private' (private static 'class' members in that case) in may 2003, the
first recognisable examples of the (so called) 'Crockford Module
Pattern' in April 2003 (with numerous variations over the following
couple of years), which were joined by numerous other variations and
applications posted by other contributors to this group as a direct
development of my posted cod, truly anonymous full scripts (complex
scripts with zero (or at most one) global prophetess) towards the end of
2003, and wrote and published the FAQ article on closures in javascript
in may 2004 (when there were precisely zero alternative resources
available for that subject on the web), I think I have a very reasonable
claim to be responsible for the (style and widespread) use of that
construct in browser scripting today.

Certainly to date nobody has suggested any alternative candidate, though
I would be interested to see the evidence of any alternative claim. But
it isn't only a question of "realising the possibly", or even realising
the possibility first. There also has to be the actions of publishing
(with a need to explain it sufficiently for an audience to understand),
others being interested enough to take up the idea and run with it, a
propagation into a wider context, etc.

So there is no question of others not being "capable of realizing the
possibility" (simultaneously, before or after), just an observation that
chains of actual influence appear to lead to a particular place, and
that place is here.

> I used anonymous-and-immediately-invoked-function and long
> before I had ever heard of anyone else doing that.

But you didn't think anyone else would be sufficiently interested to
tell them at the time?

Richard.

Garrett Smith

unread,
Apr 21, 2010, 10:17:11 PM4/21/10
to
Richard Cornford wrote:
> Garrett Smith wrote:
>> Richard Cornford wrote:
>>> Johannes Baagoe wrote:
[...]

>>>
>>> As I am responsible for that construct's use in browser
>>> scripting I
>>
>> The only way for that to be true
>
> The only way?
>

If someone else realize the possibility independently, then you cannot
be responsible for that.

[...]

The closures article was influential.

>
>> I used anonymous-and-immediately-invoked-function and long
>> before I had ever heard of anyone else doing that.
>
> But you didn't think anyone else would be sufficiently interested to
> tell them at the time?
>

My interest in javascript was not high; but yes, I actually published an
article around early 2004 about that. I am not proud of it because there
are some things in it that are bad advice and the use of that was
limited to what I wanted it for, which at that time, was not very
sophisticated:
<http://dhtmlkitchen.com/learn/js/singleton/>

It cannot compare to the Closures article in the notes section.

I did not know even about ECMA-262 at that time. I recall that I new
what I local variable was, how to use a function of a constructor, and
combined the two.

Ry Nohryb

unread,
Apr 22, 2010, 3:35:14 AM4/22/10
to
On Apr 22, 2:33 am, Johannes Baagoe <baa...@baagoe.com> wrote:
>
> Actually, if we weren't playing games, there would be two cases.
>
> 1. 21! is the only factorial we need.
>
> In that case, we may want to prevent the factorial function from
> becoming global, since it only serves once.
>
> This might serve - it is IMHO clearer than all other proposed
> solutions, and quite as efficient :
>
>   var fact21 = (function() {
>     function fact(n) {
>       return n > 0 ? n * fact(n - 1) : 1;
>     };
>     return fact(21);
>   }());
> (...)

Guess what would drive people away from writing it so :

var fact21 = (function fact (n) {


return n > 0 ? n * fact(n - 1) : 1;

})(21);

The "do NOT use named FEs" advice that has spread far and wide.
Just another bit of Microsoft's (evil) legacy for the web.
--
Jorge.

Ry Nohryb

unread,
Apr 22, 2010, 4:31:22 AM4/22/10
to

It's less verbose and as efficient... :-)
--
Jorge.

VK

unread,
Apr 22, 2010, 4:48:52 AM4/22/10
to
On Apr 22, 11:35 am, Ry Nohryb <jo...@jorgechamorro.com> wrote:
> Guess what would drive people away from writing it so :
>
> var fact21 = (function fact (n) {
>   return n > 0 ? n * fact(n - 1) : 1;
>
> })(21);
>
> The "do NOT use named FEs" advice that has spread far and wide.
> Just another bit of Microsoft's (evil) legacy for the web.

On Apr 22, 11:35 am, Ry Nohryb <jo...@jorgechamorro.com> wrote:
> The "do NOT use named FEs" advice that has spread far and wide.
> Just another bit of Microsoft's (evil) legacy for the web.

Microsoft-Netscape "evil legacy", or even more properly JavaScript
original implementations of 1995-1999 "evil legacy". But I would say
that the common sense, not some evil legacy drives people away from
writing it so. Why create a named function to assign it to a named
variable, what is the purpose of that? If one needs a function that is
used more than once in one's code then create it and name it and call
it from any place of the code, for Christ's sake :-)

And if one really needs an anonymous function to be called recursively
then specially for those special cases there is arguments.callee in
ECMA-262:

var fact21 = (function (n) {
return n > 0 ? n * arguments.callee(n - 1) : 1;
})(21);

And about "change it" there is an enlightening article of Eric Lippert
"How many Microsoft employees does it take to change a lightbulb?" at
http://blogs.msdn.com/ericlippert/archive/2003/10/28/53298.aspx

Feel free to replace "Microsoft" with any company name and don't
forget to apply yet another "VK's rule": every half-a-year the cost of
change doubles. For the behavior existing since 1995 it would mean to
check every single corporate customer's solution for not being
affected - and it is just for the starter. And for what? For our holly
right to right nonsensical code like
var foo = (function bar(){/*...*/})();
"because by specs bar has to disappear anyway and I want it see
disappearing"?
I never was and I am not a M$ supporter but hey guys, maybe we should
not act like a bunch of capricious children? ;-)


Johannes Baagoe

unread,
Apr 22, 2010, 5:03:00 AM4/22/10
to
Ry Nohryb :

> Guess what would drive people away from writing it so :
>
> var fact21 = (function fact (n) {
> return n > 0 ? n * fact(n - 1) : 1;
> })(21);

From: The Boss
To: Software developers
Subject: Unnecessary cuteness in production code

It has come to my attention that several software developers have fallen
into the habit of writing terse code that requires lengthy explanations
when straightforward self-explanatory code would serve equally well.

This is to stop immediately. We are in the business of serving the
customers' needs, not the technical staff's egos.

--
The Boss.

Ry Nohryb

unread,
Apr 22, 2010, 5:16:22 AM4/22/10
to
On Apr 22, 10:48 am, VK <schools_r...@yahoo.com> wrote:
> (...)

> I never was and I am not a M$ supporter but hey guys, maybe we should
> not act like a bunch of capricious children? ;-)

Resistance is futile !
And you've been assimilated.

After 11 years of service patch^H^H^Hck after service patch^H^H^Hck
without a bug fix, I wouldn't call that unreasonable suspiciousness.
Neither, as Smith hypocritically has put it, a "misinterpretation" of
the specs. Currently, the only mainstream browser that does not have a
"check for updates" menu item is IE. Think about that, what it means,
and its consequences. Just in a single day as yesterday there's been
108 commits to the webkit trunk, so today I just press the button to
get all of them. Both bug fixes and enhancements. So much for the best
and greatest M$.
--
Jorge.

VK

unread,
Apr 22, 2010, 5:45:09 AM4/22/10
to
On Apr 22, 1:16 pm, Ry Nohryb <jo...@jorgechamorro.com> wrote:
> On Apr 22, 10:48 am, VK <schools_r...@yahoo.com> wrote:
>
> > (...)
> > I never was and I am not a M$ supporter but hey guys, maybe we should
> > not act like a bunch of capricious children? ;-)
>
> Resistance is futile !
> And you've been assimilated.

Are you accusing me to fell in love to Big Brother?! You'd better
accuse me in not paying my taxes, really :-) :-|

Strictly by secret, after 13 years I do hate all of them: IE, NN, Fx,
Opera, Safari, Konqueror (that one specially, don't know why, maybe
because atop of the perpetual lousy coding the name sounds ugly to
me). Chrome is not hated yet because too recent, but sure will be
eventually added. For each of them I can give a long list why exactly
are they hated.

But I do *not* hate IE in particular for kipping the original
FunctionExpression behavior or having a slightly different elision
treatment in array declarations. These two are "fixation points" of
Brendan Eich, not mine - he runs with them for years and puts nearly
on each ECMA committee session, at least used to. For me these are
laughable nuisance points to prove someone "evilness". Just like
jumping on someone attempting to drive DUI for his shoes not being
polished. IMHO.

Marco Mariani

unread,
Apr 22, 2010, 5:56:51 AM4/22/10
to
On 04/22/2010 11:45 AM, VK wrote:

> But I do *not* hate IE in particular for kipping the original
> FunctionExpression behavior or having a slightly different elision
> treatment in array declarations. These two are "fixation points" of
> Brendan Eich, not mine - he runs with them for years and puts nearly
> on each ECMA committee session, at least used to. For me these are
> laughable nuisance points to prove someone "evilness".

Maybe it's because those nuisances can easily be fixed, while fixing the
behaviour (or the very existence) of 'undefined' would basically require
a time machine.

Ry Nohryb

unread,
Apr 22, 2010, 6:02:56 AM4/22/10
to

No no no. The list of bugs and bizarreries is 100x longer for IEs than
for anyone else. And their rate of bug fixes is 1e-9 that of any
other. And the list of current features that they are missing, too.
E.g. the <canvas>.
--
Jorge.

VK

unread,
Apr 22, 2010, 6:42:51 AM4/22/10
to
On Apr 21, 5:56 pm, "Richard Cornford" <Rich...@litotes.demon.co.uk>
wrote:
> Function expressions, as opposed to declarations, need not result in the
> creation of any properties of any objects at all.

B.S. (the one that does not stay from Bachelor of Science)
In order to execute a function, the function has to be created. If
it's a named function, its name has to be placed somewhere. In where?
Well, assuming function-level scope structure in JavaScript, either in
the scope of the outer function or - if run out of any other function
- into Global scope. It was obvious for both NN and IE engines'
implementors. Then Mozilla came back to the market with Firefox and a
new ingenious idea: identification of a FunctionExpression has to be
placed into the scope of the expression so disappear after the
expression is executed:
( function foo() {/*...*/} )()
^__________________________^
foo visibility scope

Fine, really. As an old Persian saying says: "Who can stop Hafiz from
likening a ladybug to the Padishah"...
I am just struggling to find some description or at least mentioning
of the "expression scope" in ECMA-262 and humbly asking for help in
that.

Johannes Baagoe

unread,
Apr 22, 2010, 6:43:03 AM4/22/10
to
Ry Nohryb :

> The "do NOT use named FEs" advice that has spread far and wide.

I rather think I shall continue to spread it, although I have
somewhat softened my position - the "recursion" argument does make
sense. Still, I prefer to affect the inner function to a variable in
the outer function's scope, and I haven't been convinced that there
is a significant disadvantage in doing so.

But my reasons for doing so has nothing to do with that bug I didn't
even know existed. It because I like to think of

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

as a mere shorthand, a.k.a. "syntactical sugar", for

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

(I suspect that this is not true, and I expect to be told in elaborate
detail why it only shows a lamentable ignorance of the specs, for
which I shall be duly grateful.

But my point is that in some future, simple language for beginners,
that is how it *should* be. Actually, I would prefer to see function
declarations disappear altogether, if it were not for legacy that
cannot be easily dismissed.)

> Just another bit of Microsoft's (evil) legacy for the web.

Look - in my entire existence, I have bought *one* Microsoft product
with my own money: the BASIC that came with the, IIRC, "Floating Point
Memory Extension Card" for my Apple II.

So I am hardly a Microsoft fan, and I have just saved my mother-in-law
140 € by insisting that the computer she is going to buy this
afternoon (and that I am likely to have to maintain) run Ubuntu.

But I believe that this crusade is counter-productive. Rather than bashing
Microsoft, or for that matter anybody else, promote better alternatives.

--
Johannes

VK

unread,
Apr 22, 2010, 7:55:16 AM4/22/10
to
On Apr 22, 2:43 pm, Johannes Baagoe <baa...@baagoe.com> wrote:
> But my reasons for doing so has nothing to do with that bug I didn't
> even know existed. It because I like to think of
>
>   function f() {/*...*/}
>
> as a mere shorthand, a.k.a. "syntactical sugar", for
>
>   var f = function() {/*...*/};
>
> (I suspect that this is not true

it is not for IE at least

, and I expect to be told in elaborate
> detail why it only shows a lamentable ignorance of the specs, for
> which I shall be duly grateful.

It was explained in my other post in this thread:
http://groups.google.com/group/comp.lang.javascript/msg/eaa3f218c6babea4

For all details functioning of DISPID, name tables etc. I think that
MSDN is a better source than my rewording of it.

To show the explained difference in action may be difficult if you
don't have Microsoft products available for testing. In this case
you'll need to find a mis-fortunate friend of yours :-) having Windows
and IE installed.
Newer IE version come with Internet Explorer Developer Tools included,
so you don't need to install Script Debugger separately.

Make a simple page with a script on it like:

<script type="text/jscript">
function a() {
debugger;
}

var b = function(){debugger;};

a();

b();
</script>

"debugger" is JScript only command instructing execution breakpoint
with current execution context and call stack preserved.

Load this page to IE, then Tools > Internet Explorer Developer Tools,
start debugging

Compare call stack for a:
JScript global code -> a
with call stack for b:
JScript global code -> JScript anonymous function

In the reality for the latter of course
JScript global code -> (b) -> JScript anonymous function
but the name table jumps are not reflected in the call stack. For such
fine observation one needs to write a C++ wrapper using Microsoft
Windows Script Interfaces with DISPID access and run JScript code over
it.

> But my point is that in some future, simple language for beginners,
> that is how it *should* be. Actually, I would prefer to see function
> declarations disappear altogether, if it were not for legacy that
> cannot be easily dismissed.)

I strongly disagree with you on that point. Well, just two opinions
against of each other. :-)

Ry Nohryb

unread,
Apr 22, 2010, 8:03:21 AM4/22/10
to
On Apr 22, 12:43 pm, Johannes Baagoe <baa...@baagoe.com> wrote:
>
> Look - in my entire existence, I have bought *one* Microsoft product
> with my own money: the BASIC that came with the, IIRC, "Floating Point
> Memory Extension Card" for my Apple II.

So yours was an early II, not a II+... Have you got it still ?
Wrt the card, was it the one with 16k of RAM (the "Language card"), or
the one with ROMs and a red flip switch ?

> CALL -936
--
Jorge.

Ry Nohryb

unread,
Apr 22, 2010, 8:08:51 AM4/22/10
to
On Apr 22, 12:43 pm, Johannes Baagoe <baa...@baagoe.com> wrote:
>
> But I believe that this crusade is counter-productive. Rather than bashing
> Microsoft, or for that matter anybody else, promote better alternatives.

Yeah. Peace and love, brother. Better let's overlook it.
--
Jorge.

VK

unread,
Apr 22, 2010, 8:45:53 AM4/22/10
to
On Apr 22, 2:42 pm, VK <schools_r...@yahoo.com> wrote:
> Then Mozilla came back to the market with Firefox and a
> new ingenious idea: identification of a FunctionExpression has to be
> placed into the scope of the expression so disappear after the
> expression is executed:
> ( function foo() {/*...*/} )()
> ^__________________________^
>    foo visibility scope

Correction: not even that. The specs reading they came back on the
market is not describable at all in any common scope terms because in
say Firefox

var a = ( function f(){return 1}() + 1 );
window.alert(a); // 2

but

var a = ( function f(){return 1}() + f() );
window.alert(a); // Error: f is not defined

So trying to express it in some human way, "within an expression a
FunctionExpression gets an implicit temporary scope and is not visible
to the rest of the expression; this implicit temporary scope gets
destroyed after the containing expression is evaluated". No wonder MS
keeps sending this bright invention to the hell: in order to mimic it
a noticeable engine redesign would be needed for a total nuisance as
the objective.

Richard Cornford

unread,
Apr 22, 2010, 9:11:24 AM4/22/10
to
On Apr 22, 11:42 am, VK wrote:

> On Apr 21, 5:56 pm, Richard Cornford wrote:
>
>> Function expressions, as opposed to declarations, need not
>> result in the creation of any properties of any objects at all.
>
> B.S. (the one that does not stay from Bachelor of Science)
> In order to execute a function, the function has to be created.
> If it's a named function, its name has to be placed somewhere.
> In where?

"If it is a named function, ...". Function expressions do not need to
have names (the Identifier is optional), so even if having a name will
result in some object having a named property that refers to the (or
a, in JScript's case) function, not needing to have a name still means
they "need not result in the creation of any properties of any
objects".

> Well, assuming function-level scope structure in JavaScript,
> either in the scope of the outer function or - if run out of
> any other function - into Global scope. It was obvious for both
> NN and IE engines' implementors.

What was "obvious"?

> Then Mozilla came back to the market with Firefox and a
> new ingenious idea: identification of a FunctionExpression has
> to be placed into the scope of the expression

The spec says that object that is given a named property that
corresponds with any Identifier provided for a FunctionExpression
should be added to the scope chain that is assigned to the [[Scope]]
property of the resulting function object. These is no such thing as
"the scope of the expression".

> so disappear after the expression is executed:

But (an a conforming implementation) any object holding the property
with a name corresponding with the Identifier used in a
FunctionExpression lasts as long as the function object exists (as the
function object retains its [[Scope]] property and so preserves the
scope chain that property refers to for the life of that function
object).

If in any particular case the lifespan of a function object is
contained by the evaluation of an expression then the evaluation of
that expression will also constrain the lifespan of the object added
to the function object's scope chain, but that has nothing to do with
expressions.

> ( function foo() {/*...*/} )()
> ^__________________________^
> foo visibility scope

If you wanted to point as something that bounds the visibility of -
foo - then it would be less misleading to be pointing at the innermost
set of braces, as it is only within the function body that - foo - is
supposed to be 'visible'.

> Fine, really. As an old Persian saying says: "Who can stop Hafiz
> from likening a ladybug to the Padishah"...
> I am just struggling to find some description or at least mentioning
> of the "expression scope" in ECMA-262 and humbly asking for help in
> that.

When you are making things up off the top of your head in order to
explain your own misinterpretations of your own faulty tests then
looking at outside sources is unlikely to be worthwhile.

Richard.

Stefan Weiss

unread,
Apr 22, 2010, 9:16:16 AM4/22/10
to
On 22/04/10 14:45, VK wrote:
> On Apr 22, 2:42 pm, VK <schools_r...@yahoo.com> wrote:
>> ( function foo() {/*...*/} )()
>> ^__________________________^
>> foo visibility scope
>
> Correction: not even that. The specs reading they came back on the
> market is not describable at all in any common scope terms because in
> say Firefox
>
> var a = ( function f(){return 1}() + 1 );
> window.alert(a); // 2
>
> but
>
> var a = ( function f(){return 1}() + f() );
> window.alert(a); // Error: f is not defined
>
> So trying to express it in some human way, "within an expression a
> FunctionExpression gets an implicit temporary scope and is not visible
> to the rest of the expression; this implicit temporary scope gets
> destroyed after the containing expression is evaluated".

Could it be that you're just confused about the parentheses? They have
nothing at all to do with scope and visibility. The only reason they are
sometimes required is to make a function *expression* out of what would
otherwise be a *declaration*. In both your examples, the parentheses are
redundant, because the "f" function is already in expression form.

The "f" identifier is only visible inside the function *body*, which is
consistent with JS's function-as-scope paradigm. Microsoft breaks that
rule by making "f" available outside the function body - and not only
that: IE doesn't even need the expression to be evaluated at all. It
simply confuses NFE with function declarations:

function ouch () {
alert(typeof foo); // "function" - this is correct
alert(typeof bar); // IE: "function"; others: "undefined"
return; // evaluation stops here!
function foo() {}
var unused = function bar() {};
}

(Note that there are no parentheses around the function expression)
Now, are you still calling that a feature in MSIE?


--
stefan

VK

unread,
Apr 22, 2010, 9:25:32 AM4/22/10
to
On Apr 22, 5:11 pm, Richard Cornford <Rich...@litotes.demon.co.uk>
wrote:

> If you wanted to point as something that bounds the visibility of -
> foo - then it would be less misleading to be pointing at the innermost
> set of braces, as it is only within the function body that - foo - is
> supposed to be 'visible'.

You misread my question. I do know that inside function f() {} f will
be visible. I am asking where f has to be placed to be visible to the
engine, in what scope? Because obviously the engine cannot handle
something it doesn't see, so f has to be placed somewhere besides the
function scope itself. To where, to what scope and where is it
described in ECMA-262?

VK

unread,
Apr 22, 2010, 9:53:49 AM4/22/10
to
On Apr 22, 5:16 pm, Stefan Weiss <krewech...@gmail.com> wrote:
> The "f" identifier is only visible inside the function *body*, which is
> consistent with JS's function-as-scope paradigm.

See my last question to Mr.Cornford. Outer functions are visible to
Global so can be handled; nested functions are visible to the outer
function so can be handled. Named FunctionExpressions are visible
to...? Again, from top to bottom point of view.

> Microsoft breaks that
> rule by making "f" available outside the function body - and not only
> that: IE doesn't even need the expression to be evaluated at all. It
> simply confuses NFE with function declarations:
>
>   function ouch () {
>     alert(typeof foo);  // "function" - this is correct
>     alert(typeof bar);  // IE: "function"; others: "undefined"
>     return;             // evaluation stops here!
>     function foo() {}
>     var unused = function bar() {};
>   }
>
> (Note that there are no parentheses around the function expression)
> Now, are you still calling that a feature in MSIE?

Yes, it seems to me more logical - but I will not push this opinion to
anyone else.

P.S. OT. There are a lot of "features" of the kind we have to live
with. Real bugs get fixed, believe you me. How do you like that
"feature" of Fx for instance (now we can successfully address
properties of undefined, cool):

<html>
<head>
<title></title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type="text/javascript">
window.onload = function() {
window.alert(typeof document.all); // undefined
window.alert(document.all.test) // [object HTMLParagraphElement]
}
</script>
</head>
<body>
<p id="test">test</p>
</body>
</html>

Richard Cornford

unread,
Apr 22, 2010, 10:28:12 AM4/22/10
to
On Apr 22, 2:25 pm, VK wrote:

> On Apr 22, 5:11 pm, Richard Cornford wrote:
>
>> If you wanted to point as something that bounds the visibility
>> of - foo - then it would be less misleading to be pointing at
>> the innermost set of braces, as it is only within the function
>> body that - foo - is supposed to be 'visible'.
>
> You misread my question.

No, I read your question as meaningless.

> I do know that inside function f() {} f will
> be visible. I am asking where f has to be placed to be visible
> to the engine, in what scope?

What is "visible to the engine" supposed to mean? The internal
implementation details are of no significance at all, not least
because there are fairly unlikely to be the same in any two
implementations.

> Because obviously the engine cannot handle
> something it doesn't see,

What does 'see' mean in this context. Somewhere in memory there is
going to be a structure that represents the function object. How any
given implementation chooses where that should be, and how it tracks
it, is completely irrelevant to any discussion of javascript as a
programming language.

> so f has to be placed somewhere besides the
> function scope itself.

The "function scope" is part of javascript, what any given
implementation does internally while it is facilitating javascript is
outside of javascript.

> To where, to what scope

In the javascript sense of 'scope'; to no scope. As I said; "Function
expressions, ... , need not result in the creation of any properties
of any objects at all" (which should be taken as meaning javascript
objects, because if the implementation uses objects of any kind
internally, and assigns values to properties of those objects in the
event that it does, that is only an insignificant coincidence).

> and where is it
> described in ECMA-262?

Section 13, where the evaluation of a function expression results in a
function object. That is the necessary behaviour, and how it is
facilitated is not the concern of the specification.

Richard.

Stefan Weiss

unread,
Apr 22, 2010, 10:39:54 AM4/22/10
to
On 22/04/10 15:53, VK wrote:
> On Apr 22, 5:16 pm, Stefan Weiss <krewech...@gmail.com> wrote:
>> The "f" identifier is only visible inside the function *body*, which is
>> consistent with JS's function-as-scope paradigm.
>
> See my last question to Mr.Cornford.

I don't understand the point of that question, so I can't answer it.
Good thing you asked someone else ;-)

> Outer functions are visible to
> Global so can be handled; nested functions are visible to the outer
> function so can be handled. Named FunctionExpressions are visible
> to...? Again, from top to bottom point of view.

Asking where an expression is visible doesn't make sense. The optional
identifier of a FunctionExpression is visible in its function body (I
think I already explained that). Technically speaking, since you asked
how the engine can see it, the identifier becomes a property of the
execution context's variable object. This is all specified clearly
enough, and Garrett has even quoted the relevant passage of the specs in
this very thread.

> P.S. OT. There are a lot of "features" of the kind we have to live
> with. Real bugs get fixed, believe you me.

That made me smile :)

"Real bug" or "feature" is in the eye of the beholder. Software vendors
can officially define which is which, and when that definition clashes
with their users' expectations often enough, people tend to get angry.
This specific vendor is not amenable to criticism from developers. What
you perceive as Microsoft hate is just the logical consequence.

> How do you like that
> "feature" of Fx for instance (now we can successfully address
> properties of undefined, cool):
>
> <html>
> <head>
> <title></title>
> <meta http-equiv="Content-Type"
> content="text/html; charset=iso-8859-1">
> <script type="text/javascript">
> window.onload = function() {
> window.alert(typeof document.all); // undefined
> window.alert(document.all.test) // [object HTMLParagraphElement]

That's your own fault for not using a proper doctype. Careless coding is
the one and only reason why compatibility hacks like this had to be
introduced in otherwise (relatively) standards compliant browsers.

Do us a favor and
1) use a doctype in your HTML documents
2) do _not_ use document.all


--
stefan

Richard Cornford

unread,
Apr 22, 2010, 10:46:59 AM4/22/10
to
On Apr 22, 2:53 pm, VK wrote:
<snip>

> P.S. OT. There are a lot of "features" of the kind we have
> to live with. Real bugs get fixed, believe you me.

As the author of a 'rounding' function that, when asked to round 0.99
to one decimal place, returned the string "0.10" (numerically wrong by
an order of magnitude and the wrong number of decimal places) I
suppose that you do not consider the dubious behaviour of JScript's -
toFixed - method as a bug. It certainly took a very long time to get
fixed (12 years+).

<URL: http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/b495b4898808fde0/63c2ad2bdbdf0b40
>

> How do you like that "feature" of Fx for instance (now we
> can successfully address properties of undefined, cool):
>
> <html>
> <head>
> <title></title>
> <meta http-equiv="Content-Type"
> content="text/html; charset=iso-8859-1">
> <script type="text/javascript">
> window.onload = function() {
> window.alert(typeof document.all); // undefined

With host objects, a - typeof - operation may result in any string
value (the value is "Implementation dependent" (ECMA 262, 3rd Ed.
Section 11.4.3)). If a typeof operation results in the string
"undefined", as here, you cannot assume that the operand's value was
the undefined primitive type as it still may be (as in this case) a
host object.

> window.alert(document.all.test) // [object HTMLParagraphElement]}

This does not demonstrate an ability to "successfully address
properties of undefined".

Richard.

Garrett Smith

unread,
Apr 22, 2010, 1:00:46 PM4/22/10
to
VK wrote:
> On Apr 22, 2:43 pm, Johannes Baagoe <baa...@baagoe.com> wrote:
>> But my reasons for doing so has nothing to do with that bug I didn't
>> even know existed. It because I like to think of
>>
>> function f() {/*...*/}
>>
>> as a mere shorthand, a.k.a. "syntactical sugar", for
>>
>> var f = function() {/*...*/};
>>
>> (I suspect that this is not true
>
> it is not for IE at least
>
> , and I expect to be told in elaborate
>> detail why it only shows a lamentable ignorance of the specs, for
>> which I shall be duly grateful.
>
> It was explained in my other post in this thread:
> http://groups.google.com/group/comp.lang.javascript/msg/eaa3f218c6babea4
>

The explanation you posted there is incorrect.

A FunctionDeclaration is created upon "Entering an Execution Context". A
FunctionExpression is evaluated in order of Statements being evaluated.

You can read "Entering an Execution Context" from ECMA-262 and also this:
<http://dmitrysoshnikov.com/ecmascript/chapter-2-variable-object/#entering-the-execution-context>

A short exposition of the difference shows that in testDec, the
FunctionDeclaration is available to Statements before it appears in
source order.

A FunctionDeclaration is created upon Entering an Execution Context
/* Returns a function */
function testDec() {
return f;
function f() {/*...*/}
}

In contrast, FunctionExpression is evaluated in order of Statements
being evaluated, so the value is not available prior to being evaluated
in source order.

/* Returns undefined.
function testExp() {
return f;
var f = function() {};
}

In some cases you want FunctionDeclaration, in other cases,
FuncitonExpression is more appropriate.

var b;
if(window.special) {
b = function() {
alert('special');
};
} else {
b = function() {
alert('not special');
};
}

There are various patterns that use closures.
[...]

VK

unread,
Apr 22, 2010, 2:00:36 PM4/22/10
to
> > It was explained in my other post in this thread:
> >http://groups.google.com/group/comp.lang.javascript/msg/eaa3f218c6babea4
>
> The explanation you posted there is incorrect.

Sorry to disagree, but it is. I was talking about a named
FunctionExpression in IE, not about FunctionExpression overall as per
ECMA-262

> A FunctionDeclaration is created upon "Entering an Execution Context". A
> FunctionExpression is evaluated in order of Statements being evaluated.

Again, I have a very little interest in what is written in ECMA-262 of
any edition yet I am greatly interested in my script behavior for
60%-90% of my visitors per regions. In IE:

function demo() {
return [bar, foo];
var foo = function bar(){};
}

var v = demo();

window.alert(v[0]); // "function bar(){}"
window.alert(v[1]); // "undefined"

thus:

function demo() {
return [bar, foo];
var foo = function bar(){};
}

equals to

function demo() {
return [bar, foo];
var foo = bar;
function bar(){};
}

as it was explained earlier.

John G Harris

unread,
Apr 22, 2010, 3:32:22 PM4/22/10
to
On Thu, 22 Apr 2010 at 15:16:16, in comp.lang.javascript, Stefan Weiss
wrote:

>On 22/04/10 14:45, VK wrote:

<snip>


>Could it be that you're just confused

<snip>

He so often is that it's always a pretty good guess.

John
--
John Harris

Garrett Smith

unread,
Apr 22, 2010, 5:14:19 PM4/22/10
to
VK wrote:
>>> It was explained in my other post in this thread:
>>> http://groups.google.com/group/comp.lang.javascript/msg/eaa3f218c6babea4
>> The explanation you posted there is incorrect.
>
> Sorry to disagree, but it is. I was talking about a named
> FunctionExpression in IE, not about FunctionExpression overall as per
> ECMA-262
>

OK. I saw:

| (function foo() { /*...*/ })()
|
| is equivalent (with some subtle details) to:
|
| function foo() { /*...*/ };
| foo();


but I now realize that just before that was the line:
| In IE:

That is arguably correct. The part that is arguable is if the details
are subtle or not.

In JScript, the production:
| (function foo() { /*...*/ })()

Results in the creation of both a FunctionExpression *and* a
FunctionDeclaration. This behavior is a deviation that is documented in
MS-ES3 pdf (linked from the FAQ).

Other interesting related deviations documented therein include
"Entering an Execution Context" and the `JScriptFunction` production.

>> A FunctionDeclaration is created upon "Entering an Execution Context". A
>> FunctionExpression is evaluated in order of Statements being evaluated.
>
> Again, I have a very little interest in what is written in ECMA-262 of

Yes I know.

The specification is of interest for those who want to understand the
language.

> any edition yet I am greatly interested in my script behavior for
> 60%-90% of my visitors per regions. In IE:
>

I prefer to adhere the pertinent standard features, expect nothing more
than is stated.

Understanding how a program can be expected to behave is valuable.

When the program works, but as a result of using nonstandard quirks, it
has potential to break later on.

When taking on a piece of legacy code or when reviewing a peer's code,
finding where the code relies on nonstandard quirks helps find
weaknesses in the code.

Of course, a program's weaknesses can include more than reliance on
nonstandard features; that is only one potential weakness.

Specifications do not instruct one how to design a program (and things
like WebIDL seem to go to great lengths to encourage some atrociously
bad design).

Regarding the statistical criteria: 90% means that one out of ten won't
get the right script behavior. 60% is just over half. Ouch!

> function demo() {
> return [bar, foo];
> var foo = function bar(){};
> }
>
> var v = demo();
>
> window.alert(v[0]); // "function bar(){}"
> window.alert(v[1]); // "undefined"
>
> thus:
>
> function demo() {
> return [bar, foo];
> var foo = function bar(){};
> }
>

Expected output:
ReferenceError - bar is undefined.

> equals to
>
> function demo() {
> return [bar, foo];
> var foo = bar;
> function bar(){};
> }
>

Expected output:
Array containing 'bar' reference and value undefined.
[bar, undefined]

The two are not equivalent.


> as it was explained earlier.

Calling the first `demo` function:
Upon entering the execution context, Variable Instantiation is
performed, adding `foo` the VO as a property with value `undefined`.

Variable Instantiation completed, Statements are evaluated. The first
statement, a ReturnStatement, is evaluated. The ReturnStatement contains
an ArrayLiteral expression. Evaluating the ArrayLiteral, the identifiers
`foo` and `bar` must be resolved. The identifier `foo` is resolved on
the VO, however `bar` cannot be resolved to an identifier and so a
ReferenceError is produced. The function throws the ReferenceError,
completing abruptly.

Calling the second `demo` function:
Upon entering the execution context, *FunctionDeclaration* `bar` is
added to the VO and given a value of that Function object created by the
source which follows the identifier. Next, variable `foo` is added to
the VO and given the value `undefined`.

Variable Instantiation completed, Statements are evaluated. As in the
previous example, the first statement, a ReturnStatement, is evaluated.
Here again, an ArrayLiteral expression results in the creation of an
array where identifiers `foo` and `bar` must be resolved. Both values
are resolved and added to the Array. The ReturnStatement complete, the
function completes, returning the reference to the Array to the caller.

Dr J R Stockton

unread,
Apr 23, 2010, 3:02:10 PM4/23/10
to
In comp.lang.javascript message <Nq6dnSe5CMD9BFLWnZ2dnUVZ7r9i4p2d@gigane
ws.com>, Wed, 21 Apr 2010 19:33:36, Johannes Baagoe <baa...@baagoe.com>
posted:

>It assumes however that we can be sure that `fact` is always being
>called with a small enough positive integer. Above 21, it won't return
>an exact result due to floating point rounding, more than 170 will
>return Infinity, and anything but a positive integer won't make sense
>unless we take the trouble to implement the Gamma function. Therefore,
>an actual, production factorial function may be much more complicated.

I think 22! (1124000727777607680000) is represented exactly, but not
23!.
22! seems to be IEEE Double 444e77526159f06c. However, 22! does not
convert exactly to String.
Tested in <URL:http://www.merlyn.demon.co.uk/js-misc0.htm#DW4>.

function Fac(N) {
var U, FAC = [1, 1, 2, 6, 24, ... 1124000727777607680000]
if (N<0 || N%1) return U
U = FAC[N]
return U ? U : 1/0 } // NOT TESTED. NOT OPTIMISED for making [].

To the extent that floating-point maths is trustworthy, from
my js-maths.htm,

function BigFac(J) { var L = 0, k
for ( k=1 ; k<=J ; k++ ) L += Math.log(k)
L *= Math.LOG10E
return Math.exp((L%1)/Math.LOG10E) + 'e' + Math.floor(L) }

--
(c) John Stockton, nr London UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;
<URL:http://www.merlyn.demon.co.uk/clpb-faq.txt> RAH Prins : c.l.p.b mFAQ;
<URL:ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip> Timo Salmi's Turbo Pascal FAQ.

VK

unread,
Apr 24, 2010, 2:26:40 AM4/24/10
to
On Apr 23, 11:02 pm, Dr J R Stockton <reply1...@merlyn.demon.co.uk>
wrote:

> I think 22! (1124000727777607680000) is represented exactly, but not
> 23!.
> 22! seems to be IEEE Double 444e77526159f06c.  However, 22! does not
> convert exactly to String.

The IEEE-754 FP-DP limits were once analyzed here in depth at "How are
JS numbers represented internally??"
http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/38d21acb4d4509ce

In the particular see the excellent summary by Lasse Reichstein
Nielsen:
http://groups.google.com/group/comp.lang.javascript/msg/3833df1762d81fee

<quote>
The limit on integers that can be used with bitwise operations:
2^32-1 = 4294967295

The limit on integers that can all be represented exactly:
2^53 = 9007199254740992

The limit on representable numbers that does not display in scientific
notation (largest representable number below 10^21):
10^21-2^17 = 999999999999999868928

Limit on number literals that are converted to this number:
10^21-2^16-1 = 999999999999999934463
(above this, the number is closer to 10^21, which can itself be
represented exactly)
</quote>

VK

unread,
Apr 24, 2010, 2:44:46 AM4/24/10
to
On Apr 24, 10:26 am, VK <schools_r...@yahoo.com> wrote:
> The IEEE-754 FP-DP limits were once analyzed here in depth at "How are
> JS numbers represented internally??"
>  http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/38d21acb4d4509ce

Also in that thread I linked BigInt.js library by Leemon Baird
http://www.leemon.com/crypto/BigInt.html

It is still presented and fully functional, but by taking into account
JavaScript productivity and execution time limits he says that "It's
hard to imagine any practical cryptographic use for this code, other
than pedagogical." and I do agree with him.


--
"ECMAScript was always an unwanted trade name that sounds like a skin
disease."
Brendan Eich

Johannes Baagoe

unread,
Apr 24, 2010, 7:24:48 AM4/24/10
to
Dr J R Stockton :

> I think 22! (1124000727777607680000) is represented exactly,

You're right. It is of course greater than 2^53 (9007199254740992),
but it has 19 factors 2 which are represented in the exponent(22! =
2^19 * 2143861251406875), so it should be.

> but not 23!.

That would indeed be impossible: 23! = 2^19 * 49308808782358125,
and that odd factor is greater than 2^53.

> 22! seems to be IEEE Double 444e77526159f06c.

It is.

> However, 22! does not convert exactly to String.

Yes, that was what mislead me. Now, why is that?

--
Johannes

VK

unread,
Apr 24, 2010, 7:57:00 AM4/24/10
to
On Apr 24, 3:24 pm, Johannes Baagoe <baa...@baagoe.com> wrote:
> > However, 22! does not convert exactly to String.
>
> Yes, that was what mislead me. Now, why is that?

Because 1124000727777607680000 is greater than 999999999999999868928

Please read my recent post

Dr J R Stockton

unread,
Apr 25, 2010, 1:53:37 PM4/25/10
to
In comp.lang.javascript message <456e1ea1-bc81-48d0-854b-f5cdb703d7d3@b3
3g2000yqc.googlegroups.com>, Fri, 23 Apr 2010 23:26:40, VK
<school...@yahoo.com> posted:

>
>The limit on integers that can all be represented exactly:
> 2^53 = 9007199254740992

Which part of the word "all" do you not understand? Before answering,
you should have considered the evidence of the cited page section
<URL:http://www.merlyn.demon.co.uk/js-misc0.htm#DW4> when fed with the
number 22!.

--
(c) John Stockton, nr London UK. ???@merlyn.demon.co.uk Turnpike v6.05 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
Check boilerplate spelling -- error is a public sign of incompetence.
Never fully trust an article from a poster who gives no full real name.

Dr J R Stockton

unread,
Apr 25, 2010, 2:24:10 PM4/25/10
to
In comp.lang.javascript message <aN2dnQp4ysKdSE_WnZ2dnUVZ7rFi4p2d@gigane
ws.com>, Sat, 24 Apr 2010 06:24:48, Johannes Baagoe <baa...@baagoe.com>
posted:

>
>> However, 22! does not convert exactly to String.
>
>Yes, that was what mislead me. Now, why is that?

I suppose that the implementation does not convert to an accurate string
of whatever length is needed (my page does do that) and then truncate,
but uses IEEE Double arithmetic to compute the digits, getting rounding
errors in extreme cases. Perhaps instead they could use the 80-bit IEEE
Extended internally. But I do not actually know.

ASIDE : I hear Opera 10.52 fixes the Summer Time Bug.

--
(c) John Stockton, nr London, UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links;
Astro stuff via astron-1.htm, gravity0.htm ; quotings.htm, pascal.htm, etc.
No Encoding. Quotes before replies. Snip well. Write clearly. Don't Mail News.

VK

unread,
Apr 25, 2010, 5:50:32 PM4/25/10
to
On Apr 25, 9:53 pm, Dr J R Stockton <reply1...@merlyn.demon.co.uk>
wrote:

> Which part of the word "all" do you not understand?

I understand everything. For one who don't - and based on your other
answer you are one of them - I provided the link for a profound
discussion on the topic. And I expect you not blaming on my bad
English as the key part are written not by me and by using very good
English. For nightly thoughts and in hope that you will finally follow
the link and read it (watch c and d behavior):

<script type="text/javascript">

var a = 9007199254740991;
var b = 9007199254740991 + 1;

document.write('<p>'+a+'</p>');
document.write('<p>'+b+'</p>');
document.write('<p>a == b '+(a==b)+'</p>');

document.write('<hr>');

var c = 9007199254740992;
var d = 9007199254740992 + 1;

document.write('<p>'+c+'</p>');
document.write('<p>'+d+'</p>');
document.write('<p>c == d '+(c==d)+'</p>');
</script>

Dr J R Stockton

unread,
Apr 26, 2010, 2:06:19 PM4/26/10
to
In comp.lang.javascript message <ccbf5f0e-0165-45c5-9489-5766b5f8d058@y1
4g2000yqm.googlegroups.com>, Sun, 25 Apr 2010 14:50:32, VK
<school...@yahoo.com> posted:


You there demonstrate that ECMAScript cannot store 2^53+1 exactly; and
therefore cannot store all integers above 2^53 exactly.

However, we can I thing agree that all integers from 0 to 2^53 can be
stored exactly (an IEEE Double's mantissa represents enough bits); and
from that it follows that the product of any of those integers and any
reasonable power of two can be stored exactly, with the SAME mantissa
and a different exponent.

The aforesaid factorial is such a number, as shown by JB.


For example, 2^1000 will be stored exactly. But its default conversion
to String gives a string (1.0715086071862673e+301) which is equivalent
to an odd number multiplied by a power of 10, which cannot be a power of
two.

Math.pow(2, 1000) is stored as eight bytes 7e70000000000000 and that
represents
+10715086071862673209484250490600018105614048117055336074437503883703510
511249361224931983788156958581275946729175531468251871452856923140435984
577574698574803934567774824230985421074605062371141877954182153046474983
581941267398767559165543946077062914571196477686542167660429831652624386
837205668069376.0 - you can easily divide that by 2 a thousand times as
a check. That demo was done in my js-misc0.htm#DW4.


It can also be checked against LONGCALC (on my web site, see sig line 3)

prompt>longcalc cof 2 1000 pow wrt

LONGCALC: www.merlyn.demon.co.uk >= 2005-07-22
compiled with Borland Delphi.
+10715086071862673209484250490600018105614048117055336074437503883703510
511249361224931983788156958581275946729175531468251871452856923140435984
577574698574803934567774824230985421074605062371141877954182153046474983
581941267398767559165543946077062914571196477686542167660429831652624386
837205668069376

Who said JavaScript was limited to about 15 significant digits ?!?

Now look up "all" in the dictionary.

--
(c) John Stockton, nr London UK. ?@merlyn.demon.co.uk DOS 3.3, 6.20; WinXP.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links.
PAS EXE TXT ZIP via <URL:http://www.merlyn.demon.co.uk/programs/00index.htm>
My DOS <URL:http://www.merlyn.demon.co.uk/batfiles.htm> - also batprogs.htm.

Dr J R Stockton

unread,
Apr 29, 2010, 12:08:26 PM4/29/10
to
In comp.lang.javascript message <eo13ncSK...@invalid.uk.co.demon.me
rlyn.invalid>, Sun, 25 Apr 2010 19:24:10, Dr J R Stockton
<repl...@merlyn.demon.co.uk> posted:

> ASIDE : I hear Opera 10.52 fixes the Summer Time Bug.

It does.

But it does not fix

"THIS :\t" + new Date(2010, 0, 1) + "\n\"\t\t" + new Date(2010, 6, 1)

which still gives

THIS : 1262304000000
" 1277938800000

See sig.

--
(c) John Stockton, nr London, UK. ?@merlyn.demon.co.uk Turnpike v6.05 IE 7.


Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.

MiniTrue is good for viewing/searching/altering files, at a DOS / CMD prompt;
free, DOS/Win/UNIX, new via <URL:http://www.merlyn.demon.co.uk/pc-links.htm>.

It is loading more messages.
0 new messages