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

How to understand this form (something) (param);

1 view
Skip to first unread message

john_woo

unread,
Jul 29, 2009, 8:02:47 PM7/29/09
to
Hi,

I've read/used JavaScript for more that 2 years, but still don't
understand the following:

(function($) {
//when the DOM is ready...
window.addEvent('..,function() {

/* ALL JAVASCRIPT WILL BE IN HERE */

});
})(document.id);

Can any one tell:
1. any document explain this () () format;
2. what do the first and second () mean;
3. what does $ represent;
4. Does the inner statement like "window.addEvent..." work globally;
5. How to call its inner function from outside;
6. What's the advantage declare like this ()(), can this prevent
memory leak?

--
Thanks lots
John

Gabriel Gilini

unread,
Jul 29, 2009, 8:38:48 PM7/29/09
to
john_woo wrote:
> Hi,
>
> I've read/used JavaScript for more that 2 years, but still don't
> understand the following:
>
> (function($) {
> //when the DOM is ready...
> window.addEvent('..,function() {
This line throws a SyntaxError.
http://jibbering.com/faq/#posting read "Posting Code."

>
> /* ALL JAVASCRIPT WILL BE IN HERE */
>
> });
> })(document.id);
>
> Can any one tell:
> 1. any document explain this () () format;
This is a FunctionExpression. You can see its formal definition in the
language specification[1], and kangax has a nice article on named
function expressions which explains the differences from
FunctionDeclaration and FunctionExpression[2].

> 2. what do the first and second () mean;
The first pair of parenthesis acts as grouping operators, and is
optional. The second one contains the arguments that will be passed to
the expression.

> 3. what does $ represent;
`document.id', whatever that property contains.

> 4. Does the inner statement like "window.addEvent..." work globally;
It is executed in the same context which the program was before. So if
that expression is placed on the Global context, it will be executed in
the Global context[3].

> 5. How to call its inner function from outside;
You can't.

> 6. What's the advantage declare like this ()(), can this prevent
> memory leak?
No, it usually causes memory leaks by creating circular references[4].

[1]
http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf
[2] http://yura.thinkweb2.com/named-function-expressions/
[3] http://jibbering.com/faq/faq_notes/closures.html#clExCon
[4] http://jibbering.com/faq/faq_notes/closures.html

HTH

Jonathan Fine

unread,
Jul 30, 2009, 3:02:33 AM7/30/09
to

Functions can be used to store code for reuse. That's not what what's
happening in your example. Instead, the function is being used to
create a closure. The FAQ, in my view, could be better on closures, but
do take a look yourself.
http://jibbering.com/faq/

Let's now unpack (and change slightly) your example.

var tmp = function(){
var tgt = document.getElementById('ssss');

// Lot's of code involving tgt.
};

tmp();
tmp = undefined;

We've now got a variable 'tgt' that saves us some typing when writing
our code. We can do other things with 'tgt', and this is the powerful
side of closures. But I don't think it's present in your example.

The code I wrote can be condensed as:
var tmp; // Retained as worthless side-effect of above.
(function(){ ....})();

In this case there's no real difference between
(function(){ var tgt = document.getElementById('sss'); ....})();
(function(tgt){ ....})(document.getElementById('sss'));

I think the first form is clearer, although most people use the second.

BTW, all the parentheses are required.
js> function(){}()
typein:2: SyntaxError: syntax error:
typein:2: function(){}()
typein:2: .............^


--
Jonathan

Jonathan Fine

unread,
Jul 30, 2009, 3:05:48 AM7/30/09
to
Gabriel Gilini wrote:
> john_woo wrote:
>> Hi,
>>
>> I've read/used JavaScript for more that 2 years, but still don't
>> understand the following:
>>
>> (function($) {
>> //when the DOM is ready...
>> window.addEvent('..,function() {
> This line throws a SyntaxError.
> http://jibbering.com/faq/#posting read "Posting Code."
>>
>> /* ALL JAVASCRIPT WILL BE IN HERE */
>>
>> });
>> })(document.id);

[snip]

>> 2. what do the first and second () mean;
> The first pair of parenthesis acts as grouping operators, and is
> optional. The second one contains the arguments that will be passed to
> the expression.

All the parentheses are required for the example above:


js> function(){}()
typein:2: SyntaxError: syntax error:
typein:2: function(){}()
typein:2: .............^

But note that this does work:
js> x = function(){}()
js>


[snip]

--
Jonathan

Jonathan Fine

unread,
Jul 30, 2009, 3:11:49 AM7/30/09
to
Jonathan Fine wrote:
The FAQ, in my view, could be better on closures, but
> do take a look yourself.
> http://jibbering.com/faq/

The problem is not as bad as I thought. 'closure' appears once in the
FAQ, and it is a link to

http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/df602506ee48b400/e65e00f5cad07676#e65e00f5cad07676

In fact there is a page
http://jibbering.com/faq/faq_notes/closures.html
which would be much better as the target of the link.

That said, I do think the exposition there could be made more accessible
to newcomers without compromising accuracy.

I've not checked to see if there are other 'link errors' in the FAQ.

--
Jonathan

John_Woo

unread,
Jul 30, 2009, 10:05:02 AM7/30/09
to
On Jul 30, 3:05 am, Jonathan Fine <jf...@pytex.org> wrote:
> Gabriel Gilini wrote:
> > john_woo wrote:
> >> Hi,
>
> >> I've read/used JavaScript for more that 2 years, but still don't
> >> understand the following:
>
> >>  (function($) {
> >>      //when the DOM is ready...
> >>      window.addEvent('..,function() {
> > This line throws a SyntaxError.
> >http://jibbering.com/faq/#postingread "Posting Code."

>
> >>         /* ALL JAVASCRIPT WILL BE IN HERE */
>
> >>      });
> >>  })(document.id);
>
> [snip]
>
> >> 2. what do the first and second () mean;
> > The first pair of parenthesis acts as grouping operators, and is
> > optional. The second one contains the arguments that will be passed to
> > the expression.
>
> All the parentheses are required for the example above:
>      js> function(){}()
>      typein:2: SyntaxError: syntax error:
>      typein:2: function(){}()
>      typein:2: .............^
>
> But note that this does work:
>      js> x = function(){}()
>      js>
>
> [snip]
>
> --
> Jonathan


Thanks lots Gabriel Gilini and Jonathan.

Further question is:

Do the following both get executed right away (the window property
changed)?
A. function(){ window.addEvent(...) } ()
B. var x = function(){ window.addEvent(...) } () ;

if yes, line A just a declaration, should not be executed; if no,
let's see the following example, in which jQuery.js is loaded along
with all codes:

(function($) {
jQuery.util = {
...
};

})(jQuery);

then the jQuery.util is called/used outside this function. This case
seems to change the jQuery property, and happed in a function
declaration stage.

I'm a bit stuck on this, Can any one clarify and make it clear?

--
John

kangax

unread,
Jul 30, 2009, 10:18:38 AM7/30/09
to
Jonathan Fine wrote:
> Gabriel Gilini wrote:
[...]

>>> 2. what do the first and second () mean;
>> The first pair of parenthesis acts as grouping operators, and is
>> optional. The second one contains the arguments that will be passed to
>> the expression.
>
> All the parentheses are required for the example above:
> js> function(){}()
> typein:2: SyntaxError: syntax error:
> typein:2: function(){}()
> typein:2: .............^
>
> But note that this does work:
> js> x = function(){}()
> js>

Of course. You change function declaration to function expression by
putting function instantiation on the right hand side of assignment.
Therefore you no longer need surrounding parenthesis (grouping operator)
to allow this function to be interpreted as function expression (which
is the case with OP's example, when a function occurs as a SourceElement
- either in Program or in FunctionBody).

--
kangax

Gabriel Gilini

unread,
Jul 30, 2009, 10:56:21 AM7/30/09
to
On 30 jul, 11:05, John_Woo <john_...@canada.com> wrote:
[snip]

> Do the following both get executed right away (the window property
> changed)?
> A. function(){ window.addEvent(...) } ()
No. SyntaxError. Read kangax's reply.

> B. var x = function(){ window.addEvent(...) } () ;
It does get executed, and `x' will have `undefined' stored in after it
exits.

