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

Explanation of closures

2 views
Skip to first unread message

Richard Cornford

unread,
Mar 29, 2004, 12:25:42 AM3/29/04
to
I have just finished an page for inclusion in the notes on the FAQ that
is intended as an explanation of javascript closures (I realise that is
not really a subject that is frequently asked about but it hardly seems
to get a mention anywhere else):-

<URL: http://www.jibbering.com/faq/faq_notes/closures.html >

- and I would appreciate any reviews (technical or otherwise) anyone
cares to give it prior actually including it in the notes.

Richard.


Martin Honnen

unread,
Mar 29, 2004, 9:35:38 AM3/29/04
to

Richard Cornford wrote:

Typos/Grammar review:
1) In the section introduction, second paragraph

function definitions and function expression that are inside the
function bodes of other functions

should be

function definitions and function expressions that are inside the
function bodies of other functions

2) In the section accidental closures, first paragraph

javascript authors who do not appreciate closures as a language feature
can observer the use of inner functions

probably should be

javascript authors who do not appreciate closures as a language feature
can observe the use of inner functions

3)in the section accidental closures, second paragraph I don't
understand the sentence

It is not the closures themselves the impact of efficiency, indeed
carefully used they can contribute significantly towards the creation of
efficient code.

maybe you want something alike

It is not the closures themselves but the impact on efficiency, indeed
carefully used they can contribute significantly towards the creation of
efficient code.

but I am not entirely sure whether you maybe don't want that "the impact
of efficiency" in that sentence at all, maybe you want it removed and
only mentioned in the following sentence:

It is not the closures themselves, indeed carefully used they can
contribute significantly towards the creation of efficient code. It is
the use of inner functions that can impact on efficiency.
--

Martin Honnen
http://JavaScript.FAQTs.com/

Yann-Erwan Perio

unread,
Mar 29, 2004, 2:39:02 PM3/29/04
to
Richard Cornford wrote:

> I have just finished an page for inclusion in the notes on the FAQ that
> is intended as an explanation of javascript closures

> <URL: http://www.jibbering.com/faq/faq_notes/closures.html >

