Confusion about closures

L

Lasse Reichstein Nielsen

David Mark said:
On Apr 21, 7:36 am, Lasse Reichstein Nielsen <[email protected]>
wrote:

Still, the "non-trivial closure" that John G Harris mentioned is what
has been traditionally referred to as a "closure" in JS.

I'm not sure I have been introduced to that tradition. Perhaps I'm
handicapped by actually learning the word in the more general sense
first.
I can see that it is being used that way though (searching for
"Javascript closure" gives a little of each, and also a bunch of
completely clueless explanations).

....
But it's too late to change it in the context of JS (at least without
causing massive confusion).

"Let it always be the goal that stirs us, and not the odds."
Who said anything about "ECMAScript binding". I'm talking about the
DOM spec's, which have always referred to properties as "attributes"
as they use IDL to describe the interfaces.

Say what?
The DOM specification is based on the HTML specification (where elements
have *attributes*), and HTML predates JavaScript by several years.
Why on earth would the DOM specification (which isn't Javascript specific)
suddently rename attributes to "properties".
I.e., they are *not* referring to properties as "attributes". They are
referring to attributes.
OMFG. No kidding? :)

It wasn't obvious from your description of the problem that you
were aware of the distinction.
/L
 
D

David Mark

I'm not sure I have been introduced to that tradition.

Sure you have. You've been hanging around here long enough.
Perhaps I'm
handicapped by actually learning the word in the more general sense
first.
Perhaps.

I can see that it is being used that way though (searching for
"Javascript closure" gives a little of each, and also a bunch of
completely clueless explanations).

As would any JS-related search.
...


"Let it always be the goal that stirs us, and not the odds."

Best of luck with it! :)
Say what?
The DOM specification is based on the HTML specification (where elements
have *attributes*), and HTML predates JavaScript by several years.

Say DOM spec's, IDL, references to DOM properties as "attributes". In
other words, ancient history. I mean, how many times has this come up
over the years?

Why on earth would the DOM specification (which isn't Javascript specific)
suddently rename attributes to "properties".

You aren't following at all. I am referring to DOM property
definitions, which have nothing to do with HTML attributes.
I.e., they are *not* referring to properties as "attributes". They are
referring to attributes.

You have lost your way here.
It wasn't obvious from your description of the problem that you
were aware of the distinction.

No, you are simply confused as hell at this point.
 
D

David Mark

Sure you have.  You've been hanging around here long enough.


As would any JS-related search.





Best of luck with it!  :)





Say DOM spec's, IDL, references to DOM properties as "attributes".  In
other words, ancient history.  I mean, how many times has this come up
over the years?


You aren't following at all.  I am referring to DOM property
definitions, which have nothing to do with HTML attributes.


You have lost your way here.





No, you are simply confused as hell at this point.

And, in an attempt to jar you out of your confusion:-

http://www.w3.org/TR/DOM-Level-2-Core/core.html

Ctrl+F, type "attribute", click "Find", repeat... Lot of 'em, aren't
there? :)

And no, they aren't referring to HTML attributes. ;)
 
D

David Mark

And, in an attempt to jar you out of your confusion:-

http://www.w3.org/TR/DOM-Level-2-Core/core.html

Ctrl+F, type "attribute", click "Find", repeat...  Lot of 'em, aren't
there?  :)

And no, they aren't referring to HTML attributes.  ;)

Except where they are talking about HTML attribute-related interfaces
of course (e.g. getAttribute).

Here is a salient excerpt that will (hopefully) end this discussion:

"Thus, even though there is a generic nodeName attribute on the Node
interface, there is still a tagName attribute on the Element
interface; these two attributes must contain the same value, ..."

What? "tagName" ain't no attribute I ever heard of. :)
 
T

Thomas 'PointedEars' Lahn

Lasse said:
"Let it always be the goal that stirs us, and not the odds."