> if yes, line A just a declaration, should not be executed;
And it isn't. I was mistaken.

> let's see the following example, in which jQuery.js is loaded along
> with all codes:
>
> (function($) {
> jQuery.util = {
> ...
>
> };
> })(jQuery);
>
> then the jQuery.util is called/used outside this function. This case
> seems to change the jQuery property, and happed in a function
> declaration stage.
I can't understand your point here.

> I'm a bit stuck on this, Can any one clarify and make it clear?
Where's the question?

Jorge

unread,
Jul 30, 2009, 11:25:12 AM7/30/09
to


identifierName (parameters)
^^PART1^^^^^^^ ^^^PART2^^^^

functionName(parameters) (parameters)
^^^^^^^^PART1^^^^^^^^^^^ ^^^PART2^^^^

(any expression) ( parameters )
^^^^^^ PART 1^^^ ^^^^PART 2 ^^^

(function optionalFunctionName (parameters) { ..body.. })
( parameters )
^^^^^^^^^^^^^^^^^^^^^^^ PART 1 ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^PART 2
^^^

PART 2 "(parameters)" is the call operator : () : whenever something
[1] that refers to a function is followed by a call operator, the
function that that something points to gets called.

[1] An expression's result or an identifier:

varPointingToaFunction(); : an identifier followed by a call operator.
(varPointingToaFunction)(); : expression whose result is a function
followed by a call operator.
(function(){})(); : expression (containing a function expression)
whose result is a function followed by a call operator.
varPointingToaFunction()(); : expression whose result is a function
followed by a call operator.
(varPointingToaFunction())(); : idem.
etc.

--
Jorge.

Jonathan Fine

unread,
Jul 30, 2009, 11:40:20 AM7/30/09
to
Jorge wrote:

There is an exceptional special case (the new operator):

>>> new Object();
Object
>>> new Object;
Object

Same applies to your own constructors:

>>> F = function(){ return this.a = 1}
function()
>>> new F();
Object a=1
>>> new F;
Object a=1

John (the OP), I hope this does not confuse you.

My advice is not to drop the parentheses, even though you are allowed to.

--
Jonathan

RobG

unread,
Jul 31, 2009, 5:13:28 PM7/31/09
to
On Jul 30, 5:02 pm, Jonathan Fine <jf...@pytex.org> wrote:
> john_woo wrote:
> > Hi,
>
> > I've read/used JavaScript for more that 2 years, but still don't
> > understand the following:
>
> >  (function($) {
> >      //when the DOM is ready...
> >      window.addEvent('..,function() {
>
> >         /* ALL JAVASCRIPT WILL BE IN HERE */
>
> >      });
> >  })(document.id);
[...]

>
> Functions can be used to store code for reuse.  That's not what what's
> happening in your example.  Instead, the function is being used to
> create a closure.

The code pattern queried doesn't necessarily create any closures.

[...]


> Let's now unpack (and change slightly) your example.
>
>      var tmp = function(){
>          var tgt = document.getElementById('ssss');
>
>          // Lot's of code involving tgt.
>      };
>
>      tmp();
>      tmp = undefined;
>
> We've now got a variable 'tgt' that saves us some typing when writing
> our code.  We can do other things with 'tgt', and this is the powerful
> side of closures.

That code doesn't create any closures. It is equivalent to:

function tmp() {
/* same function body */
}

The only difference between the two is when the function is assigned
to the identifier tmp. In the first case, it's during execution of
global code - tmp will be undefined until the code is executed. In the
second, it will be assigned a value during variable instatiation and
have a value before any code is executed.


>  But I don't think it's present in your example.

Yes, there is no closure.

>
> The code I wrote can be condensed as:
>      var tmp;  // Retained as worthless side-effect of above.
>      (function(){ ....})();

There is a very big difference: in the first example, the function
expression is assigned to tmp so it can be reused. In the second, no
assignment is made so tmp stays undefined.


> In this case there's no real difference between
>      (function(){ var tgt = document.getElementById('sss'); ....})();
>      (function(tgt){ ....})(document.getElementById('sss'));
>
> I think the first form is clearer, although most people use the second.

There is no practical difference because using an identifier in a
formal parameter list is the same as declaring it locally. The second
form should only used if a value should be passed to tgt, otherwise,
it should be declared inside the function.


> BTW, all the parentheses are required.
>      js> function(){}()
>      typein:2: SyntaxError: syntax error:
>      typein:2: function(){}()
>      typein:2: .............^

See Kangax's response for why.


--
Rob

Jonathan Fine

unread,
Jul 31, 2009, 5:28:40 PM7/31/09
to
RobG wrote:
> On Jul 30, 5:02 pm, Jonathan Fine <jf...@pytex.org> wrote:

[snip]

>> Let's now unpack (and change slightly) your example.
>>
>> var tmp = function(){
>> var tgt = document.getElementById('ssss');
>>
>> // Lot's of code involving tgt.
>> };
>>
>> tmp();
>> tmp = undefined;
>>
>> We've now got a variable 'tgt' that saves us some typing when writing
>> our code. We can do other things with 'tgt', and this is the powerful
>> side of closures.
>
> That code doesn't create any closures. It is equivalent to:
>
> function tmp() {
> /* same function body */
> }
>
> The only difference between the two is when the function is assigned
> to the identifier tmp. In the first case, it's during execution of
> global code - tmp will be undefined until the code is executed. In the
> second, it will be assigned a value during variable instatiation and
> have a value before any code is executed.

Sorry, Rob, but there is a difference. In what I wrote the function is
executed. In what you wrote it is not.