I've read this thoroughly and AFAICS it's perfectly compliant with
ECMA262-3. I've therefore very few remarks to make, FWIW:
- "But all objects may have prototypes (...)", well they all _have_
prototypes;
- although you're saying that the distinction between the prototype
property and [[prototype]] is outside the scope[1] of the article, you
make such a detailed analysis of the prototype resolution (and a very
good one as well!) that I feel you should add a paragraph on this;
- while explaining the Variable Object, you could have insisted a bit
more on the declaration of variables being completely separated from
their initialization (they're treated like a function declaration);
- about how many objects are possible in the scope chain, I've just
tried but just succeeded in having Mozilla explode with 5000 objects, so
I guess it cannot be accurately calculated;
- the "associateObjWithEvent" pattern is excellent, I'll keep that at hand;
- some typos:
- "to Stirng" => "to String"
- "deceleration" => declaration
- "funciton" => function
- "contest" => context
- "palace" -> place

> (I realise that is
> not really a subject that is frequently asked about but it hardly seems
> to get a mention anywhere else)

Well, I wish I had read such an article 6 months ago, not only it's
clearly written and well structured, but it also provides an excellent
analysis, especially in regards of the scope resolution. People not
mentioning closures just means they don't know about it, so I'd urge you
to include your article in the FAQ notes, it's about not-that-well-known
although _essential_ aspects of javascript.

BTW, I've just read your article about using "with" to make private
static members (you're quite inspired there days), I think I'll
experiment a bit in my next posts, the idea is very interesting!


Cheers,
Yep.

[1] sorry I couldn't resist:-)

Dr John Stockton

unread,
Mar 29, 2004, 5:26:08 PM3/29/04
to
JRS: In article <c48c0n$edu$1$8302...@news.demon.co.uk>, seen in
news:comp.lang.javascript, Richard Cornford
<Ric...@litotes.demon.co.uk> posted at Mon, 29 Mar 2004 06:25:42 :


ISTM that a pre-processor for HTML drafts would be useful; one that
numbered every paragraph in numerical order regardless of text
structure.

In Introduction, ISTM that there should be an example of the simplest
possible closure, and one of the simplest useful closure, and more on
where they are useful. Is it still a closure if the internally defined
function accesses no local variables?

The parameters referred to are those of the latest call of the outer
function? Can there be a question of the outer function itself going
out of scope?

If available, an explanation of why the string "closure" was chosen for
the purpose would be nice; I've never previously had any idea of what it
means.

paras 1, 2 : which -> this.

When, in the major browsers, did closures appear?

"Reading of Values", word 4 -> from.

I think your examples might be easier to read if the comment were
indented by an extra tab, or if the comment and code had different
colour backgrounds (better still if the comment were in a second column;
but there's not room for that).

Meaning of "prorate" ?

"eval is never normally used ...". That's wrong; it is often used, we
see that in the newsgroup. I could agree to "eval should never be used
by most ..." or suchlike.


n = Math.abs(n) % 0x1000000

ISTM wrong to use the method of Procrustes here. If the parameter is
wrong, an error message should be given - or the definition changed so
that it cannot be wrong. It is the user's duty to provide an
appropriate value, and the user should choose what to do to ensure this.

function RGB(x) { // x >= 0, LS 6 hex digits used
return ('00000'+x.toString(16)).replace(/.*(.{6})/, '#$1') }

function rgb(y) { // LS 6 hex digits used
return ((0x1000000+y).toString(16)).replace(/.*(.{6})/, '#$1') }

// seem more direct (need toUpperCase for equivalence). Check!


in Other Examples
Who? What? Douglas Crokford's ... ECMAScirpt


in The Internet Explorer Memory Leak Problem
... wring)) -> ... writing)), curricular -> circular



--
© John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4 ©
<URL:http://jibbering.com/faq/> Jim Ley's FAQ for news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.

Yann-Erwan Perio

unread,
Mar 29, 2004, 6:40:32 PM3/29/04
to
Dr John Stockton wrote:

> Is it still a closure if the internally defined
> function accesses no local variables?

What about the activation object? A closure isn't defined by whether
there are elements in the environment in which it has been defined, but
whether it keeps this environment.

> Can there be a question of the outer function itself going
> out of scope?

If you lose all "visible" references to the outer function, it'll still
be in the scope chain of the closure, so the function is still
accessible; then it's not really out of scope:-)

> If available, an explanation of why the string "closure" was chosen for
> the purpose would be nice; I've never previously had any idea of what it
> means.

From:
<URL:http://encyclopedia.thefreedictionary.com/Closure%20(computer%20science)>

<QUOTE ABOUT="Definition">
Closures are typically implemented with a special data structure that
contains a pointer to the function code, plus a representation of the
function's lexical environment (i.e., the set of available variables and
their values) at the time when the closure was created).
(...)
Such a function may "capture" name/value bindings from its enclosing
environment, producing a closure.
(...)
Some speakers call any data structure that binds a lexical environment a
closure, but the term usually refers specifically to functions.
</QUOTE>


<QUOTE ABOUT="Closures' use">
Closures have many uses:

* Designers of software libraries can allow users to customize
behavior by passing closures as arguments to important functions. For
example, a function that sorts values can accept a closure argument that
compares the values to be sorted according to a user-defined criterion.
* Because closures delay evaluation --- i.e., they do not "do"
anything until they are called --- they can be used to define control
structures. For example, all Smalltalk's standard control structures,
including branches (if/then/else) and loops (while and for), are defined
using objects whose methods accept closures. Users can easily define
their own control structures as well.
* Multiple functions can be produced which close over the same
environment, enabling them to communicate privately by altering that
environment.
</QUOTE>