AFAIK, Silver Surfer said "ever", not "always" :)
Say what?
The DOM specification is based on the HTML specification (where elements
have *attributes*), and HTML predates JavaScript by several years.
Why on earth would the DOM specification (which isn't Javascript specific)
suddently rename attributes to "properties".
I.e., they are *not* referring to properties as "attributes". They are
referring to attributes.

They are referring to both. Attributes of interfaces in the IDL (of which
only some relate to markup attributes), and properties of objects in the
ECMAScript Binding section. Methods of objects are referred to as
"functions of objects" there.

Further confusion is caused by the term "property attributes" in the
specification. Those are attributes of interfaces that are implemented as
properties of (host) objects implementing these interfaces, which (loosely)
relate to attributes of (markup) elements represented by those objects (and
are therefore called "attribute properties" around here, where
implementations matter.)

<http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-642250288>
<http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html>


PointedEars
 
D

Dmitry A. Soshnikov

Yeah, notice though, that in JS functions created via `Function`
constructor do not capture in general case the parent frames and can be
considered as non-closures (which is also correct). However, in
particular case, if such a function is defined in the global context,
then being used in the downward funarg case it still shows the static
scope affecting which is directly related to closures.

One more thing to note. This exact case with `Function` functions as is
said particular. A similar case can be seen in a language which doesn't
support closures but however supports static scoping for global
functions. That is has only support of "downwards funargs".

For example, C/C++. A function may be used as a funarg (via passing a
pointer to the function) and even the static scope is applied, but still
it's not a closure, since C (except some versions of the compiler, e.g.
GNU) has only global functions.

int x = 10;

void foo()
{
cout << x;
}

void bar(void (*fun)())
{
int x = 20;
fun(); // 10 (static scope), not 20!
}

int _tmain(int argc, _TCHAR* argv[])
{
bar(foo); // pass "foo" as a funarg
return 0;
}

Another languages, e.g. Pascal may even have inner functions and to
support using free variables in these inner functions (that is also has
only "downward funargs"), but doesn't support "upward funargs", i.e.
escaping the function to the outside. While it's so, closures are easily
emulated/implemented via technique which is called a "lambda lifting" --
when inner function become global function with augmented formal
parameters set.

Dmitry.
 
V

VK

"static" in C means "a variable that has been allocated statically —
whose lifetime extends across the entire run of the program"
"static" in Java means "a property or method appertaining to class
itself and not to class instances"
"Static" in Visual Basic / VBA means "a function or sub that retains
its internal state between calls"
Now let's make a global definition "what does static mean In The
Programming" and we will get the same eclectic nonsense so far
demonstrated in this thread.

Let's make slow step by step:

1) We don't dive a damn what "closure" would mean in C, C++, Java,
Perl, PHP and ad infinitum. We only care what "closure" means in any
ECMA-262 compatible implementation of the programming language here
and further conventionally referred as "Javascript" (with only first
letter capitalized).

2) In Javascript "a closure" is a function with its internal call
state fully retained even after the execution of that function is
ended. It can be achieved by using "an inner function". Inner
functions are *not* closures and they do not automatically create
closures with outer functions. Yet inner functions is the instrument
to form closures in Javascript if such programmatic decision is made
by the programmer.

/////////////////
// Not a closure:

function outer() {

return inner('Hello');

function inner(x) {
return x + ' World!';
}

}

window.alert(outer()); // "Hello World!"
/////////////////


/////////////////
// A closure:

function outer() {

var x = 'foobar';

return inner;

function inner() {
return x;
}

}

var myClosure = outer();

window.alert(myClosure); // 'foobar'
/////////////////

So the key points of Javascript closures are:
a) the outer function execution context is fully retained even after
exiting the outer function
b) the inner function is the only gates to access in any way the
retained context
c) the retained context exists and garbage collection exempted until
at least one reference to the inner function exists.

This definition differs from other programming languages. For instance
in Perl a closure is any state of things when one sub contains another
sub and they are using each other. See for instance "Perl Cookbook" by
Tom Christiansen, Nathan Torkington, the chapter "10.16 Nesting
Subroutines". So in some languages "a closure" may equal to "nested
functions". This is why it is important to remember the step 1 at the
beginning and what we do give a damn and what we don't.

3) The "founding fathers" of CC scoping were rather unclear with their
definition of closure. Most importantly the key point (a) from above
is fully escaped from their attention. They are concentrated on one
particular outcome of (a)+(b): the possibility of a restricted access
to variables of the outer function.

