Jump to content

Talk:Closure (computer programming): Difference between revisions

Page contents not supported in other languages.
From Wikipedia, the free encyclopedia
Content deleted Content added
No edit summary
Line 298: Line 298:
::Simply put, it means that <code>return</code> inside the closure would return not from the closure itself, but from the function inside which that closure was created. This is the take on closures the Java guys did, and you can read more on it [http://www.javac.info/closures-v04.html here] - you may notice an oddly familiar name in the list of authors there as well. ;)
::Simply put, it means that <code>return</code> inside the closure would return not from the closure itself, but from the function inside which that closure was created. This is the take on closures the Java guys did, and you can read more on it [http://www.javac.info/closures-v04.html here] - you may notice an oddly familiar name in the list of authors there as well. ;)
::Of course, such approach is only meaningful in a language which distinguishes closures from "normal" functions (Scheme doesn't, for example, and neither does ECMAScript), and it seems to be conceptually weak in a sense that it does not go well with nested closures (what if I don't want to return from the topmost enclosing non-closure, but from a closure 2 levels up? and if I can't, why not?). [[User:Int19h|-- int19h]] 08:53, 28 January 2007 (UTC)
::Of course, such approach is only meaningful in a language which distinguishes closures from "normal" functions (Scheme doesn't, for example, and neither does ECMAScript), and it seems to be conceptually weak in a sense that it does not go well with nested closures (what if I don't want to return from the topmost enclosing non-closure, but from a closure 2 levels up? and if I can't, why not?). [[User:Int19h|-- int19h]] 08:53, 28 January 2007 (UTC)

::: ''"what if I don't want to return from the topmost enclosing non-closure, but from a closure 2 levels up? and if I can't, why not?"'' <br />I think JavaScript lets you do that, but through an improper use of a differently aimed construct, so I'm writing this just for comparison sake (since this method could make one of the javascript examples to behave like the Smaltalk one on the "^" operator). Furthermore, this method requires an explicit handling of the "exit point", yet it's very easy and maybe obvious: just use <code>throw</code> instead of <code>return</code> and capture the result as an exception, wherever you need it.<br /><br />Of course, that's not the right way one should use an exception-handling construct, so that'd be perhaps misleading/confusing in a real script, yet that should work as wished. And of course, great troubles might arise when using such an improper return method combined with regular exceptions, yet it's possible to make it work: in example, one could wrap the "exception-like" result into a certain "class" object and verify whether a captured exception is an instance of such a "class". So doing, the <code>throw</code> keyword whould behave quite like the <code> ^ </code> operator in Smalltalk, while <code>return</code> whould be the equivalent of a "normal" procedure end.--[[Special:Contributions/151.74.14.142|151.74.14.142]] ([[User talk:151.74.14.142|talk]]) 01:21, 2 April 2008 (UTC) xeal


::: In languages with full support for closures, you can't "return" from any closure, no matter how many levels up, except by providing a final expression. Providing an example of what it would look like in Javascript would require that I make up a new syntax. For that, I suggest you see the proposed Java extension. [[User:Gafter|Gafter]] 17:14, 28 January 2007 (UTC)
::: In languages with full support for closures, you can't "return" from any closure, no matter how many levels up, except by providing a final expression. Providing an example of what it would look like in Javascript would require that I make up a new syntax. For that, I suggest you see the proposed Java extension. [[User:Gafter|Gafter]] 17:14, 28 January 2007 (UTC)
Line 304: Line 306:


:::: A programming language's expressive power is not determined by what one can compute, but rather what kinds of abstractions one can express. Most modern languages are Turing-complete and can therefore compute the same set of functions. I suggest you read Guy Steele's "lambda the ultimate..." series of papers to understand what is lost when not all lexical bindings are preserved. Alternatively, I suggest you attempt to write a function in JavaScript that can be used in place of the built-in if-then-else statement (of course the invocation syntax would differ; that's OK). You'll find you can't. [[User:Gafter|Gafter]] 23:51, 28 January 2007 (UTC)
:::: A programming language's expressive power is not determined by what one can compute, but rather what kinds of abstractions one can express. Most modern languages are Turing-complete and can therefore compute the same set of functions. I suggest you read Guy Steele's "lambda the ultimate..." series of papers to understand what is lost when not all lexical bindings are preserved. Alternatively, I suggest you attempt to write a function in JavaScript that can be used in place of the built-in if-then-else statement (of course the invocation syntax would differ; that's OK). You'll find you can't. [[User:Gafter|Gafter]] 23:51, 28 January 2007 (UTC)

::::: ''"Alternatively, I suggest you attempt to write a function in JavaScript that can be used in place of the built-in if-then-else statement (of course the invocation syntax would differ; that's OK)."'' <br />I'm not sure this is exactly what you're asking for, but at first glance I'd write the following:
<pre>
//
// Implementing the if-else construct as a function which takes three functions as arguments.
// The first function passed is the condition to be tested, and is expected to evaluate as
// true or false; the second one is the block to be executed if the test condition evaluates to
// true, and may optionally return a value; the third is the alternative block to be executed
// and may optionally return a value. One of such optional values is returned (null or undefined
// if none is supplied). The calling function might assign the result value to a somewhat variable,
// or let the function-block to handle it. A preferred way to call this function and easily handle
// variables as in a standard if-else statement is throughout internal functions, as shown in
// the alertMax function below.
//
function if_else(ifcond, ifblock, elseblock){
var result = null;
var doIF = ( ifcond() ) && ( result = ifblock() ); //when ifcond evaluates to true ifblock is
//called and results assigned to result,
var doELSE = (! ifcond() ) && ( result = elseblock() ); //otherwise elseblock is called in
//the same fashion.
return result;
}

//
// Comparing values by calling if_else function with opportune parameters.
//
function alertMax( a, b ){
var max = if_else(
function(){ return (a >= b); },
function(){ alert( a + " is greater than or equal to " + b); return a; },
function(){ alert( b + " is greater than " + a); return b; }
); //note functions passed as ifblock and elseblock alerts different text;
//this shows the alternate execution of statements-equivalent functions works.
alert("Max computed value is: " + max);
}

alertMax(6, 5);
alertMax(8, 9);</pre>
:::::--[[Special:Contributions/151.74.14.142|151.74.14.142]] ([[User talk:151.74.14.142|talk]]) 01:21, 2 April 2008 (UTC) xeal


::::: I can, however, write a function in JavaScript that can be used the same way Scheme's <code>if</code> or <code>cond</code> expression can be used. That's what my point was - that JavaScript closures can express all abstractions Scheme closures can. [[User:Int19h|-- int19h]] 06:45, 29 January 2007 (UTC)
::::: I can, however, write a function in JavaScript that can be used the same way Scheme's <code>if</code> or <code>cond</code> expression can be used. That's what my point was - that JavaScript closures can express all abstractions Scheme closures can. [[User:Int19h|-- int19h]] 06:45, 29 January 2007 (UTC)

Revision as of 01:21, 2 April 2008

Don't start with Lisp

I don't think the initial examples should be in Lisp. Here's why: the vast majority of Lisp programmer will already be familiar with closures, but a lot of people who navigate to this page will tend to be people who aren't familiar with Lisp (if they were familiar with Lisp, they'd probably know what a closure was already). I'd suggest (for the initial examples) some language which has syntax which is more C-like. Maybe javascript? Or maybe pseudocode. Of course, definitely include the Lisp code later. Just not the very first thing. Does anyone else agree?

This will probably be a controversial suggestion as Lisp advocates will argue that the language is directly rooted in lambda calculus. Still, I think it is a good idea. I would suggest using Eiffel for such intro examples because it's an imperative language, close to what most people use, and yet the syntax is very clear and the notion of agent directly represents the mathematical concept of closure. I am willing to do it but I will wait to see if there is some agreement. Necklace 22:56, 2 August 2006 (UTC)[reply]
It's important to remember here that Wikipedia is not a textbook or tutorial, but an encyclopedia: the goal is not to teach (that's what Wikibooks is for), but to describe, with accuracy and relevance. When it comes to the choice of example language, it's not industrial popularity that's relevant, but things like historical prominence, and representation in the literature.
With all that in mind, i think Lisp is an ideal choice; probably the only change called for is to switch the examples to the Scheme dialect, because of its simpler syntax, and because of the important role it played in popularizing the concept of closures to begin with. (If a non-Lispy example is desired for contrast, a member of the ML family is probably appropriate.) --Piet Delport 21:06, 3 August 2006 (UTC)[reply]
I'm all for using Lisp or Scheme along with a second language - but I think JavaScript would be the ideal choice for that language. It's certainly relevant, being by far the most widespread language that supports closures, and its syntax is instantly clear to a huge number of programmers. Even if the goal isn't to teach, a familiar language helps make the article clear to a wider audience. I would be happy to provide some JavaScript examples to go along with the Lisp ones if others agree. Michael Geary 04:44, 20 August 2006 (UTC)[reply]
Sounds good to me. --Piet Delport 15:48, 20 August 2006 (UTC)[reply]
I totally agree with not starting in Lisp. I program for a living, and I totally balked at the Lisp intro, not grasping one single thing of what it tries to explain (The same goes for Continuations, using Scheme). If one look at Coroutines, this starts off with some nice pseudocode, immediately understandable for anyone having the slightest interest in computer languages, adaptable to one's preferred universe. While wikipedia shouldn't be to teach people as such (apparently, as stated above, although I still use it to "start" my understanding of many topics), I don't think it should be for showing off one's intelligence by using one of the rather uncommon computer languages out there. This puts people off. —Preceding unsigned comment added by 84.208.115.107 (talk)
I totally disagree with starting with a language other than lisp. Closures originated with Lisp. Many programming languages that claim to support closures - for example Java, Javascript, C#, Python - actually don't support full closures for one reason or another. Scheme and Smalltalk are the best examples of imperative languages that do support closures. Gafter 15:48, 10 December 2006 (UTC)[reply]
Then you should at least be sure what kind of closures you are talking about. The opening reference to Structure and Interpretation of Computer Programs is totally misplaced - the authors are talking about Closure (mathematics), not Closure (computer science) (e.g. the cons of a list is itself a list [1]). This is explained quite clearly in this footnote to chapter 2.2:
The use of the word "closure" here comes from abstract algebra, where a set of elements is said to be closed under an operation if applying the operation to elements in the set produces an element that is again an element of the set. The Lisp community also (unfortunately) uses the word "closure" to describe a totally unrelated concept: A closure is an implementation technique for representing procedures with free variables. We do not use the word "closure" in this second sense in this book.[2]
Anyway, while lots of nifty things originated in Lisp, I find it hard to think of closures without lexical scoping, and Lisp didn't get that until 1984. Geira (talk) 19:01, 4 February 2008 (UTC)[reply]
That's not correct WRT JavaScript. JavaScript does support closures in every sense of the word. And a tip o' the hat to User:Int19h for adding the JavaScript examples. Because so many programmers can read JavaScript, it is an excellent language for showing examples of closures. --Michael Geary 17:53, 26 January 2007 (UTC)[reply]

Closures in Perl

In perl at least, a closure doesn't have to be a function definition. It's more or less anything between a pair of braces, that serves as it's own variable scope. In Damian Conway's Object Oriented Perl, I believe he uses closures to implement the private variables of an object, so it might be misleading to say that the closure itself is an object or acts like one. In any case, something needs to be said about scope here. Wesley

How could one use a closure that's not a function definition?

Typically closures are not function definitions, they are anonymous functions. In Lisp, they are lambda functions, in Perl, they are blocks. —The preceding unsigned comment was added by Nowhere man (talkcontribs) 13:15, 7 March 2007 (UTC).[reply]

This isn't right. In perl6 blocks will technically be closures, but thats pretty obscure stuff afaik. In perl5 blocks aren't closures. Demerphq 19:09, 7 April 2006 (UTC)[reply]

Regarding the "acts as an object" comment, I was thinking of a closure like this:

sub counter {
    my $x = shift;
    return sub { print "$x\n"; $x--; };
}

$h = counter(4);
$g = counter(7);

$h->();  # gives 4
$h->();  # gives 3
$g->();  # gives 7
$h->();  # gives 2
AxelBoldt

A closure can be used as a way to simulate static variables. For instance consider the following (slow) function:

sub fib {
  my $n = shift;
  if ($n <= 1) {
    return 1;
  }
  else {
    return fib($n-1) + fib($n-2);
  }
}

It works, but calculating (say) fib(40) may take a while. Now let's add a private closure in which we cache results (this kind of caching is known as memoizing):

{
  my %cache;
  sub fib {
    my $n = shift;
    if ($n <= 1) {
      return 1;
    }
    elsif (exists $cache{$n}) {
      return $cache{$n};
    }
    else {
      return $cache{$n} = fib($n-1) + fib($n-2);
    }
  }
}

Now the function runs much more quickly. If we had static variables (the "my $foo if 0;" bug does not count in my books!), that would be the right way to do this, but closures can do it as well.

BTW I hope that the example I gave is not too complex. I wanted to provide something that was accessible but gave an idea of why someone might choose to use closures.

bjt


IMO the example was too complex. Also, Perl is a heinous language for explaining computer science concepts (e.g., you have to use "shift" to peel off arguments --- utterly obscure --- not to mention all the other random syntactic noise that comes with Perl). I replaced it with a more basic explanation that just conveys the idea of lexical scope capture. I used ML, which has a far more concise and pseudocode-like syntax than Perl.

If you want to do a more involved programming example, IMO you should create an article for first-class function or higher-order function and write it there; or, better still add it to functional programming. The term "closure", as commonly used by language designers/implementors, refers specifically to the data structure with the code pointer and environment pointer. Programming using higher-order functions is a broader idea, and belongs in a broader article. k.lee 00:44, 24 Oct 2003 (UTC)


Re: typical implementation as "a set of values that record the values of the relevant variables in the function's lexical environment at the time of binding", this was not correct. A naive Lisp interpreter can implement a closure as a pair containing a pointer to the function and a pointer to the actual lexical environment (activation record) at the point of capture. There's no recording of values, or selection of relevant variables for capture. Wasteful and slow, but adequate. k.lee 17:27, 24 Oct 2003 (UTC)


IMO a Perl example is well called for. The counter example IMO isn't bad. I took the liberty of updating it a touch style wise tho, the &$f() style is a bit archaic. And really I think there are a lot more people out there that can read Perl than can read ML, and k.lee's comments appear a bit uninformed, shift isnt the only way to access arguments in perl. Also, Perl is one of the few "popular" (non-academic maybe is better) languages that makes heavy use of closures, so i think an example of it would be well worth while. Demerphq 19:09, 7 April 2006 (UTC)[reply]


Im going to add a perl example back to the page unless somebody protests. Demerphq 17:05, 10 April 2006 (UTC)[reply]

Closures and Java

I have just edited the page such that the Java simulation section has "final" instead of "immutable". My understanding of the term immutable in the context of Java is that it means once you have a reference to the object its internal state will never change i.e. all fields (including private ones) can be declared final and all references that the object holds are themselves to immutable objects. This property, as far as I know, is not detected or enforced by the runtime and is not necessary for a local variable to be used in an anonymous inner class. The meaning of the keyword final, on the other hand, is that the value of the variable will never change which object it references (or will never change value if a primitive). It is this that is necessary for the anonymous inner type to make use of the variable so that the runtime can simply clone the primitive values and object references of final variables on the stack when instantiating the anonymous inner class.

--Jwal 18:35, 12 Jun 2004 (UTC)



Closures and Python

Why Python doesn't have closures:

Python has nested scope, but not the ability to modify variables in outer lexical scopes (except for globals, and via reflexion). Therefore, Python doesn't have closures. It's that simple. --Lament

Admittedly Python closures are broken in this respect compared to Scheme, but this is overstated. As a matter of practice, 99% of the time Python closures work just like Scheme closures. They look the same, work the same, and are used for the same purposes. On the other hand, if you're using a closure in Python to hide modifiable state, it's probably a kindness that Python doesn't support what you want to do. Jorend 20:41, 10 January 2006 (UTC)[reply]
I have changed my view on this. Python closures are not used for the same purposes as Scheme closures. I am told that in Scheme, closures are very commonly used to hide state. In Python, you would just use a class instead. Jorend 21:50, 15 February 2006 (UTC)[reply]

FWIW, Python does allow you to modify variables in outer scopes; it does not, however, have syntax for rebinding names in outer scopes to new values. The workaround when this is needed (which isn't often) is to use a mutable container object in the enclosing scope, and replace the contained value rather than the container

>>> def foo(start=0):
...     counter = [start] # counter is 1-element array
...     def bar():
...         counter[0] = counter[0] + 1
...         return counter[0]
...     return bar
...
>>> count = foo(10)
>>> print count()
11
>>> print count()
12
>>> print count()
13

Although Jorend is right that classes are preferred for encapsulation in Python, closures actually hide state better than classes do. All class data is, ultimately, accessible from within Python. I don't think I can get to the counter in the example above without writing a C extension.

This is discussed in slightly more depth in Talk:Python_programming_language#Closures. I like my example better, though. :)

Your link to the discussion on the Python talk page seems to be broken, now -- the #Closures part of it, specifically. It seems someone eliminated that part of the discussion. -- Apotheon 06:34, 22 November 2006 (UTC)[reply]
It's been archived over here. --Piet Delport 09:31, 22 November 2006 (UTC)[reply]
Actually, you can get to the counter: the object returned by foo() is a function obj, it has an attribute ('func_closure' I think), which is a list of cell objects; one of those holds a reference to the list. There is another attribute func_code, which is a code object, it has an attribute which gives the corresponding names of the closure variables. So, it's not a direct access (and may change a bit in later Python versions) but it's plenty useful enough for debuggers and the like. The cell objects are used so that the outer function can change the variable after the inner function is created, and the closure will see the change; and they allow the outer function's frame to be destroyed while keeping the closure; the cells live as long as the outer frame or the inner function, whichever is later. There's no mechanical reason why closures could not change these shared variables -- the required opcode is there -- currently it is prevented by a syntactic catch-22 (any assignment to a name makes it local), but there was a decision made that only the outer function can change the binding. Remember that one invocation of the outer frame can manufacture any number of instances of the closure (each with different parms), and any of these could be called recursively or re-entrantly in different threads, or they could call each other, and they all share the same cell from the original call to the outer function. Prohibiting them from shooting things out from under each other doesn't seem like a bad idea, and you still have a way to share changeable state if you choose so to do.


This is largely an academic discussion; I'm not suggesting changes to the article. If Python's identity as a language supporting closures does come into question, however, maybe this will head it off. --Pgroce 14:26, 18 May 2006 (UTC)[reply]

Removed "merge this with Function object" note

Closures are a critically important concept in programming languages (and computer science) and definitely deserve their own separate article. They are different from Function objects, despite the fact that the two are sometimes confused.

First, it does not concern us if a topic is imporant or not. If there is no article named closure, it would never mean that closure is an unimportant topic as long as the topic is well covered. Second, it is not clear to me the difference between the two, and since the "current" content of this article is similar to that in function object, I suggest we merge the two. -- Taku 07:45, Jun 8, 2005 (UTC)
What a silly remark is that! Why does the importance of a topic "not concern" you? Closures are an immensely important aspect of computer science, and they have nothing in common with function objects. The very minute the page on closures loses its page, I will make a new one. Wouter Lievens 09:05, 8 Jun 2005 (UTC)
Because if a closure is not an obscure topic (which it is not), we still have to cover it. I am not saying this is not important so we have to merge it with the other. It's about overlap. For example, the example given in this article resembles the idea of a function object. -- Taku 09:18, Jun 8, 2005 (UTC)
If the example is bad, then it needs to be rewritten. It doesn't mean the article has to be merged with an unrelated random other article. You might as well merge it with Lambda Calculus. Also, the example isn't a bad one, and it doesn't even closely resemble a function object, as it is expressed in ML, which isn't object-oriented. If in your view closures and function objects are the same thing, you need to get your concepts straight. Wouter Lievens 10:15, 8 Jun 2005 (UTC)
From my point of view, keeping Closure as its own topic is useful from a searching perspective. I'm realatively new to computer science concepts, and when I came across 'closure' repeatedly in literature (and without a definition), a search on Wikipedia was immediately successful. If you don't already know that a closure is related to a function object, it would be a bit harder to find. The articles should definitely reference each other; something like "A closure is very similar in most respects to a function object" in this article, and "Function objects are related to the more general concept of a closure" in the other. From what I can tell of those to articles, they are separate (though related) things, and seem to deserve separate treatment. RadiantMatrix 20:27, 23 Jun 2005 (UTC)
My concepts of function objects and closure are those put in each article.
a closure is an abstraction representing a function, plus the lexical environment (see static scoping) in which the function was created, and its application to arguments.
A function object, often called a functor, is a computer programming construct allowing an object to be invoked or called as if it were an ordinary function, usually with the same syntax.

The definition of a closure awafully resembles that of a function object in Java, for instance. Take this:

interface Function {
  public int map (int y);
}
final int step = 2;
new Function () {
  public int map (int y) { return y + step; }
}

I am not suggesting the example in the article is bad. It shows what is a closure. And I am still waiting to see what is a difference. I can't find this anywhere yet. Finally, a function object is certainly not limited to object-oriented languages. I think it's an old concept originated in functional programming. Maybe I am missing something. -- Taku 11:41, Jun 8, 2005 (UTC)

A function object is something you create in object-oriented programs to make up for the lack of proper first-class and higher-order functions (i.e. closures). OOP languages that support closures (e.g. Smalltalk) typically do not use function objects (as shown in the example), because the presence of closures removes the need for function objects. However, as closures in such languages (e.g. Smalltalk blocks) are modelled as objects, they do resemble function objects. But the typical languages where function objects are used (such as C++ and Java) do not support lexical environment closure, and thus function objects are not equivalent and not even related. The key feature of a closure is the environment link. A function object in C++ can be best compared to a function pointer in C, in that it can be invoked and passed around dynamically. Closures are not supported in C++ because the language's activation record model is entirely stack-based. Java anonymous inner classes fix this halfway by providing syntactic sugar for using final variables in the closure, but these are in fact translated to parameters to the anonymous class. So to summarize: a function object is an object that behaves semantically (and sometimes syntactically) like a function, whereas a closure is a function extended with its environment of definition. Some function objects may be in fact closures, and some closures may in fact be objects (Smalltalk blocks), which means the two concepts may overlap. But they definately don't have to. Wouter Lievens 12:43, 8 Jun 2005 (UTC)
Good now I see your distinction. But I don't think this is large enough to warrant two separate articles. Obviously not everyone sees this distinction, for one. It is true that some closures that are never function objects, and some function objects have no relation with closure. But it does not mean they cannot be discussed in one article. Certainly, the usage of a function object is similar to that of closure. And I still think, like the above post, discussing the two concepts is helpful for readers. Take negative and non-negative numbers. A negative number is never positive, but discussing two numbers in one place helps readers understand the two concepts. If you think a term function object would cause confusion, we can simply rename it. -- Taku 23:15, Jun 8, 2005 (UTC)
I think each distinct subject deserves its own page. What can possibly be gained from merging these (rather unrelated) pages together? More precisely, it would introduce serious problems in terms of categorization. For instance, function object would belong in [[Category: Object-Oriented Programming]], whereas closure (computer science) definately does not. In analogy, we might as well put President and King in the same page, as they're related too (both are heads of state). Wouter Lievens 09:56, 22 Jun 2005 (UTC)
Another reason why these can't be merged, is because of terminology tradition. Your average C++ or Java programmer has never even heard of a closure, whereas the average Scheme/Lisp/ML programmer will think function object is a contradiction in terminis. Wouter Lievens 10:01, 22 Jun 2005 (UTC)
All right. I am convinced. If not merger, we at least mention how the two differ somehow. -- Taku July 5, 2005 01:31 (UTC)

Implementation, actors, concurrency

Carl: thank you for clarifying that.

One query, though: I'm not sure if the actor model reference belongs under the heading "implementation"? ISTM that actors are related to more to abstractions than implementations. Also, the concurrency issue might deserve a section of its own, which could then also be expanded to cover the approaches taken in practice by languages like Erlang and Concurrent ML. I'll leave things unchanged myself till I've had a chance to read Clinger's thesis, though. Haeleth 15:49, August 22, 2005 (UTC)

For now I changed the section title to "Implementation and Theory"--Carl Hewitt 16:53, 22 August 2005 (UTC)[reply]

Focus on state

It seems to me that the focus on "storing information" is just wrong. Am I crazy? Google says:

Definitions that do not mention storing information: [3] [4] [5] ([6]--see function closure) ([7]--see lambda) ([8]--see lexical closure) [9].

Definitions that do mention storing information: [10].

Definitions that sort of imply it: [11].

In my experience, a closure is (a) in source code, a syntactical construct where the code for a function appears, and it has open variables that are declared not within the function, but outside, in its lexical scope; (b) at run-time, the implementation of that function, consisting of some code and a pointer to the environment (where the open variables live at run-time). You can assign to open variables in some languages, true; but a lot of functional languages don't let you assign to local variables at all; this is hardly the essential, defining feature of closures. -- Jorend 21:13, 10 January 2006 (UTC)[reply]

Yeah, I also found the focus on state rather weird, especially in the introductory paragraph. -Chinju 03:22, 24 January 2006 (UTC)[reply]

Okay, I changed it. The current page is worse stylistically, but at least it's correct. And the new examples have some meaning. Maybe someone with more time and writing talent can help clean up my terrible wording. Jorend 00:15, 16 February 2006 (UTC)[reply]

closures in prolog??

c'mon, what are you tlaking about? I will kindly remove the reference if not explained =) -- Euyyn 7-2-05

Fix non-breaking space

In "Closure-like constructs in other languages" section, I tried adding a non-breaking space so that "void *" would appear in the same line. It worked fine in preview mode, but not in the actual article. I know this is pretty minor, but still if someone with better understanding in HTML or Wiki can fix it that'd be great. madoka 09:25, 25 November 2006 (UTC)[reply]

What closures aren't

At the moment, the article claims that:

C# 2.0 has "anonymous methods" [2] which can use variables from enclosing scopes. However, these are not fully featured closures because the lexical binding of the "return" statement is hidden inside of an anonymous method.

And the same argument was used to remove my ECMAScript examples. Now, I don't think it makes sense at all. The definition of the closure is given in the very first sentence of the article, and it states that "closure is a function that refers to free variables in its lexical context". It does not say anything about return (or control flow in general). Many languages which are listed as having full-featured closures do not have any equivalent of "return" at all (e.g. Scheme, Haskell...). Furthermore, if closures would be able to return from the enclosing scope, what meaning would it have when the scope has been returned from already? Consider this example in pseude-JS:

 var bar;
 function foo()
 {
    bar = function() { return 1 from foo; }
    return 2;
 }
 x = foo();
 y = bar();

What is the final call to bar() supposed to do? Would it even return control to the caller, and if no, then where would it go? And if yes, what would be the values of x and y?

[NealGafter: Depends on your language. In scheme the continuation is resurrected (you simulate return using a continuation). In the proposed Java language extension, an exception is thrown. In most languages with closures, there is no issue because there is no return statement, as you observe. The reason the definition doesn't mention "return" is that the definition was written using the terminology appropriate for one particular language, Scheme. The term "closure" itself was brought about to help describe the semantics of lambda in Scheme as contrasted with all previous lisp dialeces. In Scheme variable bindings are the only lexically scoped semantic concept. In languages with additional lexically scoped semantic concepts those need to be captured by the closure as well. I count about 10 or 11 for Java, for example. I'll publish a more detailed explanation in the next week or two.]
If you want to try it out and see, I suggest you try Smalltalk or CommonLisp, both of which have full closures and a "return" form that is lexically captured by the closure. Gafter 19:56, 28 January 2007 (UTC)[reply]
"In scheme the continuation is resurrected." - closures are not continuations. The very difference between them is that continuations also capture the control flow up to the point of the capture, while closures do not. It would seem to me that "return" is precisely that, control flow - that it is explicit in C#, and implicit in Scheme, doesn't change its meaning. -- int19h 07:49, 28 January 2007 (UTC)[reply]
"The reason the definition doesn't mention "return" is that the definition was written using the terminology appropriate for one particular language, Scheme." - Then the definition should be changed. -- int19h 07:49, 28 January 2007 (UTC)[reply]
The definition came about in a particular historial context; changing it would be rewriting history. Admitedly that historial context should probably be explained in this article. I am working on something that might be suitable for that purpose. Gafter 17:17, 28 January 2007 (UTC)[reply]
Indeed, I agree that closures are historically defined like that. And according to that definition, both C# and ECMAScript have closures - which is precisely my point. -- int19h 18:35, 28 January 2007 (UTC)[reply]
The definition wasn't written referring to the concept of "variable" in the ECMAScript specification, it was referring to the concept of "variable" in Scheme - in other words, all lexically scoped semantic constructs. Gafter 20:02, 28 January 2007 (UTC)[reply]
Erm? Here's the definition of variable from R5RS:
An identifier that names a location is called a variable and is said to be bound to that location.
I find it rather applicable to JavaScript variables as well, and at the same time, quite certainly not referring to "all lexically scoped semantic constructs". -- int19h 06:59, 29 January 2007 (UTC)[reply]
"In languages with additional lexically scoped semantic concepts those need to be captured by the closure as well." - if this goes into the article (and if you insist on C# 2.0 & JavaScript closures not being closures, then it should), I'll ask for it to be sourced. Personally, it's the first time I hear that closure should capture more than variable bindings. -- int19h 07:49, 28 January 2007 (UTC)[reply]
Agreed, and for that a reference to Guy Steele's "lambda the ultimate..." papers might be appropriate. Gafter 20:02, 28 January 2007 (UTC)[reply]

Now, of course, if "bar" in the example above is a continuation, it all makes a lot of sense. But closures aren't continuations. They only close over the lexical variables, not the entire environment.

Therefore, I propose to remove the statement that C# anonymous methods are not closures, and move C# to the appropriate section (languages with full support for closures). -- int19h 07:09, 27 January 2007 (UTC)[reply]

[NealGafter: It is in part because C# 2 does not have closures that they are adding lambda expressions in C# 3! If you wish to clarify that it is the proposed C# 3 language that you're referring to, then it does indeed make sense to move it to the list of languages with closures.]
What exactly do lambdas in C# 3.0 add over anonymous methods in C# 2.0 except for shorter syntax thanks to type inference? -- int19h 07:49, 28 January 2007 (UTC)[reply]
It isn't what they add that is important, it is what they take away: the return syntax. Gafter 20:00, 28 January 2007 (UTC)[reply]
On a side note, lambdas in C# 3.0 do not take away "return", they only make it optional. You can write x => x + 1, but you can just as well write x => { return x + 1; }, which is the same thing. -- int19h 07:20, 29 January 2007 (UTC)[reply]
As said below, it is trivial to prove that "return" can be treated as nothing more than syntactic sugar. If exceptions or continuations are present in the language, it is particularly obvious that either can be used to express semantics of "return" (as well as "break" & "continue", for that matter), but even so neither is required. Obviously, syntactic sugar does not add nor remove any expressiveness to the language. -- int19h 06:51, 29 January 2007 (UTC)[reply]

Despite this being a rather interesting discussion, it does drift away from the issue, so let me get back to that. The consensus in the field, so far as I'm aware, is that ECMAScript at the very least has closures in full sense of the word. However, you insist that:

In languages with additional lexically scoped semantic concepts those need to be captured by the closure as well.

Now, can you please provide a reference to a reliable source to back this, and in particular, the "need" part (i.e. that if a closure does not capture these, then it cannot be called closure)? -- int19h 07:06, 29 January 2007 (UTC)[reply]

It would be nice if JavaScript had the more powerful kind of closure that's in the Java proposal, but this article won't convince any JavaScript programmer that JavaScript doesn't have closures. Given that JavaScript is by far the most widely used language whose programmers believe it has closures, it seems futile to define the word in a way that excludes them. --Michael Geary 08:05, 29 January 2007 (UTC)[reply]

I've posted a request on LtU forums to comment on this discussion. Hopefully some qualified outside opinion will help us reach a consensus quicker one way or another. -- int19h 08:51, 29 January 2007 (UTC)[reply]

Well, it would seem that the exlcluding definition of closures as proposed by Neal is rather not universally agreed upon. This isn't to say it's not valid as such - only that "closure" is often meant to be something different. To that extent, my proposals are:

I've been following the discussion on LtU and would concur. Neal's comments, especially his blog entries, were highly informative and enlightening and he may well hold the correct view of what closures should be. However he is very much a part of a debate on which Wikipedia should not be taking sides.A B Carter (talk) 20:58, 31 January 2007 (UTC)[reply]
  • Broaden the definition of closure in the very first sequence. It should refer to lexically-scoped names, and not just variables, to avoid confusion later.
You might want to start in very general terms: define a closure as a function and an environment that allows for the evaluation of the function. Keep the second sentence and then mention that what a function must refer to in the environment will depend upon the language. As far as I can see most text-book definitions of closures still express it in terms of closing off "free variables". I'm not too sure Wikipedia should stray to far from this. A B Carter (talk) 20:58, 31 January 2007 (UTC)[reply]
  • Explain the issues with interpretation of the broadened definition. Describe the commonalities inherent in all approaches (e.g. variables are always captured), and list the possibilities for variation (e.g. such as capturing scope for flow control statements). Explain the advantages and disadvantages of each approach on concrete examples (Scheme, Smalltalk, ECMAScript and Haskell should allow sufficiently broad comparison to explore all nuances). Also explain what minimal requirements are expected of closures, and give a few examples of constructs in popular languages that seem to be close but fall short of the common definition of closure (Java inner classes in particular).
  • Get rid of the lists of languages with / without closure. I don't think they add any encyclopedic value to the article. Particular languages can be served as illustrations on specific points, but otherwise they are irrelevant to the subject of the article. There could be a separate category for "languages with closures", though I'm not certain that even that would be of much practical use.
  • Provide examples in ECMAScript alongside the present Common Lisp ones, to aid (possibly the majority of) readers unfamiliar with Lisp. Personally, I would also favor redoing the CL examples in Scheme - it's cleaner and easier to understand and read, as well as more widely known (due to it being part of the CS curricilum in many places).
Scheme strikes me as the obvious choice given the history of closures. I'm fine with an example in ECMAScript; however just curious,what would you thinking of giving an example in Perl instead. A B Carter (talk) 20:58, 31 January 2007 (UTC)[reply]

Any suggestions/corrections/objections? -- int19h 19:26, 31 January 2007 (UTC)[reply]

I think this general approach makes sense. I suggest two or three references to support the comment about return needing to return from the enclosing method: (1) Tennent's "Principles of Programming Languages" and specifically his Correspondence Principle (2) Guy Steele's "Lambda the Ultimate Imperative", and possibly also (3) My article on this specific topic, quoted earlier: http://gafter.blogspot.com/2006/08/tennents-correspondence-principle-and.html . I'm also happy to have any relevant text copied out of http://gafter.blogspot.com/2007/01/definition-of-closures.html (or a link to it as a reference). As for another language, I think it would be better to select a language that fully supports closures by all definitions, such as Smalltalk. I don't know Perl well enough to judge that. As to languages with closure-like constructs: it is valuable to have many of these language on the list described as they are. For example, Java's anonymous inner classes are not lexically scoped (names are first resolved in the scope of the class being constructed rather than the enclosing scope). 03:43, 1 February 2007 (UTC)
It's clear that the intent of int19h's use of ECMAScript was to provide a couple simple examples of closures in a well known language. That was why I mentioned Perl and why I think Smalltalk is in pretty much the same boat as Lisp. I don't think the language has to have the full featured support that you're after so long as the core notion of closing over free variables is supported. I think there was clear support for this reading of ECMAScript inthe LtU thread. A B Carter (talk) 02:03, 1 February 2007 (UTC)[reply]
Different question: could you supply a page number where return is specifically talked about in "Lambda the Ultimate Imperative"? Not doubting you, just really curious. A B Carter (talk) 03:15, 1 February 2007 (UTC)[reply]

On ECMAScript examples

Regardless of whether ECMAScript closures are "true" closures or not, I don't see why it should preclude the ECMAScript examples from being included in the article. They are faithful translations of the corresponding CL examples, nothing more, nothing less, and they do get the point across - what more do you need? Also, it should be understood that many people who come here to familiarize themselves with the concept of closure do not know either CL or Scheme, and they should not be forced to learn either. Whereas ECMAScript (or rather its JavaScript incarnation) is much more well-known, and immediately readable for any person with even basic C/C++/C#/Java knowledge. In fact, the reason why I put those examples there was that one of the people whom I directed to this article when asked what a closure is, complained that Lisp examples were utterly unreadable - which is no surprise, that coming from a C# programmer. -- int19h 07:55, 28 January 2007 (UTC)[reply]

It's funny, I use closures in JavaScript every day. They are one of the most useful and powerful features of the language, and they seem as natural to me as an if statement. I can explain them clearly in just a few sentences. But I have NO IDEA what this debate is about. JavaScript closures "do not capture the binding of 'return' from the enclosing context"? What is that supposed to mean? Could somebody give me an example of how JavaScript closures would work if they did this? Type real slow so I can understand it. :-) As it is right now, this article is the last place I'd ever send a JavaScript programmer if they wanted to understand closures. --Michael Geary 08:12, 28 January 2007 (UTC)[reply]
Simply put, it means that return inside the closure would return not from the closure itself, but from the function inside which that closure was created. This is the take on closures the Java guys did, and you can read more on it here - you may notice an oddly familiar name in the list of authors there as well. ;)
Of course, such approach is only meaningful in a language which distinguishes closures from "normal" functions (Scheme doesn't, for example, and neither does ECMAScript), and it seems to be conceptually weak in a sense that it does not go well with nested closures (what if I don't want to return from the topmost enclosing non-closure, but from a closure 2 levels up? and if I can't, why not?). -- int19h 08:53, 28 January 2007 (UTC)[reply]
"what if I don't want to return from the topmost enclosing non-closure, but from a closure 2 levels up? and if I can't, why not?"
I think JavaScript lets you do that, but through an improper use of a differently aimed construct, so I'm writing this just for comparison sake (since this method could make one of the javascript examples to behave like the Smaltalk one on the "^" operator). Furthermore, this method requires an explicit handling of the "exit point", yet it's very easy and maybe obvious: just use throw instead of return and capture the result as an exception, wherever you need it.

Of course, that's not the right way one should use an exception-handling construct, so that'd be perhaps misleading/confusing in a real script, yet that should work as wished. And of course, great troubles might arise when using such an improper return method combined with regular exceptions, yet it's possible to make it work: in example, one could wrap the "exception-like" result into a certain "class" object and verify whether a captured exception is an instance of such a "class". So doing, the throw keyword whould behave quite like the ^ operator in Smalltalk, while return whould be the equivalent of a "normal" procedure end.--151.74.14.142 (talk) 01:21, 2 April 2008 (UTC) xeal[reply]
In languages with full support for closures, you can't "return" from any closure, no matter how many levels up, except by providing a final expression. Providing an example of what it would look like in Javascript would require that I make up a new syntax. For that, I suggest you see the proposed Java extension. Gafter 17:14, 28 January 2007 (UTC)[reply]
It's fairly obvious that any ECMAScript closure with "return" can be rewritten in such a way that return only occurs in a place where a final expression would be in other language. In that sense, the difference is syntactic, not semantic - "return" is just a syntactic sugar, no more. Thus, "return" in ECMAScript does not allow one to do anything one couldn't do in Scheme, nor does it make ECMAScript closures any less expressive then Scheme closures are. One can conclude that, if Scheme closures are "full-featured", then so are ECMAScript ones, since they are completely functionally equivalent. Either that, or we have a case of double-standard here... -- int19h 18:51, 28 January 2007 (UTC)[reply]
A programming language's expressive power is not determined by what one can compute, but rather what kinds of abstractions one can express. Most modern languages are Turing-complete and can therefore compute the same set of functions. I suggest you read Guy Steele's "lambda the ultimate..." series of papers to understand what is lost when not all lexical bindings are preserved. Alternatively, I suggest you attempt to write a function in JavaScript that can be used in place of the built-in if-then-else statement (of course the invocation syntax would differ; that's OK). You'll find you can't. Gafter 23:51, 28 January 2007 (UTC)[reply]
"Alternatively, I suggest you attempt to write a function in JavaScript that can be used in place of the built-in if-then-else statement (of course the invocation syntax would differ; that's OK)."
I'm not sure this is exactly what you're asking for, but at first glance I'd write the following:
//
// Implementing the if-else construct as a function which takes three functions as arguments.
// The first function passed is the condition to be tested, and is expected to evaluate as
// true or false; the second one is the block to be executed if the test condition evaluates to
// true, and may optionally return a value; the third is the alternative block to be executed
// and may optionally return a value. One of such optional values is returned (null or undefined
// if none is supplied). The calling function might assign the result value to a somewhat variable,
// or let the function-block to handle it. A preferred way to call this function and easily handle
// variables as in a standard if-else statement is throughout internal functions, as shown in
// the alertMax function below.
//
function if_else(ifcond, ifblock, elseblock){
	var result = null;
	var doIF = ( ifcond() ) && ( result = ifblock() ); //when ifcond evaluates to true ifblock is
                                                           //called and results assigned to result,
	var doELSE = (! ifcond() ) && ( result = elseblock() ); //otherwise elseblock is called in
                                                                //the same fashion.
	return result; 
}

//
// Comparing values by calling if_else function with opportune parameters.
//
function alertMax( a, b ){
	var max = if_else(
		function(){ return (a >= b); },
		function(){ alert( a + " is greater than or equal to " + b);  return a; },
		function(){ alert( b + " is greater than " + a);  return b; }
	); //note functions passed as ifblock and elseblock alerts different text;
           //this shows the alternate execution of statements-equivalent functions works.
	alert("Max computed value is: " + max);
}

alertMax(6, 5);
alertMax(8, 9);
--151.74.14.142 (talk) 01:21, 2 April 2008 (UTC) xeal[reply]
I can, however, write a function in JavaScript that can be used the same way Scheme's if or cond expression can be used. That's what my point was - that JavaScript closures can express all abstractions Scheme closures can. -- int19h 06:45, 29 January 2007 (UTC)[reply]
I'd very much like to see your javascript "if". I think I can demonstrate that it doesn't work. Or do you intend to restrict your clients to a subset of the language that lacks Javascript's "return"? Admittedly, if you pretend this part of the javascript language doesn't exist, then there is no issue. 01:19, 30 January 2007 (UTC)
That was precisely what I meant when I wrote about "a function in JavaScript that can be used the same way Scheme's if or cond expression can be used".
It should be noted that you're effectively doing the same thing from the other end, by restricting your clients to a subset of the language when writing closures, by not giving them the same convenience they get when writing top-level methods (since they cannot return from the middle of the closure to the outer scope anymore). This stems from the fact that closures are simply not the right tool for the job - what you need to emulate control structures is blocks, Ruby-style. That way you get a structure which does not "rebind" return and other similar keywords from the outer scope, but that cannot outlive the scope it was created in either (so there's no possibility that it will be called when there's nothing to return from anymore), thus not a true closure. Well, in Ruby you can cheat your way around it, but at least you have to do that explicitly (by proc'ifying the block to an object). -- int19h 05:39, 30 January 2007 (UTC)[reply]
I would certainly like it if I could write my own control flow structures in JavaScript as I used to do in FORTH. But you won't convince me, or any other experienced JavaScript programmer, that the language lacks closures. Ain't gonna happen. Sorry! :-) I've often heard the phrase "dictionaries are descriptive, not prescriptive." Doesn't the same principle apply to encyclopedias? --Michael Geary 08:13, 29 January 2007 (UTC)[reply]

Sidestepping the above the theoretical arguments real quick, I must say that I find the ECMAscript examples to be very illuminating, more so than the scheme/list ones (which are important in their own right of course). Regardless of whether the ECMA examples are "pure" in the language design sense, they definitely help bridge the gap for those used to procedural languages. Bravo to whomever put them in. Pkcirtap 00:44, 8 March 2007 (UTC)[reply]

What Are Closures

I’ve been lurking for the past few days trying to understand the discussion regarding closures are and examples of them. There are still a number of things I'm trying to figure out but here are some observations:

  1. The core notion of a closure is an implementation concept rather than a language feature.
  2. The concept of a closure is quite old, dating back at least to the mid 60’s with Peter Landin’s work on ISWIM and the SECD machine. Guy Steele was like twelve then.
  3. Scheme was designed with closures as an explicit feature of the language. Since then many languages have incorporated closures as a feature.
  4. Consequently a language can have higher-order functions that are implemented with closures, but not have closures as an explicit feature of the language.
  5. While the basic meaning of a closure is fairly clear-cut and unambiguous, how the concept appears within a particular language is going to depend on that language. How it appears in Scheme, where it is one of the fundamental tools of abstraction, may be different than how the concept appears in Java, where it will play a more auxiliary role.
  6. In general worry less about what “Full featured closures” are and just talk about, and provide examples of, how the concept is used in various languages. Pursuing the former is going to lead to increasingly contentious debate, while the latter would provide a real service to anyone trying to understand what closures really are.
  7. If progress is going to be made with this article, everyone is going to have to begin providing citations to back up any points being made. And not just, "Look at the Lambda Pages", but something like chapter and verse. It keeps us honest and we all learn. For example, my claim in Point 2 above is substantiated by looking at Peter Landin’s “The Mechanical Evaluation of Expressions”, pages 16-17.

A B Carter (talk) 19:34, 29 January 2007 (UTC)[reply]

Closures are definitely a language feature, not a implementation concept: they define the semantics of nested functions. (At the implementation level, closures need not even exist at run-time: techniques like lambda lifting can transform them all into simple global functions at compile-time.) --Piet Delport 22:26, 31 January 2007 (UTC)[reply]
Here’s my take: at their most abstract a closure is a construct consisting of a function and an environment within which the function can be evaluated when called with arguments. Historically the concept first arose in implementing and providing operational semantics for functional languages. For example, Peter Landin’s ISWIM contains no explicit reference to closures because it’s a direct extension of the lambda calculus, but the SECD machine used for evaluating ISWIM requires a notion of closure. For more along this line see [12] It was only later that closures became an language feature.
My original statement was a bit too pat since closures are a language feature. I wanted to emphasize the historical context because I had mistakenly thought gafter was implying that closures began with Scheme. I think where we may agree is with the statement that closures are essentially a semantic concept. A B Carter (talk) 02:32, 1 February 2007 (UTC)[reply]

Please provide counter-examples

What is it about, for example, C, which makes its normal functions not closures? Given in one file:

int foo;
int setFoo(int x) { foo = x; }
int mulFoo(int x) { return foo * x; }

and in another:

#include <stdio.h>
int main() { int foo; setFoo(4); foo = 3; printf("%d\n", mulFoo(2)); }

you get: 8, not 6.

How is that different? (that is not a rhetorical question)

(note that C functions can be passed around just like any other object in C) --vstarre 21:37, 31 January 2007 (UTC)[reply]

Your example doesn't have much to do with closures... that's just normal file (compilation unit) scoping in action.
Closures, roughly speaking, are nested functions with lexical scoping: since standard C doesn't even allow nested functions to begin with, the question of whether they're closures does not arise. (Some compilers, like gcc, do provide language extensions for nested function, though.) --Piet Delport 22:11, 31 January 2007 (UTC)[reply]

A counter-example:

function foo(x)
{
  return function(y) { if (y == null) { return x; } else { x = y } };
}

f1 = foo(1); f2 = foo(2);
print(f1(), f2()); // 1 2
f1(3);
print(f1(), f2()); // 3 2
f2(4);
print(f1(), f2()); // 3 4

Fancy doing that in C... ;) -- int19h 07:23, 1 February 2007 (UTC)[reply]

First, let's convert your example into scheme, since I have no idea what language you were using before:
(define (foo x) (lambda (y) (if (null? y) x (set! x y))))
(define f1 (foo 1))
(define f2 (foo 2))
(define (stat) (display (f1 '())) (display '" ") (display (f2 '())) (newline))
(stat) ;1 2
(f1 3)
(stat) ;3 2
(f2 4)
(stat) ;3 4
Next, we write the counter-example in (non-standard, but gcc-accepted) C:
#include <stdio.h>
int (*foo(int x)) (int y)
{
    int bar(y) {
        if (y == 0) {
            return x;
        } else {
            x = y;
            return x;
        }
    }
    return bar;
}

int main()
{
    int (*f1)(int y);
    int (*f2)(int y);

    f1 = foo(1);
    f2 = foo(2);
    printf("%i %i\n", (f1)(0), (f2)(0)); // UNDEFINED, probably 2 2
    (f1)(3); // UNDEFINED, probably SEGFAULT
    return 1;
}
In the C example, it appears bar is being stored on the stack (I did not expect that), so the pointer is technically out-of-scope as soon as it is returned. Using valgrind, however, you can see that after exiting from printf, dereferencing f1 results in garbage being executed as instructions.
Note that the definition of closure from the article does not indicate that a closure must be returned from another function. Ruby blocks, for example, are considered closures even when they're defined in the outermost scope. Trying to do anything like that in C, though, just makes it explicite that f1 and f2 use the same (global) x.
None of this is yet suitable for inclusion in the article, though. How might we rephrase/summarize this so we can provide a "This is a closure" vs "this is not a closure" section in the article?
Note that besides "you can't define them at run-time" (which seems like a silly thing to have a seperate word for, and not what people use the word "closure" to mean..) and "you can't return them from another function" (which seems like an entirely separate issue), I am still somewhat unclear about what "closure" is supposed to mean :/ —The preceding unsigned comment was added by 68.219.59.120 (talk) 18:14, 1 February 2007 (UTC).[reply]
--vstarre 17:12, 1 February 2007 (UTC)[reply]
The language I used was ECMAScript. With regard to closures at the outermost scope - they are indeed closures (since they do capture all bindings in their lexical scope - in their case it just happens to be all globals), and in that sense C functions are also closures. When we speak of language supporting closures or not, though, we usually mean by that the ability to create a closure in any lexical scope.
Agreed, if a language can't close over a function using a non-global scope, then it is essentially using dynamic binding.A B Carter (talk) 12:40, 2 February 2007 (UTC)[reply]
Reflecting on that, it seems that it doesn't really make much sense to speak of language supporting or not supporting those, since what it is really about is having functions as first-class values or not. On the other hand, informally, this sort of thing is widely referred to as "closures", so there has to be something here on that as well. I'm kinda lost on what to do with this issue, to be honest. -- int19h 18:47, 1 February 2007 (UTC)[reply]
In many languages the concepts of closures and first-class functions are closely related because closures are used to implement first-class functions. However closures are used for a number of things other than creating first-class functions and you can have first-class functions without having closures. A B Carter (talk) 12:40, 2 February 2007 (UTC)[reply]
Well, I've read for example that pre-scheme lisp did not support closures (though now all lisps do). Perhaps we could give an example of pre-scheme lisp vs modern lisp? --vstarre 23:34, 1 February 2007 (UTC)[reply]
I don't know the history of Lisp all that well, but it is probably refers to older Lisps using dynamic rather than lexical scoping. Since definition of closure refers to lexical bindings, it simply doesn't make sense in a language with only dynamic scoping. -- int19h 07:16, 2 February 2007 (UTC)[reply]
AFAIK Scheme was the first version of Lisp to use lexical binding by default. You could provide examples of how first-class functions are created in pre-Scheme Lisp and Scheme, but this would just be illustrating the funarg problem. Also, pre-scheme list did have a mechanism called, oddly enough, FUNARG that forced lexicla binding when creating a function. A B Carter (talk) 12:40, 2 February 2007 (UTC)[reply]

Rewrite of Introduction

I rewrote the introduction based upon recent discussion and int19h's proposals. Please this is nothing more than a provisional attempt to articulate my own thoughts about closures and get some feedback from others. I have little invested in these specific words and I'm happy for this to be completely overhauled. However there are a few key aims that guided me that I do think are important:

  1. Start with the most general definition possible, one that allows for the idea that a closure may be more than simply binding the free variables of a functon.
  2. Quickly provide some basic characterization that can be understood with a minimal understanding of programming language.
  3. Keep the typical example because it captures the notion implied by many text book definitions of a closure.
  4. Defer more technical discussions of closures to a yet to be written Overview section.

A B Carter (talk) 14:32, 4 February 2007 (UTC)[reply]

I think you've done an excellent job. Gafter 07:31, 16 February 2007 (UTC)[reply]

Thanks for the comment. It means something since even after more than a month of research I still feel a bit wobbly about the concept. In this regards I'm still hoping to get a specific citation from you for "Lambda the Ultimate Imperative". Just which parts of the paper are directly relevant to what we've been talking about? A B Carter (talk) 18:04, 16 February 2007 (UTC)[reply]

Intro is too confusing and inaccurate

The introduction is somewhat confusing and inaccurate, it seems to me. The italicized portions below are from the intro; interspersed are my comments.

In computer science, a closure is a semantic concept referring to a function paired with an environment.

No, a closure is a function defined in a non-null lexical environment. (And as such, closures can't really exist in languages that don't support lexical scope.)
I don't think the disagreement is one of content, but of expression. There is nothing in the actual statement that is meant to disagree with yours. Your definition is definitely more precise. The problem for me was that I wanted to start with a definition that was fairly general and didin't introduce other notions that might require explanation. One of the criticisms of this article was that it had become too technical. A B Carter (talk) 14:04, 16 April 2007 (UTC)[reply]

When called, the function can reference elements of the environment required for the function’s evaluation.

True enough, because those variables are in scope; it's more interesting though that other code cannot access those variables, since they are only in scope for the enclosed function(s).
This is interesting because it lets you build objects with private data members out of closures.

Typically, a closure occurs when one function appears entirely within the body of another, and the inner function refers to local variables of the outer function.

This is unnecessarily limited. For instance, a function can be defined inside a lexical environment other than an outer function, such as a let. The typical introductory example is (in Common Lisp):
(let ((counter 0))
(defun count-up ()
(incf counter)))
This defines a procedure count-up which will return 1 the first time it's called, 2 the next time, and so on. And other code can't get at the counter variable.
Agreed, and this is why I said "typically", implying that this was not the only way a closure may arise. If you don't like the word, "typical" that's fine. My own experience has been that this is the most common way closures are used. Happy to be corrected here.A B Carter (talk) 14:04, 16 April 2007 (UTC)[reply]

At runtime, when the outer function executes, a closure is formed, consisting of the inner function’s code and references to any variables of the outer function required by the closure.

This is not necessarily true, depending on the language implementation. Not all the world's an interpreter. As noted above, the association of closures with inner and outer functions is misleading.
I could easily be mistaken here, but I was not implying that closures only exist in interpreted language, and don't quite see how I was implying this in the example. The point would be that in compiled code the closure was only created at run-time. A B Carter (talk) 14:04, 16 April 2007 (UTC)[reply]

The exact nature of a closure's environment and the relation between this environment and its associated function will vary from language to language and depend upon both the features of the language and how closures were implemented.

Obviously true, but too wordy.
Originally I would have agreed with you here. But I made this change after the extensive debate concerning closures in Java. What came out of it was a need to emphasize that the nature of closures could vary substantially from language to language. A B Carter (talk) 14:04, 16 April 2007 (UTC)[reply]

The distinguishing feature of closures is the ability to associate an "intermediate" set of data with a function where the data set is distinct from both the global data of the program and data local to the function itself.

Data in a closed-over variable isn't "intermediate" any more than any other data. The variable is in a different scope, but the data are just as first-class as any other data.
Again there is not a clear disagreement here. I use the term "intermediate" informally to make the distinction in scope. If you can think of a better term, please offer it. A B Carter (talk) 14:04, 16 April 2007 (UTC)[reply]

As a consequence closures can be used to hide state, implement higher-order functions and defer evaluation.

This is confused -- closures are often found with higher-order functions, but writing or using higher-order functions does not entail writing code with explicit closures.
I'm in complete agreement but there is nothing in the statement that implies otherwise.

All in all, it seems to me that it would be useful to refer more closely to definitions of "closure" found in actual languages that define the notion. For instance, the Common Lisp HyperSpec defines "closure" as "lexical closure", and that as follows:

lexical closure n. a function that, when invoked on arguments, executes the body of a lambda expression in the lexical environment that was captured at the time of the creation of the lexical closure, augmented by bindings of the function's parameters to the corresponding arguments.
Certainly in agreement with this, but the bulk of the article provides extensive examples. It is exactly because of the example session that there is not a clear need to examples in the intro. Moreover giving a intro definition that is specific a single language will entail much the same confusion you mention above. My thinking was to begin with something quite general and then work out the details in the examples. A B Carter (talk) 14:04, 16 April 2007 (UTC)[reply]


The notion that closures are lexical is central.

OK, I'm tempted to agree with you on this point. I would also agree that the intro is deficient because it never brings up a concept that is essential to closures. However I would like to avoid introducing the term in the very first sentence. One of the guidelines of the Computer Science Wikiproject is to make all articles are accessible as possible. This doesn't mean dumbing down the articles, but it does suggest providing an easy introduction to technical concepts.
In anycase thanks for the comments and thanks for bringing up your concerns first before making major changes. A B Carter (talk) 14:04, 16 April 2007 (UTC)[reply]


--FOo 07:36, 16 April 2007 (UTC)[reply]

Relate concept to broader semantics of "closure"?

I came here as a practitioner -- coder -- who encountered closures in Ruby manuals. It would be useful to me to be able to relate the programming concept to the broader meaning of the English word. Googling "mathematical closure" yielded an ask.metafilter.com discussion which both poses my question and provides a partial(?) answer. Brec 17:22, 25 May 2007 (UTC)[reply]

Via this discussion:

The reason it is called a "closure" is that an expression containing free variables is called an "open" expression, and by associating to it the bindings of its free variables, you close it.

—Ake Wikstrom, Functional Programming using Standard ML

(Maybe this would make a good addition to the article?) --Piet Delport 08:10, 27 May 2007 (UTC)[reply]

There are way too many external references at bottom, listing most everyone's blog entry on "How to do closures in language X (and what are they)". While a user of language X might want to know this, we should not try to anticipate every new programmer of every language. They can use Google, or one of the sites intended as indexes of PL resources, for that.

Absent strong objections, I'll remove about 80% of the external links pretty soon. LotLE×talk 18:17, 21 July 2007 (UTC)[reply]

I agree. Only the links relevant to closures as such should remain, IMO. To be honest, I'd rather get rid of all the "how to do it in language XXX" sections in the article itself as well. -- int19h 04:52, 23 July 2007 (UTC)[reply]

Firmly agreed, to both. "How to" sections have strong tendency to accrete more and more languages, as visitors notice their favored ones are missing. (Look at the state the Currying article was in recently.) —Piet Delport 01:39, 24 July 2007 (UTC)[reply]

I'm definitely in favor of also killing the "how to do it in language X" sections. Does someone else want to do that? I'd feel like I was overstepping slightly since all I've done in this particular article is delete the linkfarm. LotLE×talk 15:18, 9 August 2007 (UTC)[reply]

Closures and Objects

I don't believe the cited article, taken in context, supports the statement that closures are a better alternative to objects. It seems to say, instead, that closures and objects each have their appropriate place. If there are no objections, I will remove the second half of the following statement: "Closures can be used to implement object systems [2], and may in fact be better alternatives to objects [3]." --Akellymi (talk) 16:09, 19 February 2008 (UTC)[reply]