To illustrate these points:
- the first use is described in Ecma with the regular expressions
implementation (continuations); Lasse has also given many 'functional'
examples in the past few weeks;
- the second use has been exemplified in Richard's article, all small
examples;
- the third use was nicely implemented with Richard's protected members
solution.

Closures, in javascript, also permit object-oriented practices, as has
been demonstrated many times in the group.


Regards,
Yep.

Lasse Reichstein Nielsen

unread,
Mar 29, 2004, 6:58:43 PM3/29/04
to
Dr John Stockton <sp...@merlyn.demon.co.uk> writes:

> JRS: In article <c48c0n$edu$1$8302...@news.demon.co.uk>, seen in
> news:comp.lang.javascript, Richard Cornford
> <Ric...@litotes.demon.co.uk> posted at Mon, 29 Mar 2004 06:25:42 :
>>I have just finished an page for inclusion in the notes on the FAQ that
>>is intended as an explanation of javascript closures (I realise that is
>>not really a subject that is frequently asked about but it hardly seems
>>to get a mention anywhere else):-
>>
>><URL: http://www.jibbering.com/faq/faq_notes/closures.html >
>>
>>- and I would appreciate any reviews (technical or otherwise) anyone
>>cares to give it prior actually including it in the notes.
>
>
> ISTM that a pre-processor for HTML drafts would be useful; one that
> numbered every paragraph in numerical order regardless of text
> structure.

It can be handled by a simple CSS rule, e.g.:

<style type="text/css">
p:before {counter-increment:para;
content: "ง" counter(para);
float:right;
color:green;
}
</style>

Ofcourse it requires a browser that understands CSS 2 (ruling out IE)

> In Introduction, ISTM that there should be an example of the simplest
> possible closure,

function store(x){return function(){return x;};}

That would be about the smallest usable (as opposed to "useful") closure.

> and one of the simplest useful closure,

My vote is on:
function curry1(func,a){return function(b){return func(a,b);}}


> and more on
> where they are useful. Is it still a closure if the internally defined
> function accesses no local variables?

I'd say yes, but it's really irrelevant. Like asking whether an immutable
value is passed by name or by reference.

> The parameters referred to are those of the latest call of the outer
> function?

No, the call that was current when the closure was created. Example
where it isn't the latest:

function K(x){ return function(){return x;};};

var K1 = K(1);
var K2 = K(2); // most reccent call to K had x==2
alert(K1(42)); // alerts 1

> Can there be a question of the outer function itself going
> out of scope?

Easily.
function K(x) {
function makeConstant(y) {
return function(){return y;}
}
return makeConstant(x);
}
var K1 = K(1); // K1 is closure of function(){return y;} and environment {y:1}
// makeConstant is out of scope.

> If available, an explanation of why the string "closure" was chosen for
> the purpose would be nice; I've never previously had any idea of what it
> means.

An expression with no "free variables" is called "closed". In
function(){return y;}
the identifier "y" is unbound, or "free". In
function makeConstant(y) {return function(){return y;};}
the identifier "y" is bound by the function declaration as an
argument.

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

> paras 1, 2 : which -> this.
>
> When, in the major browsers, did closures appear?

As far as I can see: Netscape 4.0, IE 4, Opera 5.

This script used as test:
function foo(x) {
function bar() {return x;}
return bar;}
alert(foo(42)(37)); // alerts 42

It fails in Opera 4, Netscape 3 and IE 3, but works in Opera 5,
Netscape 4.04 and IE 4.

/L
--
Lasse Reichstein Nielsen - l...@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'

Richard Cornford

unread,
Mar 29, 2004, 6:51:30 PM3/29/04
to
Yann-Erwan Perio wrote:
> Richard Cornford wrote:
>
>> I have just finished an page for inclusion in the notes on the FAQ
>> that is intended as an explanation of javascript closures
>
> > <URL: http://www.jibbering.com/faq/faq_notes/closures.html >
>
> I've read this thoroughly and AFAICS it's perfectly compliant with
> ECMA262-3. I've therefore very few remarks to make, FWIW:
> - "But all objects may have prototypes (...)", well they all _have_
> prototypes;

