Confusion about closures

R

RobG

I've seen many comments that the following creates a closure:

var firstNameValue = (function(elementId) {
var firstName = document.getElementById(elementId);
return firstName.value;
})("firstName");

I just don't see it. There is only one function, an anonymous
function, and it only has access to its own and global variables. It
gets a reference to a DOM element and returns the string value of one
of its properties. Then the function ends, there is nothing
referencing it and it has no references to variables in its outer
scope.

The only thing it references outside its scope is a solitary DOM
element. Is the inference that because IE makes element ids into
global variables that somehow creating a reference within the
anonymous function creates a closure? If that is true, then *every*
function that gets an element reference using getElementById creates a
closure every time it's called.

Can someone enlighten me?
 
L

Lasse Reichstein Nielsen

RobG said:
I've seen many comments that the following creates a closure:

var firstNameValue = (function(elementId) {
var firstName = document.getElementById(elementId);
return firstName.value;
})("firstName");

I just don't see it. There is only one function, an anonymous
function, and it only has access to its own and global variables. It
gets a reference to a DOM element and returns the string value of one
of its properties. Then the function ends, there is nothing
referencing it and it has no references to variables in its outer
scope.

It still creates the function object before calling it (according
to the specification, some engines might optimize it away ofcourse).
The function object is called a closure.

In this case it's almost a trivial closure, since it has no free
variables except "document" (a global variable), so the environment
it's closing over is indistinguishable from the global object (unless
there's something you are not showing us).

So, it's technically correct, but possibly a little misguided, to
focus on the closure in this case.
The only thing it references outside its scope is a solitary DOM
element. Is the inference that because IE makes element ids into
global variables that somehow creating a reference within the
anonymous function creates a closure?

Probably not.
If that is true, then *every* function that gets an element
reference using getElementById creates a closure every time it's
called.

Can someone enlighten me?

You are thinking too hard :)
It's not deep, but every function object in Javascript is a closure,
so trivially this code creates a closure[1].

/L
[1] In this case, for absolutely no reason.
 
A

Asen Bozhilov

RobG said:
  var firstNameValue = (function(elementId) {
    var firstName = document.getElementById(elementId);
    return firstName.value;
  })("firstName");

Lasse has answered on your question, but just for a record, this code
could and should be rewritten as:

var firstNameValue = document.getElementById("firstName").value;

From where you get this code? I guess you have written that example
only for your question and such a code does not exist in the
productions.
 
D

David Mark

It still creates the function object before calling it (according
to the specification, some engines might optimize it away ofcourse).
The function object is called a closure.

That's an odd oversimplification.

In my book, there's no closure formed here. It's simply a one-off
function creation/call.

ISTM that the classification of closures (or non-closures) has been
discussed here recently and the consensus was not that Function
objects are closures, but that closures are created by functions under
very specific circumstances (and the current example falls way short).

I mean, why even have the term if it is meaningless (e.g. adds nothing
to "function object")?
 
R

RobG

Lasse has answered on your question,

I think David's comments are relevant too. While it might be said that
technically there is a closure for some immeasurably short time, it
trivialises the term to the point of irrelevance.

but just for a record, this code
could and should be rewritten as:

var firstNameValue = document.getElementById("firstName").value;

From where you get this code? I guess you have written that example
only for your question and such a code does not exist in the
productions.

It was apparently shown as a question asked in a recruiting interview.
I'm torn between thinking it's a dumb question - because there is no
closure worth discussing and no memory leak as far as I can tell - or
a very smart one because the applicant should say "There is no memory
leak or closure (or at least nothing worth calling a closure), but
hey, what a needlessly complex piece of code!!".
 
R

RobG

ISTM that the classification of closures (or non-closures) has been
discussed here recently and the consensus was not that Function
objects are closures, but that closures are created by functions under
very specific circumstances (and the current example falls way short).

Are you talking about this thread:

"How to understand this form (something) (param);"
<URL: https://groups.google.com/group/com...339c7/5c83ec5f14b3cfc9?hl=en#5c83ec5f14b3cfc9
Or some other thread?
 