Douglas Crockford
http://www.crockford.com/javascript/private.html
"... JavaScript has closures. What this means is that an inner
function always has access to the vars and parameters of its outer
function, even after the outer function has returned."

Richard Cornford
http://classic-web.archive.org/web/...totes.demon.co.uk/js_info/private_static.html
"It is possible to form a closure that included the class constructor
and local variables that would server as private class members by
making a one-off inline function ..."

Back in 2006 I asked Richard Cornford if it was the original
underestimate of the daemon they are calling or it was a conscious
decision with benefits - as they saw it - well overcoming any possible
drawbacks. I understand that the latter, see his answer at "Function
declaration inside other function" tread:
http://groups.google.com/group/comp.lang.javascript/msg/b44b1b7d902a124a

4) Till rather recently CC scoping was easy to bypass on Gecko
platforms by using non-standard __parent__ function property. It was
finally removed only in the last year:
http://whereswalden.com/2010/05/07/...special-__parent__-property-has-been-removed/
Until then one could access the outer activation object and its
variable by addressing innerFunctionReference.__parent__.whateverINeed
The exception was made for variables with names starting with
underscore: _likeThis. Such variables would not be visible to
__parent__. This is what David Mark mentioned as a "story of one
clueless programmer". It was much fun to read it to see the "broken
telephone game" in action :)

Now after we have figured out what closures are in Javascript we can
actually start answering OP's question. Is it a closure? No, because a
DOM object is not a function and there is not activation object to
retain. Can it form a circular reference or other garbage collection
troubles in some version of some browser? A careful investigation
needed.
 
L

Lasse Reichstein Nielsen

VK said:
"static" in C means "a variable that has been allocated statically —
whose lifetime extends across the entire run of the program"
"static" in Java means "a property or method appertaining to class
itself and not to class instances"
"Static" in Visual Basic / VBA means "a function or sub that retains
its internal state between calls"
Now let's make a global definition "what does static mean In The
Programming" and we will get the same eclectic nonsense so far
demonstrated in this thread.

Those definitions of "static" are in the language specifications
for those languages, and are reflected in the syntax by "static"
being a keyword. The language itself defines what it means.

The first two langauges are also statically typed. See:
http://en.wikipedia.org/wiki/Type_system#Static_typing
That's a different meaning of "static", meaning "at compile time".
I.e., even though the langauges define what "static" means, that
definition also limits what that meaning of "static" refers to.
It's perfectly reasonable to use other, more generic, meanings
if the word "static" about other features of the langauges.
Let's make slow step by step:

1) We don't dive a damn what "closure" would mean in C, C++, Java,
Perl, PHP and ad infinitum. We only care what "closure" means in any
ECMA-262 compatible implementation of the programming language here
and further conventionally referred as "Javascript" (with only first
letter capitalized).

In that case, there is no formal *definition* of the word "closure" in
the ECMAScript specification.
There are uses of it, though, as names in algorithms.
See, e.g., the meaning of the
PropertyAssignment : get PropertyName () { FunctionBody }
production. In that, "closure" is the name of the result of creating
a function object. That function object is assigned as a getter on
an object, but it doesn't have to leave its defining scope.
So, a function object is being considered a "closure" by the
specification writers at the point it's created.

The same goes for setter properties and function expression.

It's also used internally in the RegExp matcher specification, but
that's purely internal. It's use is consistent with the internal
procedure being a closure at the time it's created, though.

I.e., it's safe to say that the writers of the ECMAScript
specification considers all function objects as being closures.
2) In Javascript "a closure" is a function with its internal call
state fully retained even after the execution of that function is
ended. It can be achieved by using "an inner function". Inner
functions are *not* closures and they do not automatically create
closures with outer functions. Yet inner functions is the instrument
to form closures in Javascript if such programmatic decision is made
by the programmer.

Since there is no official definition of "closure", it's possible for
different people to assign different meanings to the word.

I can see that the meaning above is being used by some Javascript
writers. However, other people use the more general meaning where
being a closure is a property of the value generated by a function
expression (e.g., the FAQ). This is also the meaning generally used in
computer science. What you describe above is the the act of
*returning* a closure - which *is* one of the most interesting use
cases of closures, and where it really becomes obvious that a closure
is not just a function pointer.