If in the body of the function tmp I wrote
window.store = [tgt];
then there is a closure. This is what I meant by the powerful side of
closures. (Not required for OP's question.)

I wish I had time to read the rest of your post. Sorry. I hope that
what you've written helps the OP.

--
Jonathan

Jonathan Fine

unread,
Jul 31, 2009, 5:38:19 PM7/31/09
to
RobG wrote:
> On Jul 30, 5:02 pm, Jonathan Fine <jf...@pytex.org> wrote:

>> Let's now unpack (and change slightly) your example.
>>
>> var tmp = function(){
>> var tgt = document.getElementById('ssss');
>>
>> // Lot's of code involving tgt.
>> };
>>
>> tmp();
>> tmp = undefined;
>>
>> We've now got a variable 'tgt' that saves us some typing when writing
>> our code. We can do other things with 'tgt', and this is the powerful
>> side of closures.
>
> That code doesn't create any closures. It is equivalent to:
>
> function tmp() {
> /* same function body */
> }
>
> The only difference between the two is when the function is assigned
> to the identifier tmp. In the first case, it's during execution of
> global code - tmp will be undefined until the code is executed. In the
> second, it will be assigned a value during variable instatiation and
> have a value before any code is executed.

I now understand what you mean. You're saying that
// Top level.
var tmp = function(){ ... };
function tmp(){ ... };
are very similar. I agree.

I never use the second form because it can be confusing and cause a
gotcha. For example, this works:
// Top level
doit(1, 2, 3);
function doit(){...};

Here's another example. Even though the function definition/declaration
is inaccessible, being past the return, it is executed.
===
var x = function(){
var tmp;
return tmp;
function tmp(){
};
};
===

I don't do
function name(){ ... };
and I advise you not to do this either.

--
Jonathan

Jorge

unread,
Jul 31, 2009, 7:41:10 PM7/31/09
to
On Jul 31, 11:13 pm, RobG <robg...@gmail.com> wrote:
> On Jul 30, 5:02 pm, Jonathan Fine <jf...@pytex.org> wrote:
> > john_woo wrote:
>
> > >  (function($) {
> > >      //when the DOM is ready...
> > >      window.addEvent('..,function() {
>
> > >         /* ALL JAVASCRIPT WILL BE IN HERE */
>
> > >      });
> > >  })(document.id);
> [...]
>
> > Functions can be used to store code for reuse.  That's not what what's
> > happening in your example.  Instead, the function is being used to
> > create a closure.
>
> The code pattern queried doesn't necessarily create any closures.

Yes it does: the function(Expression) created and passed as a
parameter to window.addEvent captures the outer context(s) : read :
creates a closure. At least both document and $ are captured in that
closure, although as document might very well be the global document
it makes not much sense to talk about it being captured, but if it
weren't, it would be captured as well (and would be shadowing the
global document).

--
Jorge.

RobG

unread,
Aug 1, 2009, 5:39:19 AM8/1/09
to

I was discussing the general pattern, which doesn't *necessarily*
create a closure. The example does, but any function declaration or
expression inside another function will do that, it doesn't require
the specific pattern in the OP.


--
Rob

Jorge

unread,
Aug 1, 2009, 5:45:13 AM8/1/09
to
On Aug 1, 11:39 am, RobG <robg...@gmail.com> wrote:
>
> I was discussing the general pattern, which doesn't *necessarily*
> create a closure. The example does, but any function declaration or
> expression inside another function will do that (...)

No no, not any:

this doesn't :
(function(){
function f () {};
})();

but this does:
(function(){
function f () {};
window.onload= f;
})();

--
Jorge

Jorge

unread,
Aug 1, 2009, 6:05:56 AM8/1/09
to

The same thing written in a slightly different way:

this doesn't :

(function () {
var f= function f () {};
})();

but this does:

(function () {
window.onload= function f () {};
})();

--
Jorge.

kangax

unread,
Aug 1, 2009, 8:16:45 PM8/1/09
to

That probably depends on exactly how you define a closure.

Any optimizations aside, when function is instantiated, it must
initialize (or at least behave as if it initializes) its internal
[[Scope]] property to contain the same objects as those in a scope chain
of current execution context (the one it's being instantiated within).
That [[Scope]] is then used to initialize function's execution context
(where it will be used entirely and only preceded with function's
Activation Object).

This means that in your first example -

(function(){
function f(){};
})();

- when `f` is being instantiated, its [[Scope]] contains at least outer
function's Activation Object. Whether there are any variable/function
declarations performed in the outer function (so that Activation Object
has other properties but `arguments`) is technically irrelevant; it's
already closed over inner function and so will be used when initializing
inner function's execution context.

If we consider this process to be a closure, than we can say that even
in a simple (and pointless) case like this -

function f(){
function g(){}
}

- a closure is being formed with inner function (over outer function).

On the other hand, we can make definition a bit stricter and say that
closure is formed only when there exist any free variables in any of the
activation objects (not counting implicit `arguments` property) captured
in function's [[Scope]], such as -

function f(){
var x;
function g(){}
}

We can also say that closure is formed only when inner function is being
made available to the outside of its containing function (which, I
think, is what you were trying to say), such as -

function f(){
function g(){}
return g;
}

Or we can have both prerequisites -

function f(){
// free variable
var x;
// and function is made available for outside execution
setTimeout(function(){
return x;
});
}

which would mean that both -

(function(){
return function(){};
})();

// and

(function(){
var x;
(function(){})();
})();

- would be considered as those NOT forming the closure.

I was never really sure which one of these people mean when talking
about closures. For example, Richard's article - the most definite
description of closures to date - has a definition (coined by Lasse, I
think) which seems to "fit" first, least strict, case -


| A "closure" is an expression (typically a function) that can have free
| variables together with an environment that binds those variables
| (that "closes" the expression).


But then there's a more explicit explanation, and it already mentions
"outside availability" of inner function -


| A closure is formed when one of those inner functions is made
| accessible outside of the function in which it was contained, so that
| it may be executed after the outer function has returned.


I'm actually curious which one of these examples can be considered to be
"forming a closure". I, for example, always thought (and it looks like
RobG thought so as well) that first example already does.

Perhaps, I'm just missing something here.

--
kangax

John G Harris

unread,
Aug 2, 2009, 6:28:55 AM8/2/09
to
On Sat, 1 Aug 2009 at 20:16:45, in comp.lang.javascript, kangax wrote:

<snip>


>I'm actually curious which one of these examples can be considered to
>be "forming a closure". I, for example, always thought (and it looks
>like RobG thought so as well) that first example already does.
>
>Perhaps, I'm just missing something here.

Case 1 :
function f(n)
{
return function() { alert(42); } ;
}
The returned function has nothing special about it. Describing what is
returned is straightforward.


Case 2 :
function f(n)
{
return function() { alert(n); } ;
}
The returned function has something very special about it. It displays a
parameter of f that ceased to exist when f finished executing.
Describing in detail what is returned is complicated and describing it
in simple words is almost impossible.

It seems to me that case 2 is an example of a closure, whereas case 1 is
not.

That said, the javascript implementation might include the closure
machinery in case 1 even though it's not used. On the other hand, it
need not.

John
--
John Harris

Jorge

unread,
Aug 2, 2009, 12:41:08 PM8/2/09
to
On Aug 2, 12:28 pm, John G Harris <j...@nospam.demon.co.uk> wrote:
>
> Case 1 :
>   function f(n)
>     {
>       return function() { alert(42); } ;
>     }
> The returned function has nothing special about it. Describing what is
> returned is straightforward.
>
> Case 2 :
>   function f(n)
>     {
>       return function() { alert(n); } ;
>     }
> The returned function has something very special about it. It displays a
> parameter of f that ceased to exist when f finished executing.

Yep. Exactly. That's the important point: that f() exited and its
context should have been destroyed and garbage collected but instead
it isn't and survives in the closure.

--
Jorge.

Jorge

unread,
Aug 2, 2009, 1:34:33 PM8/2/09
to

A context is what we used to call a stack frame, an old(1) Pascal
term. Other aspects of so-called "closures", such as access to the
outer (enclosing) function's ('free') vars are nothing new, we had
that in Pascal's nested subroutines back then (and it was *not* called
a "closure"). What is fresh, new, different in "closures" to what we
already had before is that the contexts can outlive (read: are not
destroyed immediatly after) the function call to which they belong, as
a consequence of (now first-class) functions being passed around as
data.