I considered whether that sentence should include the word "may" and
decided it probably should.

The Activation object should have its [[prototype]] property set to null
(else - toString - unqualified may resolve as a method of the Activation
object). Does an object with its [[prototype]] property set to null have
a prototype? (So, can the object referred to by Object.prototype be
described as having a prototype?)

> - although you're saying that the distinction between the prototype
> property and [[prototype]] is outside the scope[1] of the article, you
> make such a detailed analysis of the prototype resolution (and a very
> good one as well!) that I feel you should add a paragraph on this;

Maybe, I will have to think about that a bit. I was trying to restrict
the detail in that section to the greatest extent possible (an earlier
draft started to go into the [[Get]] and [[Put]] methods but I decided
that level of detail was not necessary). I have been considering writing
a page on objects and constructors where that detail might be
appropriate.

> - while explaining the Variable Object, you could have insisted a bit
> more on the declaration of variables being completely separated from

> their initialization ...

OK, I have added an extra paragraph on that.

> - about how many objects are possible in the scope chain, I've just
> tried but just succeeded in having Mozilla explode with 5000 objects,
> so I guess it cannot be accurately calculated;

That should be enough for all practical purposes.

<snip>
> - some typos:
<snip>

Thanks, all fixed and updated.

<snip>
> Well, I wish I had read such an article 6 months ago, ...
<snip>

Likewise, I was frustrated by my inability to turn up anything with
google when I first became interested in the subject.

> BTW, I've just read your article about using "with" to make private
> static members (you're quite inspired there days), I think I'll
> experiment a bit in my next posts, the idea is very interesting!

I thought that idea would appeal to you. Incidentally, I was being
pessimistic in my original comments on Netscape 4's handling of the
code. It does resolve unqualified identifiers as properties of the
object added to the scope chain, but it does not consider the object's
prototype so they have to be properties of the object itself.

Thanks,

Richard.


Richard Cornford

unread,
Mar 29, 2004, 6:51:34 PM3/29/04
to
Martin Honnen wrote:
> Richard Cornford wrote:
<snip>

> 3)in the section accidental closures, second paragraph I don't
> understand the sentence
>
> It is not the closures themselves the impact of efficiency, indeed
> carefully used they can contribute significantly towards the creation
> of efficient code.
>
> maybe you want something alike
>
> It is not the closures themselves but the impact on efficiency, indeed
> carefully used they can contribute significantly towards the creation
> of efficient code.
>
> but I am not entirely sure whether you maybe don't want that "the
> impact of efficiency" in that sentence at all, maybe you want it
> removed and only mentioned in the following sentence:

I actually meant to write:-

"It is not the closures themselves that impact on efficiency, ..."

> It is not the closures themselves, indeed carefully used they can
> contribute significantly towards the creation of efficient code. It is
> the use of inner functions that can impact on efficiency.

But I liked that better so I used it instead.

Thanks for those corrections. I have updated the page to include them.

Richard.


Lasse Reichstein Nielsen

unread,
Mar 29, 2004, 7:13:26 PM3/29/04
to
Yann-Erwan Perio <y-e....@em-lyon.com> writes:

> What about the activation object? A closure isn't defined by whether
> there are elements in the environment in which it has been defined,
> but whether it keeps this environment.

But if it doesn't reference it, you can't see if it keeps it.
You can make a valid ECMAScript implementation that optimizes
the contents of closures (using shallow closures instead of deep).
The algorithms in the standard are only defining the behavior,
not the implementation of it.

Ofcourse, you have to be *very* careful, wiz:

function foo(a,b,c){
var yabba,dabba,doo;
// ...
return function(e){return eval(e);} // "closed" function ... not!
}

One almost thinks they had things like this in mind when they said
that "eval" can not be used as a first class function (ECMA262,
15.1.2.1, last paragraph, cannot read its function value), so you can
always detect calls to it ... that doesn't affect Function, but that
always uses the global scope. Gotta be careful, and it seems that have
been :)