---
Douglas Crockford
http://www.crockford.com/javascript/private.html
"... JavaScript has closures. What this means is that an inner
function always has access to the vars and parameters of its outer
function, even after the outer function has returned."

So when he says "even after", it must mean that it's also true before.
I.e., it's a closure before.
Richard Cornford
http://classic-web.archive.org/web/...totes.demon.co.uk/js_info/private_static.html
"It is possible to form a closure that included the class constructor
and local variables that would server as private class members by
making a one-off inline function ..."

I agree that this seems to be using the word "closure" for the
captured scope, not the function objects.
Back in 2006 I asked Richard Cornford if it was the original
underestimate of the daemon they are calling or it was a conscious
decision with benefits - as they saw it - well overcoming any possible
drawbacks. I understand that the latter, see his answer at "Function
declaration inside other function" tread:
http://groups.google.com/group/comp.lang.javascript/msg/b44b1b7d902a124a

And here he uses it in the same way.
I.e., he uses "closure" in a third way, rather than as one of the two
you gave above. Let's add to the confusion :)
4) Till rather recently CC scoping was easy to bypass on Gecko
platforms by using non-standard __parent__ function property. It was
finally removed only in the last year:
http://whereswalden.com/2010/05/07/...special-__parent__-property-has-been-removed/
Until then one could access the outer activation object and its
variable by addressing innerFunctionReference.__parent__.whateverINeed
The exception was made for variables with names starting with
underscore: _likeThis. Such variables would not be visible to
__parent__. This is what David Mark mentioned as a "story of one
clueless programmer". It was much fun to read it to see the "broken
telephone game" in action :)

Now after we have figured out what closures are in Javascript

Obviosuly we haven't agreed on that yet.
we can actually start answering OP's question. Is it a closure? No,

I say yes.
because a DOM object is not a function and there is not activation
object to retain. Can it form a circular reference or other garbage
collection troubles in some version of some browser? A careful
investigation needed.

It shouldn't.

/L
 
D

Dmitry A. Soshnikov

I say yes.

And I said yes.

P.S.: Actually, sorry, this discussion becomes noisy and less technical.
To understand what is closure an interested person (whoever it is)
should consider the general theory of programming languages and their
interpretation. Then we'll see that JS's implementation is completely
apparent with the PLT. Once again -- the main topic to look is "static
scope", though, as was shown there are some cases when there's static
scope and there's no closure -- e.g. C's global functions, so the most
accurate pattern to search is "first-class functions + lexical scope +
nested functions". Once we have the combination -- functions are closures.

Also a good way to understand what is closure is e.g. to implement a
language which supports closures. I did. My toy Scheme implementation --
"SchemeOnCoffee", a language with first-class functions and all of the
are closures as "pairs of a code and a reference to lexical (parent)
environment". For the info: http://dmitrysoshnikov.com/scheme-on-coffee/

P.S.[2]: once again (to conclude), the most interesting and the most
practical view of a closure is an "upward funarg" with free variables.
If only practical view is interesting, then the interested person can
stop right here on understanding closure. Though, more interested person
may also consider "downward funarg" where free variables are searched in
the saved (_closured_) environment and not in the scope of the caller.

Dmitry.
 
V

VK

In that case, there is no formal *definition* of the word "closure" in
the ECMAScript specification.

Right. How would it be in there if the first ideas of the CC Scoping
(CC Scope Management, "CC" any further in this post) appeared only in
2001? This is why any references to the English word "closure" used in
any ECMA-262 docs are irrelevant to the topic. With the same success
one could refer to philosophical works ( http://en.wikipedia.org/wiki/Closure_(philosophy)
) or anything else with the word "closure" in it.
Brendan Eich himself didn't think about any "closures" when making
JavaScript. All he wanted was to allow nested functions: so to extra
organize blocks of code inside a functions which would be too long and/
or repetitive - yet too specific to a particular function to make them
global.
"Client-Side JavaScript Reference"
nested (inner) function
http://download.oracle.com/docs/cd/E19957-01/816-6408-10/function.htm
There are uses of it, though, as names in algorithms.
See, e.g., the meaning of the
 PropertyAssignment : get PropertyName () { FunctionBody }