(1)http://en.wikipedia.org/wiki/Stack_frame#Structure
--
Jorge.

John G Harris

unread,
Aug 2, 2009, 3:05:19 PM8/2/09
to

But earlier on, in a reply to RobG, you said that

(function(){
function f () {};
window.onload= f;
})();

creates a closure. It's the same as case 1 so now you're claiming it
doesn't create a closure.

What are you really trying to claim ?

John
--
John Harris

Message has been deleted

Jorge

unread,
Aug 3, 2009, 5:45:28 AM8/3/09
to

(function g () {


window.onload= function f () {};
})();

1.- g() executes and exits.
2.- outside of g's context, window.onload holds a reference to f,
therefore f still exists even after g() has exited.
3.- as f's context includes g's context, neither g's (nor f's) context
can be destroyed/garbage collected.

(function g () {


var f= function f () {};
})();

1.- g() executes and exits.
2.- outside of g's context, nobody else holds a reference to f,
therefore,
3.- g's context and f's context can be and are normally destroyed/
garbage collected.

--
Jorge.

getify

unread,
Aug 3, 2009, 11:25:01 AM8/3/09
to
On the topic of "closure" definition requiring something being made
available to the outside:

function foo() {
var x;
function bar(){alert(x);}
return {
a:function(){ bar(); }
}
}

In that example, certainly "a" has a closure to "bar".

But, the more interesting thing is that bar() has a closure, to "x".
Reason? Because it remembers the reference to "x", even if the outer
foo() has initially executed. But, it fails the strict definition that
bar() was made available to outside execution. It sort of is, but only
by indirect extension with another closure, not directly.

In my opinion, a function gets a closure if it CAN remember its
variable scope later, plain and simple. In practice you can't OBSERVE
or LEVERAGE an "internal" closure unless there's some sort of
execution chain directly or indirectly exposed, which of course much
itself be created via closure ("external").

"If a tree falls in the forest and noone hears it, did it make a
sound? Yes!"

Assigning an execution context ("external closure") to bar() certainly
is not what gives it the ability to remember "x" -- it must have had
that capability already by virtue of its declaration in the inner
function context. Without the external closure, you can't see the
internal closure, but nevertheless, it must exist because we know that
this function remembers "x" since it's able to work without throwing
symbol undefined errors.

So, to sum up, I think there's two closures happening. One internally,
and one externally.

---------------

Oh, and what about this, to even further reinforce (or perhaps
complicate):

function foo() {
var x;
function bar(myvar){
eval("alert("+myvar+");");
}
return {
a:function(myvar){ bar(myvar); }
}
}

(new foo()).a("x");

Which function(s) have a closure to "x"? I think both a() and bar().
Or maybe you could argue "neither", and that eval() just magically
creates the closure on the fly. Nevertheless, if a() wasn't present,
bar() would logically still be able to function, though we couldn't
practically demonstrate it.


--Kyle

kangax

unread,
Aug 3, 2009, 12:15:21 PM8/3/09
to
getify wrote:
> On the topic of "closure" definition requiring something being made
> available to the outside:
>
> function foo() {
> var x;
> function bar(){alert(x);}
> return {
> a:function(){ bar(); }
> }
> }
>
> In that example, certainly "a" has a closure to "bar".
>
> But, the more interesting thing is that bar() has a closure, to "x".
> Reason? Because it remembers the reference to "x", even if the outer
> foo() has initially executed. But, it fails the strict definition that
> bar() was made available to outside execution. It sort of is, but only
> by indirect extension with another closure, not directly.

Well, the thing is that function referenced from `a` property of the
returning object (let's call it just `a` function, for simplicity) is
also *instantiated within a context of `x` variable*. As a matter of
fact, this `a` function should have a scope, fully identical to that of
`bar` function. The only difference between these functions, is that
latter one is declared via function expression, and former one - via
function declaration (and also has an identifier, as a side effect).
Semantically, of course, function `a` is also different in a sense that
it is being returned from the outer `foo` function, whereas `bar` is not.

The bottom line is that `a` function has a very much direct reference to
`x` in your example; `x` ends up being a property of an Activation
Object of execution context that function `a` was instantiated within.

The peculiar thing is that even if there was no `x`, Activation Object
would still (as per specs) end up being "trapped" in an inner function's
closure - but this time only having one `arguments` property, rather
than `arguments` and `x` ones.

An example I was puzzling about was this:

(function(){
var x;
setTimeout(function(){
alert(x);
}, 100);
})();

If you try to determine whether a closure is formed here simply by
asserting that either -

a) inner function (or indirect reference to it) is being returned from
the outer function;

b) inner function (or indirect reference to it) is being assigned to
non-local variable;

- you will see that none of these apply. Yet, there clearly is a closure
formed here.

[...]

> ---------------
>
> Oh, and what about this, to even further reinforce (or perhaps
> complicate):
>
> function foo() {
> var x;
> function bar(myvar){
> eval("alert("+myvar+");");
> }
> return {
> a:function(myvar){ bar(myvar); }
> }
> }

I don't think it does what you think it should be doing :)

When `bar` is invoked, `myvar` is being coerced to a string and is being
concatenated with "alert(" and ");". This means that if you pass a
reference to an Object object, it will most likely (if `toString` will
propagate to `Object.prototype.toString` one) be converted to "[object
Object]" and overall string will become - "eval([object Object]");

In this case, `bar` itself doesn't use any free variables whatsoever.

>
> (new foo()).a("x");
>
> Which function(s) have a closure to "x"? I think both a() and bar().

Yep, both - `a` and `bar`.

[...]

--
kangax

Jorge

unread,
Aug 3, 2009, 1:03:47 PM8/3/09
to
On Aug 3, 5:25 pm, getify <get...@gmail.com> wrote:
> On the topic of "closure" definition requiring something being made
> available to the outside:
>
> function foo() {
> var x;
> function bar(){alert(x);}
> return {
> a:function(){ bar(); }
> }
>
> }
>
> In that example, certainly "a" has a closure to "bar".

No. Both "a" and "bar" have access to foo's context. It's in foo's
context where x and bar are defined. It's in foo's context where they
are found and resolved.

> But, the more interesting thing is that bar() has a closure, to "x".
> Reason? Because it remembers the reference to "x", even if the outer
> foo() has initially executed. But, it fails the strict definition that
> bar() was made available to outside execution. It sort of is, but only
> by indirect extension with another closure, not directly.

-That inner anonymous function referenced in the a: property of the
returned object is the reference that persists after foo()'s
execution,
-its context includes foo's context,
-function bar's context includes foo's context as well,
-bar is defined in foo's context as function bar () { alert(x); },
-x is defined in foo's context and has the value undefined

> (...)

--
Jorge

Jorge

unread,
Aug 3, 2009, 1:11:25 PM8/3/09
to
On Aug 3, 6:15 pm, kangax <kan...@gmail.com> wrote:
> (...)

> An example I was puzzling about was this:
>
> (function f () {
> var x;
> setTimeout(function g () {
> alert(x);
> }, 100);
>
> })();
>

A reference to g persists after f returns: it's saved in the timer's
queue.
g's context includes (access to) f's context.
What's puzzling ?
:-)
--
Jorge.

John G Harris

unread,
Aug 3, 2009, 2:37:20 PM8/3/09
to
<snip>