L

Lasse Reichstein Nielsen

David Mark said:
Not sure (don't have time to wade through that one). But, in a
nutshell, if there is nothing *preserved* once the function exits,
then there is no closure.

I'll just have to disagree on that definition.

The closure is the combination of function code and an environment
binding its free variables.

The closure created whether or not the the function leaves its
defining scope, but whether it's a closure or not is only really
relevant in the case where it does leave. That's the case that
distinguishes static and dynamic scopes. Closures are essential
to a language with first-class functions and static scope.

So yes, in Javascript all function objects are closures. It might
make "closure" an irrelevant word, but it does make a difference,
distinguishing Javascript from languages without closures.

/L
 
D

David Mark

I'll just have to disagree on that definition.  

Gentlemen can differ. :)
The closure is the combination of function code and an environment
binding its free variables.
Yes.


The closure created whether or not the the function leaves its
defining scope, but whether it's a closure or not is only really
relevant in the case where it does leave.
Right.

That's the case that
distinguishes static and dynamic scopes. Closures are essential
to a language with first-class functions and static scope.

I think we are drifting a bit.
So yes, in Javascript all function objects are closures.

All Function objects are objects as well. They are also functions.
Closures are neither.
It might
make "closure" an irrelevant word, but it does make a difference,
distinguishing Javascript from languages without closures.

But "closure" cannot be an irrelevant word for those using (and
especially those learning) JS. If it is, they have no way to
understand or express patterns that rely on closures (let alone
understand how closures can cause IE to leak memory). ISTM that's why
there is a long FAQ entry on the subject (which you contributed to).

And this is not a trivial issue. I've met plenty of JS "experts" who
didn't understand what "scope" meant, because they were so used to
reading blogs and forum posts using the word incorrectly (e.g. to mean
"this object"). Same for how inheritance works in JS, because they
read so many articles referring to "classes" and "singletons". And I
remember recently discussing "private" members and having a guy get
mixed up about the "_" prefix. Yes, they actually thought such
prefixed properties were private (and actually brought up the term
"scope" in an attempt to explain). You can't program in a language
you don't understand.

So dumb the concept down if you wish, but I don't think it promotes
the understanding of closures.
 
S

Scott Sauyet

RobG wrote:
| var firstNameValue = (function(elementId) {
|     var firstName = document.getElementById(elementId);
|     return firstName.value;
|   })("firstName");
It was apparently shown as a question asked in a recruiting interview.
I'm torn between thinking it's a dumb question - because there is no
closure worth discussing and no memory leak as far as I can tell - or
a very smart one because the applicant should say "There is no memory
leak or closure (or at least nothing worth calling a closure), but
hey, what a needlessly complex piece of code!!".

It would be an excellent question if the interviewer is using it to
probe the candidate's depths of knowledge of closures, something to
prompt discussion. It would be a terrible question if meant as a
quick-answer screening question, for precisely the reasons that you
brought it forward here. I try to use questions like this in face-to-
face interviews with candidates who clearly know how to answer the
over-the-phone screening questions. I always explain (after we've
discussed it thoroughly) that I don't necessarily think there's a
right answer to the question but that I wanted to see how they think.
These are often the ones that help me decide between candidates
otherwise equally qualified.

-- Scott
 
D

Dmitry A. Soshnikov

I think we are drifting a bit.

It's the most relevant thing though and no drifting. "The problem of a
function argument" or the "Funarg problem" is actually the problem of
lexical environments and therefore the problem of the static scope.

Concept of a static scope -- that's the main thing related to the
concept of a closure. Once you understand the static scope, the closure
is just a consequence.

So JS has static scope (as most of the today languages) and therefore --
complete support of closures which are presented there as _all
functions_. So again, _all functions_ in JS, being statically scoped,
are closures. It can be proved with the "downwards funarg":

var x = 10;

function foo() {
console.log(x);
}