Irrelevant to the topic as I said before.

If something was not known and then discovered or popularized or made
practical to use then the right to name the entity appertains
exclusively and undoubtedly to the person(s) who produced the entity.
Not to myself, not to you, not to Mr. Soshnikov, not even to the most
super-duper reputable JavaScript specialist, not even to the most
super-duper-mupper reputable SC specialist. It is obvious and strange
that I have to explain it.

Since there is no official definition of "closure", it's possible for
different people to assign different meanings to the word.

It's not possible. I mean sure, ""Who can stop Hafiz from likening a
ladybug to the Padishah" and who can stop say VK from calling a
function object "a thingy" :) But seriously one just need to read the
relevant papers and use the term as defined in there. Or do not use
CC. Or to invent something else and to call any way one likes.
The papers are:

"Private Members in JavaScript" (2001)
http://www.crockford.com/javascript/private.html

"Private Static Members in JavaScript" (2003)
http://classic-web.archive.org/web/...otes.demon..co.uk/js_info/private_static.html

"closures, what are they good for?" (clj thread of 2003)
http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/793cd655ad56fe91

From the newest not authoritative as above but useful sources there
are:

"Closure Versus Prototypal Pattern Deathmatch" audio-interview of
Brendan Eich
http://www.aminutewithbrendan.com/pages/20110216

"Closures in JavaScript" ("AJAX in Action: Appendix B - JavaScript
for Object-Oriented Programmers")
http://developers.sun.com/scripting/javascript/ajaxinaction/Ajax_in_Action_ApB.html

So when he says "even after", it must mean that it's also true before.
I.e., it's a closure before.

Please, don't play on words - this is the Thomas' job :)

Closure: "an inner function always has access to the vars and
parameters of its outer function, even after the outer function has
returned". So the state of closure appears when:
a) outer function has returned
b) inner function still has access to the activation object of the
outer function.

Before the outer function has returned the inner function just nested
(inner) function as it was documented since JavaScript 1.0
I agree that this seems to be using the word "closure" for the
captured scope, not the function objects.

No, again: the closure in Javascript is not the captured scope
(activation object) and it is not the returned inner function
reference. It is the whole effect of preserving inner function
reference and as the result having exclusively accessed captured scope
of the outer function. This all together is Javascript closure. I
propose you to read the linked docs, listen Brendan Eich and find
anything sustaining any other definition or understanding of
Javascript closure.
 
V

VK

P.S.[2]: once again (to conclude), the most interesting and the most
practical view of a closure is an "upward funarg" with free variables.
If only practical view is interesting, then the interested person can
stop right here on understanding closure.

To understand Javascript closure and CC scoping one needs to read the
original papers explaining and naming the technology. These papers a
linked in my post to Mr. Nielsen. Anything else is either irrelevant
or lesser relevant.

"an "upward funarg" with free variables"... Here Javascript
programming group, not a SC Theory group, really.
 
L

Lasse Reichstein Nielsen

VK said:
Right. How would it be in there if the first ideas of the CC Scoping
(CC Scope Management, "CC" any further in this post) appeared only in
2001? This is why any references to the English word "closure" used in
any ECMA-262 docs are irrelevant to the topic. With the same success
one could refer to philosophical works ( http://en.wikipedia.org/wiki/Closure_(philosophy)
) or anything else with the word "closure" in it.

I've had to look up what "CC" actually means in this case. I take it it's
the name you invented to mean Crockford-Cornford?

Looking at their writing, I don't think it says what you think it
says.
Crockford is using the word "closure" for the act of closing over
something (i.e., derived from the verb "TO close"), and not the result
of doing that closing (the closed functions, what is typically called
"*a* closure").

Cornford seems to use "a closure" to refer to the static scope created
by the surrounding function (at least in the link you gave).
Brendan Eich himself didn't think about any "closures" when making
JavaScript. All he wanted was to allow nested functions: so to extra
organize blocks of code inside a functions which would be too long and/
or repetitive - yet too specific to a particular function to make them
global.
"Client-Side JavaScript Reference"
nested (inner) function
http://download.oracle.com/docs/cd/E19957-01/816-6408-10/function.htm