It doesn't work like that.
function f () {}
must be a function expression as it's on the right-hand side of an
assignment. Therefore the identifier f is a name that's local to f. It's
an alias for 'myself' for use when the function wants to call itself. It
cannot be used outside f. The other code in g cannot use the name f to
call the function.

After g has exited, the unload property of window has a value that is a
pointer to a function object. window doesn't have a name for that
function object other than the property name.

To put it another way, window.unload does not hold a reference to f, it
holds a reference to a function object.

Whatever extra code is put into g the value of f cannot be different
each time g is called.

In short, that isn't an example of a closure and ECMAScript doesn't
require it to be treated as one.

John
--
John Harris

Jorge

unread,
Aug 3, 2009, 4:00:54 PM8/3/09
to
On Aug 3, 8:37 pm, John G Harris <j...@nospam.demon.co.uk> wrote:
> On Mon, 3 Aug 2009 at 02:45:28, in comp.lang.javascript, Jorge wrote:
>
> >(function g () {
> > window.onload= function f () {};
> >})();
>
> >1.- g() executes and exits.
> >2.- outside of g's context, window.onload holds a reference to f,
> >therefore f still exists even after g() has exited.
> >3.- as f's context includes g's context, neither g's (nor f's) context
> >can be destroyed/garbage collected.
>
> <snip>
>
> It doesn't work like that.
> function f () {}
> must be a function expression as it's on the right-hand side of an
> assignment. Therefore the identifier f is a name that's local to f. It's
> an alias for 'myself' for use when the function wants to call itself. It
> cannot be used outside f. The other code in g cannot use the name f to
> call the function.

Yes, and ?

> After g has exited, the unload property of window has a value that is a
> pointer to a function object. window doesn't have a name for that
> function object other than the property name.

Yes, and ?

> To put it another way, window.unload does not hold a reference to f, it
> holds a reference to a function object.

Yes, a reference to (the function named f) function object.

> Whatever extra code is put into g the value of f cannot be different
> each time g is called.

The symbol f is not defined, does not exist in g's context.

> In short, that isn't an example of a closure and ECMAScript doesn't
> require it to be treated as one.

Sure, that's why:

(function g () {
window.onload= function f () { alert(g); };
})();

window.onload();

Alerts:

function g() {
window.onload= function f () { alert(g); };
}

--
Jorge.

kangax

unread,
Aug 3, 2009, 6:09:22 PM8/3/09
to
Jorge wrote:
> On Aug 3, 6:15 pm, kangax <kan...@gmail.com> wrote:
>> (...)
>> An example I was puzzling about was this:
>>
>> (function f () {
>> var x;
>> setTimeout(function g () {
>> alert(x);
>> }, 100);
>>
>> })();
>>
>
> A reference to g persists after f returns: it's saved in the timer's
> queue.

It's clear because we "know" that reference to `f` must be stored in
setTimeout/setInterval queue, but it's not clear from the "outside" if
you don't know what a function does, is it?

For example, this might as well have been:

(function f(){
var x;
foo(function(){
alert(x);
});
})();
...

and then there could be something like:

...
function foo(fn) {
setTimeout(fn, 100);
}

or just as a plain alias before that chunk of code -

var foo = setTimeout;


Here's another example of implicit non-assignment, non-return,
non-setTimeout/setInterval closure :)

var arr = [];
(function(){
var x;
arr.push(function(){ return x; });
})();

But then I guess this still falls under an assigment category, if we
desugar it to something like:

var arr = [];
(function(){
var x;
arr[arr.length] = function(){ return x; };
})();

> g's context includes (access to) f's context.
> What's puzzling ?

Do you know if any implementations determine whether inner function
references are leaking outside of execution context (to be able to
optimize)?

--
kangax

Jorge

unread,
Aug 3, 2009, 6:50:03 PM8/3/09
to

Yep, all good, nice examples.

> Do you know if any implementations determine whether inner function
> references are leaking outside of execution context (to be able to
> optimize)?

I think there's no such thing as something to optimize :-) I mean, the
contexts for each function are created anyways, and access to outer
functions' contexts (a chained list of pointers to the outer
functions' contexts) from within inner functions exists anyways. Many
people seem to believe that the contexts are copied/duplicated, but
they need not and they are not : the context (that are essentially the
old "stack frames" data structures, probably objects themselves)
'objects' are *shared*. The only "special thing" that happens when
there's a closure is that these contexts are not marked as garbage to
be collected, to be destroyed immediately upon exiting the outer
function (probably using reference counts or something). Therefore, I
think, there's really not much to optimize...

--
Jorge.

John G Harris

unread,
Aug 4, 2009, 2:47:26 PM8/4/09
to
On Mon, 3 Aug 2009 at 13:00:54, in comp.lang.javascript, Jorge wrote:
>On Aug 3, 8:37 pm, John G Harris <j...@nospam.demon.co.uk> wrote:
>> On Mon, 3 Aug 2009 at 02:45:28, in comp.lang.javascript, Jorge wrote:
>>
>> >(function g () {
>> > window.onload= function f () {};
>> >})();
>>
>> >1.- g() executes and exits.
>> >2.- outside of g's context, window.onload holds a reference to f,
>> >therefore f still exists even after g() has exited.
>> >3.- as f's context includes g's context, neither g's (nor f's) context
>> >can be destroyed/garbage collected.

<snip>

>> In short, that isn't an example of a closure and ECMAScript doesn't


>> require it to be treated as one.
>
>Sure, that's why:

<snip>

So, now you say that point 3 is not true, in agreement with what I said.

Please stop wasting our time.

John
--
John Harris

Jorge

unread,
Aug 4, 2009, 3:07:45 PM8/4/09
to
On Aug 4, 8:47 pm, John G Harris <j...@nospam.demon.co.uk> wrote:
>
> So, now you say that point 3 is not true, in agreement with what I said.

Do I ?

> Please stop wasting our time.

"Our" ? Are you the king or something ?

--
Jorge.

Thomas 'PointedEars' Lahn

unread,
Aug 4, 2009, 4:33:23 PM8/4/09
to
kangax wrote:
> Jorge wrote:
>> On Aug 3, 6:15 pm, kangax <kan...@gmail.com> wrote:
>>> (...)
>>> An example I was puzzling about was this:
>>>
>>> (function f () {
>>> var x;
>>> setTimeout(function g () {
>>> alert(x);
>>> }, 100);
>>>
>>> })();
>>>
>> A reference to g persists after f returns: it's saved in the timer's
>> queue.
>
> It's clear because we "know" that reference to `f` must be stored in
> setTimeout/setInterval queue,