...

Good quotes!

Richard Cornford

unread,
Mar 30, 2004, 2:53:56 AM3/30/04
to
Lasse Reichstein Nielsen wrote:
> Dr John Stockton wrote:
<snip>

>> and one of the simplest useful closure,
>
> My vote is on:
> function curry1(func,a){return function(b){return func(a,b);}}

Curry functions are usable, but I am yet to see a reason to use one,
which makes me question "useful". ;-)

<snip>


> Easily.
> function K(x) {
> function makeConstant(y) {
> return function(){return y;}
> }
> return makeConstant(x);
> }
> var K1 = K(1); // K1 is closure of function(){return y;} and
> environment {y:1} // makeConstant is out of scope.

Has it gone out of scope? The - makeConstant - inner function object is
created in an execution context of - K - by - K(1) - so the [[scope]]
property of that function object should point to a scope chain
containing the Activation/Variable object from that execution context,
something like:-

{
x:1,
makeConstant:function(y){return function(){return y;}}
}

- followed by the global object. The execution context produced by -
makeConstant(x) - will add another Activation/Variable object to the top
of that chain - {y:1} - and that chain will be assigned to the [[scope]]
property of the function object resulting from the evaluation of the
innermost function expression, the function object that is returned and
assigned to - K1 -. But when - K1() - is executed its execution context
will have a scope chain consisting of the chain from the innermost
function's [[scope]] property:-

{y:1}
- then ->
{
x:1,
makeConstant:function(y){return function(){return y;}}
}
- then ->
the global object, with its own Activation/Variable object at the top.
So if that innermost function use the unqualified identifier -
makeConstant - it would resolve as a reference to the function that had
returned it. So it is still in scope, it is just never referred to.

The corresponding intermediate function in:-

function K(x) {
return ((function(y) {
return function(){return y;}
})());
}
var K1 = K(1);

Goes out of scope because it is a function expression and is never
assigned to a property of any Activation/Variable object that is placed
in the scope chain assigned to the [[scope]] property of the function it
returns.

>> If available, an explanation of why the string "closure" was chosen
>> for the purpose would be nice; I've never previously had any idea of
>> what it means.
>
> An expression with no "free variables" is called "closed". In
> function(){return y;}
> the identifier "y" is unbound, or "free". In
> function makeConstant(y) {return function(){return y;};}
> the identifier "y" is bound by the function declaration as an
> argument.
>
> 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).

<snip>

As a definition of the term appears to be wanted, may I quote that as
the definition?

Richard.


Richard Cornford

unread,
Mar 30, 2004, 2:54:02 AM3/30/04
to
Dr John Stockton wrote:
<snip>
> ISTM that a pre-processor for HTML drafts would be useful; one that
> numbered every paragraph in numerical order regardless of text
> structure.

Yes it probably would.

> In Introduction, ISTM that there should be an example of the simplest
> possible closure, and one of the simplest useful closure,

I am not sure that I would want to do that, I want the introduction to
introduce the subject, but by description not example. Understanding the
mechanism, how an inner function's scope chain is built, the
relationship between the function object's [[scope]] property and the
scope chain in its execution contexts and so on, strikes me as the best
grounding in order to understand how best to use them. So I don't want
to start with examples until the groundwork has been covered.

> and more on where they are useful.

I am not sure I could formally state where they are useful, they
facilitate some things that would be impossible otherwise, and make some
tasks easier, but there is no shortage of people who are happily getting
by without ever using them.

They are good for encapsulation in various forms, they are good for
maintaining associations in future execution, and they are good for
building unusual structures (and particularly structures that "do"
things, in a way that structures of ordinary objects would find
difficult).