(function (funArg) {
var x = 20;
funArg(); // 10 in static scope (closure), 20 in dynamic!
})(foo)

The `foo` saved its lexical environment which in other words it's a
closure -- a combination of the code and the surrounding lexical
environment.

The most popular though view of closures (which is incompletely treated
as only closures) is "upward funargs" -- when a function uses free
variables from the contexts which finishes. But the _techniques_ of this
is absolutely the same as for the "downward funarg" shown above. Notice,
variable `x` is also free for `foo` function.
All Function objects are objects as well. They are also functions.
Closures are neither.

It should be clear after explanation above that all functions are
closures in JS. Because in other languages there are and closures and
also non-closures, i.e. functions which are dynamically scoped, not
statically scoped. In JS, repeat, all functions are statically scoped.
And when we use concept of static scope, we automatically assumes closures.

Info:

http://dmitrysoshnikov.com/ecmascript/es5-chapter-3-1-lexical-environments-common-theory/
(a must read for every interested in the theory of closures more than
just a "cool thing in JS -- to return inner function" or limited
interesting on understanding closures only by reading ES spec -- it's
not enough).

http://dmitrysoshnikov.com/ecmascript/chapter-6-closures/ (also closures
from the theoretical viewpoint of the common theory).

P.S.: another thing is allocation of non-used parent bindings. JS uses
model of the "chained environment frames"
(http://dmitrysoshnikov.com/ecmascri...ments-common-theory/#environment-frames-model),
whereas also exists the model of the "combined environment frame"
(http://dmitrysoshnikov.com/ecmascri...mmon-theory/#combined-environment-frame-model).

This means that regardless the standard (which states that a complete
parent frame is saved in the [[Scope]]) implementations may not
allocated non-used parent bindings on heap. E.g. in V8 only used
(captured by a closure) bindings are heap-allocated; other are just
stack-allocated.

Dmitry.
 
D

David Mark

It's the most relevant thing though and no drifting. "The problem of a
function argument" or the "Funarg problem" is actually the problem of
lexical environments and therefore the problem of the static scope.

There's not a chance in hell that the typical questioner of closures
(they show up often) will be enlightened by such a barrage of
technical verbiage. Perhaps just post the link to the FAQ entry on
the subject.
Concept of a static scope -- that's the main thing related to the
concept of a closure. Once you understand the static scope, the closure
is just a consequence.

If you don't know what a closure is, you likely don't know what a
static scope is either. I think it's easier to learn the former.
So JS has static scope (as most of the today languages) and therefore --

It is not set apart as such. :)
complete support of closures which are presented there as _all
functions_. So again, _all functions_ in JS, being statically scoped,
are closures.

By your definition.
It can be proved with the "downwards funarg":

You can't prove such semantic arguments one way or another.
var x = 10;

function foo() {
   console.log(x);

}

(function (funArg) {
   var x = 20;
   funArg(); // 10 in static scope (closure), 20 in dynamic!

})(foo)

The `foo` saved its lexical environment which in other words it's a
closure --

I think that's the wrong term. You have an execution context that is
created on calling the function. That includes the usual trappings of
a Variable (AKA Activation) object, assigned scope chain, etc. A
closure is formed if, on exiting the function, these trappings are
*preserved* (due to there being an external reference).

The rest of it, though it may be technically valid, is inappropriate
for most programming discussions (implementers may be interested).
 
D

Dmitry A. Soshnikov

I've seen many comments that the following creates a closure:

var firstNameValue = (function(elementId) {
var firstName = document.getElementById(elementId);
return firstName.value;
})("firstName");

I just don't see it. There is only one function, an anonymous
function, and it only has access to its own and global variables. It
gets a reference to a DOM element and returns the string value of one
of its properties. Then the function ends, there is nothing
referencing it and it has no references to variables in its outer
scope.

Via saved (closured) lexical environment a function finds its free
variables. Here the anonymous function should lookup e.g. `document`
name which is _free_ (i.e. it's not a local variable, nor a formal
parameter). And exactly for searching free variables the saved
environment is used. And the combination of a function code and its
environment is a closure. Technically all functions in JS are closures.

However, as was mentioned in my previous letter, the most interesting
case of the lexical environments' (and static scope's in general) work
is a so-called "upwards funarg" where a (inner) function is returned
(upwards) and uses free variables of the parent function. It's a
particular but the most widespread (and the most interesting) case of
closures, i.e. of the static scope.