On the other hand, BE was heavily influenced by Scheme, where all
functions (lambdas) are also closures. I wouldn't begin to guess
about what he was thinking.
And so is Crockford, by the way (q.v. his reference to The Little
Schemer).
If something was not known and then discovered or popularized or made
practical to use then the right to name the entity appertains
exclusively and undoubtedly to the person(s) who produced the entity.

What Crockford and Cornford have popularized is the usage of local scope
to emulate private properties of objcets. That's what's being called the
"closure method". It is more restrictive than the usage you advocate,
where it means returning a closure (or, if you prefer, a function with
access to its defining environment).
Not to myself, not to you, not to Mr. Soshnikov, not even to the most
super-duper reputable JavaScript specialist, not even to the most
super-duper-mupper reputable SC specialist. It is obvious and strange
that I have to explain it.

Perhaps I don't agree with your interpretation of what has been named
and popularized.
It's not possible. I mean sure, ""Who can stop Hafiz from likening a
ladybug to the Padishah" and who can stop say VK from calling a
function object "a thingy" :) But seriously one just need to read the
relevant papers and use the term as defined in there. Or do not use
CC. Or to invent something else and to call any way one likes.
The papers are:

"Private Members in JavaScript" (2001)
http://www.crockford.com/javascript/private.html

Uses "closure" about the act of closing.

Uses "a closure" about the returned constructor function.

You might notice that I was writing in that thread, saying exactly
what I'm saying now, and, e.g., Cornford references my posting without
disagreeing with what I said.
I.e., you might want to reconsider your interpretation of what's being
said in that thread.
From the newest not authoritative as above but useful sources there
are:

"Closure Versus Prototypal Pattern Deathmatch" audio-interview of
Brendan Eich
http://www.aminutewithbrendan.com/pages/20110216

They seem to be talking about the use of closures in emulating
private properties. In that context, it's a distinction between
"prototypical inheritance" and "using closures". It's not trying
to say that it's the only use of closures.
"Closures in JavaScript" ("AJAX in Action: Appendix B - JavaScript
for Object-Oriented Programmers")
http://developers.sun.com/scripting/javascript/ajaxinaction/Ajax_in_Action_ApB.html

I'll just disagree with their usage.
<snip>

Please, don't play on words - this is the Thomas' job :)

Someone has to, since you seem to be ignoring the word "even".
Closure: "an inner function always has access to the vars and
parameters of its outer function, even after the outer function has
returned". So the state of closure appears when:
a) outer function has returned
b) inner function still has access to the activation object of the
outer function.

I don't agree with your conclusion. I read the same thing and have
no problem seeing an inner function as always being a closure, also
before it's returned. The "even" is significant. Why else would
it be there?
Before the outer function has returned the inner function just nested
(inner) function as it was documented since JavaScript 1.0

All function objects in Javascript are closures. Even inner functions.
That's why you can return them.
No, again: the closure in Javascript is not the captured scope
(activation object)

True, I misread. He is actually talking about the returned constructor
function as the closure.
and it is not the returned inner function
reference.

Actually, it is.
It is the whole effect of preserving inner function
reference and as the result having exclusively accessed captured scope
of the outer function. This all together is Javascript closure. I
propose you to read the linked docs, listen Brendan Eich and find
anything sustaining any other definition or understanding of
Javascript closure.

I have (well, not listened to BE, but I'll read the transcript).
I still think someone is misunderstanding the generality of the
concept, and it's not the people being quoted, because I'm sure
they do know that they are talking about a special use-case
for closures.

/L
 
D

Dmitry A. Soshnikov

P.S.[2]: once again (to conclude), the most interesting and the most
practical view of a closure is an "upward funarg" with free variables.
If only practical view is interesting, then the interested person can
stop right here on understanding closure.

To understand Javascript closure and CC scoping one needs to read the
original papers explaining and naming the technology. These papers a
linked in my post to Mr. Nielsen. Anything else is either irrelevant
or lesser relevant.

Original paper is Lisp design -- when they have fixed dynamic scope.
"an "upward funarg" with free variables"... Here Javascript
programming group, not a SC Theory group, really.

Oh, sorry, then I leave you alone with your guesses ;)

I explained what closure is, without guessing. But I can't insist on
passing the knowledge, if you don't want to understand, it's completely
your right.