Bur I doubt that I have seen their full potential yet (and Lasse's
assertion that closures allow javascript to emulate anything and
everything makes that seem probable). The also seem to be good for the
mind, the Curry function (the full versions rather than cut down two
argument version that Lasse proposed as the simplest useful closure),
while lacking any apparent application in browser scripting, was a
fascinating exercise in convoluted thinking.

> Is it still a closure if the internally
> defined function accesses no local variables?

By the specifications the Activation object from the execution context
in which the inner function is created will be at the top of the scope
chain referred to by the function object's [[scope]] property. It will
not be garbage collection until the function object is freed and it will
retain all of the values assigned to it, including references to other
objects. Preserving them for the life of the function object.

Lasse suggest that the process could be "optimised" so that the
Activation object could be removed when it cannot be used by the inner
function, but I wouldn't bet on that having been implemented anywhere
(and it might turn out to be an unnecessary additional overhead rather
than an optimisation).

But part of the point on the section on the accidental creation of
closures was to suggest that if an inner function was not taking
advantage of its status as an inner function (by using its unique scope
chain) then maybe it should not have been written as an inner function.
(Lasse has proposed code maintenance as a possible justification for
using inner functions that don't take advantage of their status when I
have questioned the wisdom of the practice in the past. That seems a
reasonable position, so long as people understand what they are doing,
and the consequences, they can make their own informed decisions.)

> The parameters referred to are those of the latest call of
> the outer function?

No, the parameters, and all other properties of the Activation/Variable
object from the execution context of the function in which inner
function object was created, are associated with the inner function
objects created in that execution context. Each call to a function gets
a new execution context with a new and unique Activation/Variable
object, and a new and unique set of inner function objects are created
within that execution context. In principal a new inner function object
is created during variable instantiation for each inner function
declaration, and for each evaluation of an inner function expression
during execution.

The specification offers an optimisation of function object creation
(joining of externally indistinguishable function objects) but
experimentation suggest that no current implementations take that option
when it comes to inner functions.

> Can there be a question of the outer function itself going
> out of scope?

If the function object is the result of the evaluation of an anonymous
function expression it certainly can be inaccessible as a property of
any of the objects on the inner function's scope chain.

> If available, an explanation of why the string "closure" was chosen
> for the purpose would be nice; I've never previously had any idea of
> what it means.

> paras 1, 2 : which -> this.
>
> When, in the major browsers, did closures appear?

Netscape JavaScript 1.2, when function nesting became possible.

> "Reading of Values", word 4 -> from.
>
> I think your examples might be easier to read if the comment were
> indented by an extra tab, or if the comment and code had different

> colour backgrounds ...

The HTML doesn't lend itself to different coloured backgrounds for the
comments, as it would extend to the padding of the surrounding PRE
elements.

> Meaning of "prorate" ?

typo - property.

> "eval is never normally used ...". That's wrong; it is often used, we
> see that in the newsgroup. I could agree to "eval should never be
> used by most ..." or suchlike.

<snip>

Ah, but I qualified it with "by javascript programmers" so I get to
maintain that the stream of - eval - abuse we see every day is not the
product of "javascript programmers" (but of hacks).

> function RGB(x) { // x >= 0, LS 6 hex digits used
> return ('00000'+x.toString(16)).replace(/.*(.{6})/, '#$1') }
>
> function rgb(y) { // LS 6 hex digits used
> return ((0x1000000+y).toString(16)).replace(/.*(.{6})/, '#$1') }
>
> // seem more direct (need toUpperCase for equivalence). Check!

Shorter certainly, relative performance hangs on the quality of the
regular expression implementation. But the point was to demonstrate the
association of a single array with any number of calls to a function,
but I have changes the example to one where the advantages should be
more real.

> in Other Examples
<snip>

All typos fixed. Thanks.

Richard.


Dr John Stockton

unread,
Mar 30, 2004, 6:59:12 AM3/30/04
to
JRS: In article <wu535h...@hotpop.com>, seen in
news:comp.lang.javascript, Lasse Reichstein Nielsen <l...@hotpop.com>
posted at Tue, 30 Mar 2004 01:58:43 :