So answering your question, yes, this anonymous immediately invoked
functional expression is a closure. But from the practical viewpoint
there's no so much interesting in exactly this kind of closure.

You'll find links I gave in my previous letter on the very detailed
explanation of closures.

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

Description of this case with `Function` functions you'll also find in
links I gave.

Dmitry.
 
L

Lasse Reichstein Nielsen

David Mark said:
On Apr 20, 2:01 pm, "Dmitry A. Soshnikov" <[email protected]>
wrote:

I think that's the wrong term. You have an execution context that is
created on calling the function. That includes the usual trappings of
a Variable (AKA Activation) object, assigned scope chain, etc. A
closure is formed if, on exiting the function, these trappings are
*preserved* (due to there being an external reference).

That's not the traditional usage of "closure". It really just is the
code combined with an environment binding the free variables. There's
no requirement that the closure must survive the scope it was created
in, it's a closure from the moment it's created.

If you check the Wikipedia entry:
http://en.wikipedia.org/wiki/Closure_(computer_science)
they also mention closures used to implement continuation passing style.
In continuation passing style, there is no return, so the closure is never
returned from its creating scope.
The rest of it, though it may be technically valid, is inappropriate
for most programming discussions (implementers may be interested).

I don't think programming discussions are improved by using inaccurate
meanings for existing technical words. People tend to pick up half
meanings when they first see a single example of a general case [1].
If they keep seeing only that example, they will think that the general
name only refers to that particular case. Let's fix the misunderstanding
instead of encourging it.

/L
[1] E.g., the "?:" operator isn't named the "ternary operator" in C.
 
D

David Mark

That's not the traditional usage of "closure".

It is the usage of "closure" in the context of the JS language. As
written, it could hardly apply to other languages. (?)
It really just is the
code combined with an environment binding the free variables. There's
no requirement that the closure must survive the scope it was created
in, it's a closure from the moment it's created.

You are describing a fleeting "closure" that is created and disappears
immediately. What possible use is that? And how would you
differentiate such "closures" from those that are actually useful?

That's a general definition.
they also mention closures used to implement continuation passing style.
In continuation passing style, there is no return, so the closure is never
returned from its creating scope.

So what? Aren't we talking about JS? :)
I don't think programming discussions are improved by using inaccurate
meanings for existing technical words.

It really depends. If you cite the DOM specs, properties are
"attributes". And look how much grief has been caused by such mix-
ups. :)
People tend to pick up half
meanings when they first see a single example of a general case [1].
If they keep seeing only that example, they will think that the general
name only refers to that particular case. Let's fix the misunderstanding
instead of encourging it.

I am only concerned with closures in JS. If you start telling people
that JS closures are the same as function objects, they'll never
understand how to use them. I mean, what is it you would call that
"special" case where a closure is actually preserved on exit?
 
J

John G Harris

I am only concerned with closures in JS. If you start telling people
that JS closures are the same as function objects, they'll never
understand how to use them. I mean, what is it you would call that
"special" case where a closure is actually preserved on exit?

How about 'non-trivial closure' for the special case? The term to be
used once at the start of the discussion and shortened to 'closure'
thereafter.

John
 
L

Lasse Reichstein Nielsen

David Mark said:
You are describing a fleeting "closure" that is created and disappears
immediately. What possible use is that? And how would you
differentiate such "closures" from those that are actually useful?

Describe the use, not just the part of it that is the function.
In Javascript, functions can escape from and survive longer than
the scope in which thy are created. The binding of their free
variables is preserved, even if those variables were defined in
the scope that has now been exited.
It works like that because function object in Javascript are closures.
That's a general definition.