Dmitry.
 
D

Dmitry A. Soshnikov

P.S.[2]: once again (to conclude), the most interesting and the most
practical view of a closure is an "upward funarg" with free variables.
If only practical view is interesting, then the interested person can
stop right here on understanding closure.

To understand Javascript closure and CC scoping one needs to read the
original papers explaining and naming the technology. These papers a
linked in my post to Mr. Nielsen. Anything else is either irrelevant
or lesser relevant.

Original paper is Lisp design -- when they have fixed dynamic scope.

Moreover, original paper is lambda calculus (and the math in general).
Lisp is just an (approximated) implementation of lambda calculus. And JS
is the same as Lisp in this respect.
 
J

John G Harris

All function objects in Javascript are closures. Even inner functions.
<snip>

If all function objects were closures then the following program would
work:

<script type="text/javascript">
a = 42;

function f()
{ alert(a); }

delete a;
f();
</script>

But it doesn't, it says error (at least in an uptodate IE8).

In other languages with closures either there are no global variables or
they're accessible everywhere, always, so there is no need for a special
mechanism to capture the globals used by a function.

ECMAScript is different, as usual. Some kinds of global variable can be
deleted and so ought to be preserved by closures.

Thus, either top-level function declarations do not form closures, or
they're always empty closures. The latter description is rather perverse
I think.

John
 
L

Lasse Reichstein Nielsen

John G Harris said:
<snip>

If all function objects were closures then the following program would
work:

<script type="text/javascript">
a = 42;

function f()
{ alert(a); }

delete a;
f();
</script>

But it doesn't, it says error (at least in an uptodate IE8).

No, it works, exactly as you wrote it.

I usually describe a closure as code combined with an environment
binding the free variables of the code. The variables will be looked
up in that environment when the code is executed.

You have shown (and it is an interesting point) that environments in
Javascript are mutable. The environment can even stop having a binding
for the free variable (just as it could have omitted having one from
the start). The variable is still looked up in that environment, and
exactly because of that, it will now fail to find a binding.

In other languages with closures either there are no global variables or
they're accessible everywhere, always, so there is no need for a special
mechanism to capture the globals used by a function.

More importantly, in other languages you can't unbind a variable that
already exists. That is what happens here.
ECMAScript is different, as usual. Some kinds of global variable can be
deleted and so ought to be preserved by closures.

I disagree. In another language, that might be what I wanted, but in
Javascript, it would definitly not be proper. The closure maintains
the scope chain that binds the free variables of the function. Any
change to that scope chain should be reflected in the variable lookup
when the function is executed.

Extreme example:

(function scope() {
var geta;
var o = {};
with (o) {
geta = function geta() { return a; };
}
try {
geta();
} catch (e) {
alert("no a"); // no a
}
a = "outer";
alert(geta()); // outer
eval("var a = 'inner';");
alert(geta()); // inner
o.a = "with";
alert(geta()); // with
delete o.a;
delete a;
delete a;
try {
geta();
} catch (e) {
alert("no a"); // no a
}
})();

It's sick and demented, but it's Javascript :)

It was never a good idea to put mutable objects into the scope chain,
and they are working on dropping that again with Harmony.
Thus, either top-level function declarations do not form closures, or
they're always empty closures. The latter description is rather perverse
I think.

They are closures that keep the scope chain, not the individual
variable bindings. And it's exactly the same as the closures of nested
functions.

/L
 
R

Ry Nohryb

(...) The closure maintains
the scope chain that binds the free variables of the function. Any
change to that scope chain should be reflected in the variable lookup
when the function is executed.

Extreme example:

(function scope() {
  var geta;
  var o = {};
  with (o) {
    geta = function geta() { return a; };
  }
  try {
    geta();
  } catch (e) {
    alert("no a"); // no a
  }
  a = "outer";
  alert(geta()); // outer
  eval("var a = 'inner';");
  alert(geta()); // inner
  o.a = "with";
  alert(geta()); // with
  delete o.a;
  delete a;
  delete a;
  try {
    geta();
  } catch (e) {
    alert("no a");  // no a
  }

})();

It's sick and demented, but it's Javascript :)

It's marvelous :p
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top