>Dr John Stockton <sp...@merlyn.demon.co.uk> writes:

>> ISTM that a pre-processor for HTML drafts would be useful; one that
>> numbered every paragraph in numerical order regardless of text
>> structure.
>
>It can be handled by a simple CSS rule, e.g.:
>
> <style type="text/css">
> p:before {counter-increment:para;

> content: "§" counter(para);

> float:right;
> color:green;
> }
> </style>
>
>Ofcourse it requires a browser that understands CSS 2 (ruling out IE)

Valid code that does not work in IE is scarcely useful on the Web,
except possibly when written by MS.


>> In Introduction, ISTM that there should be an example of the simplest
>> possible closure,
>
> function store(x){return function(){return x;};}
>
>That would be about the smallest usable (as opposed to "useful") closure.
>
>> and one of the simplest useful closure,
>
>My vote is on:
> function curry1(func,a){return function(b){return func(a,b);}}

Needs demonstration of usefulness, though.


>> When, in the major browsers, did closures appear?
>
>As far as I can see: Netscape 4.0, IE 4, Opera 5.
>
>This script used as test:
> function foo(x) {
> function bar() {return x;}
> return bar;}
> alert(foo(42)(37)); // alerts 42
>
>It fails in Opera 4, Netscape 3 and IE 3, but works in Opera 5,
>Netscape 4.04 and IE 4.

It does indeed work (in eval) in IE4.

But my questions were intended as indications of what I think that the
document should answer, rather than being in real need of answer here.

Yann-Erwan Perio

unread,
Mar 30, 2004, 1:26:07 PM3/30/04
to
Richard Cornford wrote:

> The corresponding intermediate function in:-
>
> function K(x) {
> return ((function(y) {
> return function(){return y;}
> })());
> }
> var K1 = K(1);
>
> Goes out of scope because it is a function expression and is never
> assigned to a property of any Activation/Variable object that is placed
> in the scope chain assigned to the [[scope]] property of the function it
> returns.

To me the middle function isn't out of scope (and cannot be in my view),
since the scope of the innermost function holds the Activation object
of the middle function, which has the 'arguments' property, which itself
has the 'callee' property.

(or am I missing something big?)


Regards,
Yep.

Lasse Reichstein Nielsen

unread,
Mar 30, 2004, 1:37:21 PM3/30/04
to
"Richard Cornford" <Ric...@litotes.demon.co.uk> writes:

> Lasse Reichstein Nielsen wrote:

>> var K1 = K(1); // K1 is closure of function(){return y;} and
>> environment {y:1} // makeConstant is out of scope.
>
> Has it gone out of scope?

By "scope" I mean the textual scope of the declaration. You can no
longer refer to it by its name, so it is no longer in scope. The value
(and name) is still present in the environment of a closure, and while
evaluating the body of that closure, the declaration will again be in
scope.
Values doesn't have scope, declarations does.

> The corresponding intermediate function in:-
>
> function K(x) {
> return ((function(y) {
> return function(){return y;}
> })());
> }
> var K1 = K(1);

It is ofcourse a better example, since it avoids the declaration
completely. With my definition of scope, the inner functio was never
"in scope". And I can hear that that sounds weird :)

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

> As a definition of the term appears to be wanted, may I quote that as
> the definition?

Sure. :)

Yann-Erwan Perio

unread,
Mar 30, 2004, 1:38:20 PM3/30/04
to
Lasse Reichstein Nielsen wrote:

> You can make a valid ECMAScript implementation that optimizes
> the contents of closures (using shallow closures instead of deep).
> The algorithms in the standard are only defining the behavior,
> not the implementation of it.

ACK.

> Ofcourse, you have to be *very* careful, wiz:
>
> function foo(a,b,c){
> var yabba,dabba,doo;
> // ...
> return function(e){return eval(e);} // "closed" function ... not!
> }

Well that works fine in Mozilla, but when I tried in Opera (as of 7.23),
the browser got "closed":-)