And I would be silly for Javascript to have a different definition,
when the general definition still works, and is indeed why the word
closure was used about Javascript to begin with.

I.e., someone used the word "closure" to describe the behavior of
scope escaping functions. Someone (else, probably) thought that
that "closure" was just describing this particular case, and wasn't
just a special case of a more general concept. Other people picked
up on just the latter usage, and here we are with people advocating
that the latter, mistaken, usage should actually be used instead
of the correct one.
So what? Aren't we talking about JS? :)

You can write continuation passing style code in Javascript it you wan't.
You'll probably be bitten by the lack of proper tail-calls.
And again, I don't think it's a good idea to use a different meaning of
"closure" for Javascript than the traditional one.
It really depends. If you cite the DOM specs, properties are
"attributes". And look how much grief has been caused by such mix-
ups. :)

Actyually, no. The ECMAScript binding uses the word "properties" about
the object properties. Attributes is what HTML has. The HTML attributes
are implemented in ECMAScrit using properties and methods.
From the DOM 2 HTML ECMAScript binding:
---
Properties of objects that implement the HTMLDocument interface:
title
This property is a String.
referrer
This read-only property is a String.
---
<http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html>

In this case the "title" property of an HTMLDocument object reflects
the "title" attribute of an HTML "document" element.
I am only concerned with closures in JS. If you start telling people
that JS closures are the same as function objects, they'll never
understand how to use them.

Please give people some credit. If you don't get hung up on the
word "closure", and just describe what is happening (which don't
need the technical term "closure"), then most people would get
it.
I mean, what is it you would call that
"special" case where a closure is actually preserved on exit?

It's /not/ special. It's just how Javascript functions work.
Describe the escaping, not the function object. That's the operative
part of that case. Function objects (all function objects) can escape
the scope where they were defined. When a function object is
created, it contains references to the variables in scope at the
point where it was created. It keeps these references and can access
those variables even after the scope has been exited.[1]

It works *because* all function objects in Javascript are what's
technically called "closures" - a combination of code and bindings
for the free variables (variables used but not declared) in the code.

/L
[1] Then you can start explaining how the binding of free variables
don't bind their value, but their "location", so creating several
functions in the same scope will have them all read the same variable.
That might actually be confusing for people who have experience with
other languages with first-class functions but no mutable variables.
 
D

David Mark

Describe the use, not just the part of it that is the function.
In Javascript, functions can escape from and survive longer than
the scope in which thy are created. The binding of their free
variables is preserved, even if those variables were defined in
the scope that has now been exited.
It works like that because function object in Javascript are closures.

Still, the "non-trivial closure" that John G Harris mentioned is what
has been traditionally referred to as a "closure" in JS.
And I would be silly for Javascript to have a different definition,
when the general definition still works, and is indeed why the word
closure was used about Javascript to begin with.

I.e., someone used the word "closure" to describe the behavior of
scope escaping functions. Someone (else, probably) thought that
that "closure" was just describing this particular case, and wasn't
just a special case of a more general concept. Other people picked
up on just the latter usage, and here we are with people advocating
that the latter, mistaken, usage should actually be used instead
of the correct one.

But it's too late to change it in the context of JS (at least without
causing massive confusion).
You can write continuation passing style code in Javascript it you wan't.
You'll probably be bitten by the lack of proper tail-calls.
And again, I don't think it's a good idea to use a different meaning of
"closure" for Javascript than the traditional one.


Actyually, no. The ECMAScript binding uses the word "properties" about
the object properties.

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.
Attributes is what HTML has. The HTML attributes
are implemented in ECMAScrit using properties and methods.


OMFG. No kidding? :)
 
D

David Mark

How about 'non-trivial closure' for the special case? The term to be
used once at the start of the discussion and shortened to 'closure'
thereafter.

I suppose. But nobody is going to buy it outside of this group (so I
don't know if the convention will help anything). Remember that most
of the JS world refers to "this object" as "scope". ;)
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top