Do we? If anything, a reference to the function object represented by `g'
(when called) is stored "in the timer's queue" (more precisely, in the list
that serves as container for the pieces of code to be executed). `g' is
created with a [[Scope]] property to refer to its scope chain, which
contains a reference to the Activation/Variable Object of the Function
object that is represented by `f' (when called). Cf. ES3F, section 13, in
particular subsection 13.2 Creating Function Objects.

> [...]


>> g's context includes (access to) f's context.

Correct, in a sense.

>> What's puzzling ?
>
> Do you know if any implementations determine whether inner function
> references are leaking outside of execution context (to be able to
> optimize)?

No.


PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann

RobG

unread,
Aug 4, 2009, 11:57:59 PM8/4/09
to

I would say that it's a closure: the function object created by the
function expression assigned and to window.onload must have the
activation object of the outer function on its scope chain (or at
least appear to).

The fact that no use is made of the closure doesn't matter, it might
even be optimised away by smart compilers, but it's there in the code.
Memory leaks used to caused in IE using functions like:

function foo(el) {
el.onclick = function() { ... };
}

because the function assigned to the onclick handler has a closure to
el, which is a local variable of the foo function, thereby causing a
circular reference. The listener didn't have to actually reference el
(or any other local variable of foo).

The leak was avoided (in this case) by assigning null to el before the
end of the function, breaking the circular reference (but not the
closure):

function foo(el) {
el.onclick = function() { ... };
el = null;
}

I discussed this with Thomas a little while ago:

"this' confusion"
<URL: http://groups.google.com/group/comp.lang.javascript/msg/43a6ede69ea7abef
>


--
Rob

Jorge

unread,
Aug 5, 2009, 5:29:07 AM8/5/09
to
> (...)

That would be so in any case, whether or not assigned to
window.onload. It's a scoping rule that outer function vars be
accessible from within inner functions.

--
Jorge.

John G Harris

unread,
Aug 5, 2009, 11:51:46 AM8/5/09
to
On Wed, 5 Aug 2009 at 02:29:07, in comp.lang.javascript, Jorge wrote:

<snip>


>That would be so in any case, whether or not assigned to
>window.onload. It's a scoping rule that outer function vars be
>accessible from within inner functions.

scoping rule !== closure

John
--
John Harris

Jorge

unread,
Aug 5, 2009, 1:29:58 PM8/5/09
to

Right.

Scoping rules + first class functions => closures

--
Jorge.

John G Harris

unread,
Aug 5, 2009, 2:15:17 PM8/5/09
to
On Tue, 4 Aug 2009 at 20:57:59, in comp.lang.javascript, RobG wrote:
>On Aug 4, 4:37�am, John G Harris <j...@nospam.demon.co.uk> wrote:
>> On Mon, 3 Aug 2009 at 02:45:28, in comp.lang.javascript, Jorge wrote:
>> >On Aug 2, 9:05�pm, John G Harris <j...@nospam.demon.co.uk> wrote:
>> >> On Sun, 2 Aug 2009 at 09:41:08, in comp.lang.javascript, Jorge wrote:
>> >> >On Aug 2, 12:28�pm, John G Harris <j...@nospam.demon.co.uk> wrote:

<snip>


>> >> (function(){
>> >> � function f () {};
>> >> � window.onload= f;

<snip>

>I would say that it's a closure: the function object created by the
>function expression assigned and to window.onload must have the
>activation object of the outer function on its scope chain (or at
>least appear to).

ECMA 262 says that the javascript implementation can fall back to a
single scope object when the function objects will always use the same
scope information. So, officially it's not a closure even if the
implementation chooses to use the closure machinery.


>The fact that no use is made of the closure doesn't matter, it might
>even be optimised away by smart compilers, but it's there in the code.
>Memory leaks used to caused in IE using functions like:
>
>function foo(el) {
> el.onclick = function() { ... };
>}
>
>because the function assigned to the onclick handler has a closure to
>el, which is a local variable of the foo function, thereby causing a
>circular reference. The listener didn't have to actually reference el
>(or any other local variable of foo).

<snip>

ECMA 262 says that the observable behaviour shouldn't be different
whether the closure machinery is used or not. Unfortunately, language
standards usually don't include performance and storage hogging in
'observable' behaviour.

John
--
John Harris

John G Harris

unread,
Aug 5, 2009, 2:25:42 PM8/5/09
to

ECMA 262 says you're wrong.

John
--
John Harris

Gabriel Gilini

unread,
Aug 5, 2009, 8:06:24 PM8/5/09
to

Could you please refer to the proper section for our better understanding?
That applies to your previous reply as well.

TIA

--
Gabriel Gilini

RobG

unread,
Aug 5, 2009, 9:38:56 PM8/5/09
to

Of course, but the assignment to window.onload is what makes it
available outside the context of the original function and therefore
is necessary (in the example) for the closure to be formed.

Lets get specific:

Case 1:
---------
function foo() {
function bar() {}
bar();
}
foo();

When foo is executed, bar has foo's activation/variable object on its
scope chain. Once foo has returned, there is no persistent reference
to anything inside foo(). Can bar be said to have a closure to foo,
even if it's just for the time the bar is actually executing? I think
the consensus is "no".


Case 2:
---------
var x;
function foo() {
x = function () {
alert('hi');
}
}
foo();
x();

In this case, the anonymous function assigned to x has foo's
activation object on its scope chain (or is given the appearance that
it has). Implementations may optimise it away as there are no
references to foo's local variables, but that can't be counted on. I
think it should be assumed that a closure exists based on the code,
unless it is *known* that it will only be run in an implementation
that doesn't create a closure for this case.


Case 3:
---------
var x;
function foo(n) {
var num = n;
x = function () {
alert(num);
}
}
foo(42);
x();

I don't think there is any doubt that the above is a closure. The
anonymous function has a closure to num (at least) that persists after
foo has executed due to the assignment to x. Again, an implementation
may decide to simply add num as a local variable to the anonymous
function assigned to x, it's impossible to tell how it does it by
looking at results.

The bottom line for me is that the code pattern for cases 2 and 3
indicate a closure, whether one is in fact created by a specific
implementation is usually irrelevant in general discussion, though it
might be of interest sometimes.


--
Rob

kangax

unread,
Aug 6, 2009, 12:05:13 AM8/6/09
to

So to summarize (please correct me if I miss something), you say that
closure is formed when a function is being instantiated within another
function and is then made available outside of its enclosing function.

Whether there are any free variables declared in the scope of enclosing
function is considered irrelevant. How inner function is made available
outside of its enclosing function is also considered irrelevant (it
could be a return value (or part of it); it could be an assignment to a
non-local variable; it could be passed as one of the arguments to
another function; or by other means). Whether inner function is being
actually executed after enclosing function returns is considered
irrelevant as well.

The first paragraph is actually practically identical to a snippet from
Richard's article:

| A closure is formed when one of those inner functions is made
| accessible outside of the function in which it was contained, so that

| it may be executed after the outer function has returned. At which
| point it still has access to the local variables, parameters and inner
| function declarations of its outer function. Those local variables,
| parameter and function declarations (initially) have the values that
| they had when the outer function returned and may be interacted with
| by the inner function.


--
kangax

Jorge

unread,
Aug 6, 2009, 4:32:57 AM8/6/09
to
On Aug 6, 3:38 am, RobG <robg...@gmail.com> wrote:
> (...)

> Case 3:
> ---------
> var x;
> function foo(n) {
>   var num = n;
>   x = function () {
>     alert(num);
>   }}
>
> foo(42);
> x();
>
> I don't think there is any doubt that the above is a closure. The
> anonymous function has a closure to num (at least) that persists after
> foo has executed due to the assignment to x. Again, an implementation
> may decide to simply add num as a local variable to the anonymous
> function assigned to x, it's impossible to tell how it does it by
> looking at results. (...)

If num were a local variable of x() this wouldn't work:

var x, y;


function foo(n) {
var num = n;

x= function () { alert(num); };
y= function () { num++; }
}

foo(42);
x(); -> 42
y();
x(); -> 43

--
Jorge.

Jorge

unread,
Aug 6, 2009, 7:40:53 AM8/6/09
to

kangax wrote:
> (...)


> | Those local variables,
> | parameter and function declarations (initially) have the values that
> | they had when the outer function returned and may be interacted with
> | by the inner function.

"Those local variables, parameter and function declarations" : inner
function declarations are (really just) local vars too:

var external;
(function g (x) {
function f () { }
f= -1;
external= f;
})(27)

external(); //-> TypeError: expression 'external' [-1] is not a
function.

It's not true that "(initially) have the values that they had when the
outer function returned" :

(function g (x) {
window.onload= function f () { alert(x); }
window.onload(); // "initially" Alerts 27
x++;
})(27)

//but x is 28 when the outer function returned:
window.onload(); //->alerts 28

It would be more correct, I think, to say the truth: that outer
functions' vars and parameters are simply shared with inner functions
(in the same way as globals are, only that globals are shared
globally).

Also, when explaining closures, it might be a good idea to point out
that while

var external;
(function outer (x) {
external= function () { alert(x); };
})(27)

external(); //alerts 27

creates a closure, this -instead- does not:

var external;
(function outer (x) {
external= Function('alert(x);');
})(27)

external(); //ReferenceError: Can't find variable: x

--
Jorge.


Jorge

unread,
Aug 6, 2009, 7:51:27 AM8/6/09
to
On Aug 5, 5:57 am, RobG <robg...@gmail.com> wrote:
>
> I discussed this with Thomas a little while ago:
>
> "this' confusion"
> <URL:http://groups.google.com/group/comp.lang.javascript/msg/43a6ede69ea7abef
>

ISTM that Lahn has yet to understand what closures are, as everytime
he dares to write a single word about closures he screws it up.

--
Jorge

Richard Cornford

unread,
Aug 6, 2009, 8:07:54 AM8/6/09
to
On Aug 6, 12:40 pm, Jorge <jo...@jorgechamorro.com> wrote:
> kangax wrote:
>> (...)
>>| Those local variables,
>>| parameter and function declarations (initially) have the values
>>| that they had when the outer function returned and may be
>>| interacted with by the inner function.
<snip>

> It's not true that "(initially) have the values that they had when the
> outer function returned" :

Worthwhile points rarely follow form disingenuous editing.

What you have quoted above is preceded by:-

| ... so that it may be executed after the outer function has


returned.
| At which point it still has access to the local variables,
| parameters and inner function declarations of its outer function.

Where "executed after the outer function has returned" and "At which
point" are significant for the meaning of the following text.

Richard.

Richard Cornford

unread,
Aug 6, 2009, 8:10:39 AM8/6/09
to
On Aug 6, 5:05 am, kangax wrote:
<snip>

> So to summarize (please correct me if I miss something), you
> say that closure is formed when a function is being instantiated
> within another function and is then made available outside of its
> enclosing function.
>
> Whether there are any free variables declared in the scope of
> enclosing function is considered irrelevant. How inner function
> is made available outside of its enclosing function is also
> considered irrelevant (it could be a return value (or part of
> it); it could be an assignment to a non-local variable; it could
> be passed as one of the arguments to another function; or by
> other means). Whether inner function is being actually executed
> after enclosing function returns is considered irrelevant as well.
<snip>

I am not sure that that last sentence should be included. This is one
place where John G Harris' "scoping rule !== closure" comes in.
Consider a programming language that is exactly like ECMAScript in
every respect except that the named properties of activation/variable
objects that are created during variable instantiation are deleted as
execution contexts are returned from. This is then a language in which
closures don't exist, yet the behaviour of an inner function called
(even very indirectly) before the function that contains it (within
which it was created) returns is identical to what it would be in
ECMAScript. That behaviour is explained by the language's scoping
rules alone and doesn't require closures.

For a closure I think you want to see both a function object _and_ its
environment outliving their normal (minimum, given the uncertain
nature of garbage collection) lifespan.

This is, of course, an arguable position, even a purely philosophical
position. If all the structures and mechanisms that facilitate
closures are in place why shouldn't a closure be considered to exists?
The same goes for the case where you preserve the inner function but
do not employ its environment (no other inner functions, formal
parameters or variables (or no uses of any of them in the inner
function)); if there is no way to determine whether the environment
was preserved (so no consequences either way) is it worth labelling it
a closure just because the necessary mechanism and structures may be
in place?

Earlier someone mentioned the question of whether if tree falls in a
forest, does it still makes a sound if there is nobody around to
perceive it. A pragmatic attitude might suggest that if you have no
way of knowing if/when a tree falls there is little point in expending
any effort worrying about how much noise it may make if it did.

Richard.

Jorge

unread,
Aug 6, 2009, 11:18:48 AM8/6/09
to
On Aug 6, 2:10 pm, Richard Cornford <Rich...@litotes.demon.co.uk>
wrote:

> On Aug 6, 5:05 am, kangax wrote:
>
> > Whether there are any free variables declared in the scope of
> > enclosing function is considered irrelevant. How inner function
> > is made available outside of its enclosing function is also
> > considered irrelevant (it could be a return value (or part of
> > it); it could be an assignment to a non-local variable; it could
> > be passed as one of the arguments to another function; or by
> > other means). Whether inner function is being actually executed
> > after enclosing function returns is considered irrelevant as well.
>
> <snip>
>
> I am not sure that that last sentence should be included. (...)

The closure *must* exist as long as the reference (to inner function)
because as long as there's a reference it *could* be executed. To be
sure that it won't, its reference count must be 0.
--
Jorge.

Richard Cornford

unread,
Aug 6, 2009, 11:57:14 AM8/6/09
to
On Aug 6, 4:18 pm, Jorge wrote:

> On Aug 6, 2:10 pm, Richard Cornford wrote:
>> On Aug 6, 5:05 am, kangax wrote:
>>> ... . Whether inner function is being actually executed after

>>> enclosing function returns is considered irrelevant as well.
>><snip>
>> I am not sure that that last sentence should be included. (...)
>
> The closure *must* exist as long as the reference (to inner
> function) because as long as there's a reference it *could*
> be executed. To be sure that it won't, its reference count
> must be 0.

At first that reads as a rather VKesque tangent. Once again you edited
out the context that makes sense of my statement. The point I was
addressing was the question of whether a closure should be considered
to exist if the inner function is (only) executed before the execution
context in which it was created returns and never made available
outside of that context.

Richard.

Jorge

unread,
Aug 6, 2009, 1:14:27 PM8/6/09
to
On Aug 6, 5:57 pm, Richard Cornford <Rich...@litotes.demon.co.uk>
wrote:

As Pascal's inner procedures, that is, not having first-class
functions, you mean ?
Because if functions are first-class a reference could be passed
along... and you'd end up with a function that does not function.
--
Jorge.

John G Harris

unread,
Aug 6, 2009, 2:13:49 PM8/6/09
to
On Wed, 5 Aug 2009 at 21:06:24, in comp.lang.javascript, Gabriel Gilini
wrote:

It's the note in ECMA 262, section 13.1.2.

John
--
John Harris

John G Harris

unread,
Aug 6, 2009, 3:22:59 PM8/6/09
to
On Thu, 6 Aug 2009 at 05:10:39, in comp.lang.javascript, Richard
Cornford wrote:

<snip>


>This is, of course, an arguable position, even a purely philosophical
>position. If all the structures and mechanisms that facilitate
>closures are in place why shouldn't a closure be considered to exists?
>The same goes for the case where you preserve the inner function but
>do not employ its environment (no other inner functions, formal
>parameters or variables (or no uses of any of them in the inner
>function)); if there is no way to determine whether the environment
>was preserved (so no consequences either way) is it worth labelling it
>a closure just because the necessary mechanism and structures may be
>in place?

<snip>

I think it's a terminology problem. We need two names for two different
things :

A proper closure occurs when an inner function is made callable from
outside its outer function, *and* the code of the inner function
accesses parameters or local variables of its outer function(s). The
standard requires this to work as in a traditional closure. There are no
options about this.

An empty closure occurs when an inner function is made callable from
outside its outer function, *and* the code of the inner function
accesses none of the parameters and local variables of its outer
function(s), *and* the inner function still carries the closure
machinery with it. The standard makes this an option. It can affect
performance and garbage collection, but this is (officially) not
observable behaviour of the program.

If, instead, the inner function does not carry the closure mechanism
with it then it is not a closure. The standard makes this an option as
well.

Incidentally, since Jorge has mentioned it, if inner functions cannot be
made callable from outside then there are no closures, only lexical
scopes. (As in Pascal).

John
--
John Harris

Jorge

unread,
Aug 6, 2009, 8:03:29 PM8/6/09
to

1.- Contexts must be created, setup and inserted in the scope chain in
any case (the mechanism of identifier resolution in accordance with
the scoping rules).

2.- Sometimes a function's context can't be destroyed upon exiting the
function : when at that point in time there still exists yet another
function whose context points to, includes, has access to, uses it:
that is necessarily the context of an outliving inner function. It's
then that we say that a closure has been created.

3.- There's no "closure machinery". A closure is the absence of
destruction of a context.
--
Jorge.

RobG

unread,
Aug 6, 2009, 11:55:00 PM8/6/09
to
On Aug 6, 10:10 pm, Richard Cornford <Rich...@litotes.demon.co.uk>
wrote:

> On Aug 6, 5:05 am, kangax wrote:
> <snip>> So to summarize (please correct me if I miss something), you
> > say that closure is formed when a function is being instantiated
> > within another function and is then made available outside of its
> > enclosing function.

Yes.


> > Whether there are any free variables declared in the scope of
> > enclosing function is considered irrelevant. How inner function
> > is made available outside of its enclosing function is also
> > considered irrelevant (it could be a return value (or part of
> > it); it could be an assignment to a non-local variable; it could
> > be passed as one of the arguments to another function; or by
> > other means). Whether inner function is being actually executed
> > after enclosing function returns is considered irrelevant as well.

Yes.

> <snip>
>
> I am not sure that that last sentence should be included. This is one
> place where John G Harris' "scoping rule !== closure" comes in.

I think that is exactly the point that it moves from "scoping rule" to
closure, i.e. it is at the moment that it is available externally that
it becomes a closure.


> Consider a programming language that is exactly like ECMAScript in
> every respect except that the named properties of activation/variable
> objects that are created during variable instantiation are deleted as
> execution contexts are returned from. This is then a language in which
> closures don't exist, yet the behaviour of an inner function called
> (even very indirectly) before the function that contains it (within
> which it was created) returns is identical to what it would be in
> ECMAScript. That behaviour is explained by the language's scoping
> rules alone and doesn't require closures.

Sure, but all we learn from that is that a closure creating function
acts like a typical function if the closure isn't used. If a function
is declared but never used, is it still a function?


> For a closure I think you want to see both a function object _and_ its
> environment outliving their normal (minimum, given the uncertain
> nature of garbage collection) lifespan.
>
> This is, of course, an arguable position, even a purely philosophical
> position. If all the structures and mechanisms that facilitate
> closures are in place why shouldn't a closure be considered to exists?

I think it should.


> The same goes for the case where you preserve the inner function but
> do not employ its environment (no other inner functions, formal
> parameters or variables (or no uses of any of them in the inner
> function)); if there is no way to determine whether the environment
> was preserved (so no consequences either way) is it worth labelling it
> a closure just because the necessary mechanism and structures may be
> in place?

Yes - if I buy a shovel but leave it in the shed and never use it,
it's still a shovel. There may later arise some unexpected consequence
due to the existence of the closure - does it suddenly exist because
it now has some measureable effect?


> Earlier someone mentioned the question of whether if tree falls in a
> forest, does it still makes a sound if there is nobody around to
> perceive it. A pragmatic attitude might suggest that if you have no
> way of knowing if/when a tree falls there is little point in expending
> any effort worrying about how much noise it may make if it did.

Just because a particular person didn't hear it doesn't mean that no
one did. If a closure is created, how can anyone be *certain* that it
isn't used? How can it be known with certainty that there are no
unintended consequences, say for performance or memory consumption?
That no as yet unseen code will be added to the page? Or the closure
has been assigned to some other identifier and is called in some
obscure fashion?

Hopefully you're playing devil's advocate here. Closures have been
shown to have (hopefully unintentional) adverse consequences in some
circumstances (e.g. IE circular references and memory leaks). I think
the broader definition suits if for no other reason than it causes
programmers to be more aware of the possible consequences of their
code.


--
Rob

Lasse Reichstein Nielsen

unread,
Aug 7, 2009, 1:18:18 AM8/7/09
to
Jorge <jo...@jorgechamorro.com> writes:

> 1.- Contexts must be created, setup and inserted in the scope chain in
> any case (the mechanism of identifier resolution in accordance with
> the scoping rules).

That's the specification. Implementations may optimize as they see
fit, as long as it's semantically equivalent.
If you have a good escape analysis, you could put variables on the
stack and not create an actual scope/context object, but ofcourse
it would be equivalent.
(Not that I'm aware of anybody doing that in Javascript).

> 2.- Sometimes a function's context can't be destroyed upon exiting the
> function : when at that point in time there still exists yet another
> function whose context points to, includes, has access to, uses it:
> that is necessarily the context of an outliving inner function. It's
> then that we say that a closure has been created.

That's one way of viewing it. It's not mine, though.

Another definition is to say that a closure is:
A piece of program code together with bindings of its free variables.
No more, no less.

Function objects are closures. They combine code and binding of the
free variables of the code (specified as remembering the entire scope
chain, but that need not be necessary).

That binding might be trivial, if the code has no free variables. You
can argue that it isn't really a closure then, but that's not really
important.

> 3.- There's no "closure machinery". A closure is the absence of
> destruction of a context.

Closures as "capturing static scope" can be detected even inside their
scope/context, since they are not affected by shadowing of their free
variables' definitions:

function test(a, b) {
function add(x) { return a + x; }
function doit(a, b) { return add(b); }
return doit(42, b);
}
test(37,5); // evaluates to 42.

In lisp, which doesn't have closures, but instead has dynamic scope,
the result would have been 47.


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

John G Harris

unread,
Aug 7, 2009, 2:37:04 PM8/7/09
to
On Fri, 7 Aug 2009 at 07:18:18, in comp.lang.javascript, Lasse
Reichstein Nielsen wrote:

<snip>


>That binding might be trivial, if the code has no free variables. You
>can argue that it isn't really a closure then, but that's not really
>important.

<snip>

It can be important if the delayed garbage collection has embarrassing
consequences, especially if some browsers can go wrong and others can't.
It's then that you need two names for the two cases, otherwise you can't
talk about them sensibly.

John
--
John Harris

0 new messages