> One almost thinks they had things like this in mind when they said
> that "eval" can not be used as a first class function (ECMA262,
> 15.1.2.1, last paragraph, cannot read its function value), so you can
> always detect calls to it ...

Your example makes sense, although I think that the specification allows
either the browser to run it, or to throw an exception.

<QUOTE SRC="Ecma-262-3, 15.1.2.1">
If value of the eval property is used in any way other than a direct
call (that is, other than by the explicit use of its name as an
Identifier which is the MemberExpression in a CallExpression), or if the
eval property is assigned to, an EvalError exception may be thrown.
</QUOTE>


Regards,
Yep.

Lasse Reichstein Nielsen

unread,
Mar 30, 2004, 2:01:10 PM3/30/04
to
Yann-Erwan Perio <y-e....@em-lyon.com> writes:

> Lasse Reichstein Nielsen wrote:

>> Ofcourse, you have to be *very* careful, wiz:
>> function foo(a,b,c){
>> var yabba,dabba,doo;
>> // ...
>> return function(e){return eval(e);} // "closed" function ... not!
>> }
>
> Well that works fine in Mozilla, but when I tried in Opera (as of
> 7.23), the browser got "closed":-)

Hmm. Perhaps a bug. It seems to be corrected in Opear 7.5-preview 3.
At least it doesn't crash for me.

> Your example makes sense, although I think that the specification
> allows either the browser to run it, or to throw an exception.
>
> <QUOTE SRC="Ecma-262-3, 15.1.2.1">
> If value of the eval property is used in any way other than a direct
> call (that is, other than by the explicit use of its name as an
> Identifier which is the MemberExpression in a CallExpression), or if
> the eval property is assigned to, an EvalError exception may be thrown.
> </QUOTE>

True, it is optional. But if someone wants to make an optimization
that could be ruined by eval, they can make eval non-readable so that
all accesses to eval must go through the same, easily detectable,
global property. Then they can turn the optimization off in cases like
the above.

Without eval, all references to a (non-global) variable can be
detected statically, so you know if it needs to be in a closure
or not. With eval, data becomes program, taking program analysis
from just theoretically impossible to effectively impractical :)

Richard Cornford

unread,
Mar 30, 2004, 7:00:46 PM3/30/04
to
Lasse Reichstein Nielsen wrote:

> "Richard Cornford" wrote:
>> Lasse Reichstein Nielsen wrote:
>
>>> var K1 = K(1); // K1 is closure of function(){return y;} and
>>> environment {y:1} // makeConstant is out of scope.
>>
>> Has it gone out of scope?
>
> By "scope" I mean the textual scope of the declaration. You can no
> longer refer to it by its name, so it is no longer in scope. ...

I occurred to me some time after posting that you probably had a
definition of "scope" in mind that was somewhat less ridged than my
'structure of objects in the scope chain' interpretation. I have tended
to find arguing about the definition of words counterproductive, so,
fair enough: What does it matter that some residual property of an
object in the structure is still holding a reference to the function
object if there is no way of accessing that property? It may be "in" the
scope chain but if there is no way to get to it there is no reason not
to describe it as "out of scope".

<snip>


>>> 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).
>
>> As a definition of the term appears to be wanted, may I quote
>> that as the definition?

> Sure. :)

Thank you, I will add it later.

Richard.


Richard Cornford

unread,
Mar 30, 2004, 7:00:53 PM3/30/04
to

No, that was me missing something because the execution of the
intermediate function does indeed assign a reference to the function
object to the - arguments.callee - property. So it is referred to by a
property of one of the Activation/Variable objects in the innermost
function's scope chain. However, the - arguments - property of that
Activation/Variable object will be masked by the - arguments - property
of the Activation/Variable object belonging to the execution context of
any call to the innermost function. So the function reference is on the
chain but inaccessible (without some additional code such as a function
declaration in the intermediate function that would return its -
arguments - object).

Richard.


0 new messages