This article is rated C-class on Wikipedia's
content assessment scale. It is of interest to the following WikiProjects: | |||||||||||||||||||||||||||||||
|
To-do list for Closure (computer programming):
|
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?
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?
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)
Scope != closure. A scope is an environment where you can get at a particular value via a particular variable name; a closure is a coderef that remembers the lexical scope where it was born. A lexical scope arises every time execution passes into a given block (or file), but you don't create a closure (at least in Perl 5) until you take a reference to a function that uses a lexical from its environment. That function has to be able to see that lexical in order to run, so the coderef has to wrap up (a piece of) the current lexical scope along with the function. It is this wrapping of state with functionality that makes a closure. (Which is more general than objects: You can take two or more coderefs that close over the same variable, if you want.) eritain ( talk) 07:27, 26 October 2010 (UTC)
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.
That's a scope, but I'd hesitate to call it a closure. The distinctive thing about closures is that you can (potentially) take multiple references to the same sub, and get it wrapped up with a different environment each time. In this example, we know from compile time that there is one and only one %cache, so no matter how many times I say \&fib there is never a need to clarify which %cache we mean, and therefore no reason to wrap any environment with the coderef. eritain ( talk) 07:27, 26 October 2010 (UTC)
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)
Im going to add a perl example back to the page unless somebody protests. Demerphq 17:05, 10 April 2006 (UTC) Seriously? no mention at all of Perl in the article? 159.83.196.1 ( talk) 18:30, 14 May 2018 (UTC)
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)
Java has no first class functions, therefore has no closures.
Actually that java example on the anonymous class is overcomplicated for its result. The following code performs the same function without the need of creating an embedded runnable class. This is because the embedded Runnable classes run method is just called from the Thread classes run. Anyone who does threading in java knows this, which is why we can just extend thread instead of implementing Runnable. In such a case as this, it would be better formed code to just extend the thread into an anonymous, instead of creating an embedded runnable.
class CalculationWindow extends JFrame {
private volatile int result;
...
public void calculateInSeparateThread(final URI uri) {
// The expression "new Thread() { ... }" is an anonymous class.
new Thread() {
public void run() {
// It can read final local variables:
calculate(uri);
// It can access private fields of the enclosing class:
result = result + 10;
}
}.start();
}
}
76.235.207.239 ( talk) 09:11, 29 May 2011 (UTC)
Scala compiles to Java and supports Clousures. Not sure if this is an imperative language or not, but if so please append Scala to the list of "modern garbage-collected imperative languages support closures" — Preceding
unsigned comment added by
Jcalfee (
talk •
contribs) 16:47, 22 August 2013 (UTC)
Python does not have closures and shouldn't even be listed among the list of languages that do have closures, let alone used as the example language to demonstrate what they are. Using Python to demonstrate what closures are is completely misleading and damaging to a reader's understanding of what closures are. Can we just swap the example language and remove Python from the list? — Preceding unsigned comment added by Mmachenry ( talk • contribs) 06:14, 25 June 2014 (UTC)
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
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. :)
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)
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.
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)
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)
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)
Yeah, I also found the focus on state rather weird, especially in the introductory paragraph. - Chinju 03:22, 24 January 2006 (UTC)
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)
c'mon, what are you tlaking about? I will kindly remove the reference if not explained =) -- Euyyn 7-2-05
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)
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?
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)
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)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:
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)
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)
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:
Any suggestions/corrections/objections? -- int19h 19:26, 31 January 2007 (UTC)
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)
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. ;)throw
instead of return
and capture the result as an exception, wherever you need it.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// // 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);
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)if
or cond
expression can be used".proc
'ifying the block to an object).
-- int19h 05:39, 30 January 2007 (UTC)ifcond()
twice, which if ifcond()
alters any variables or calls any functions that alter anything, could result in incorrect state. Additionally, if something changes such that the second call to ifcond()
does not return the same result as the first, both (or neither) of ifblock()
and elseblock()
could be evaluated. —Preceding
unsigned comment added by
Evildeathmath (
talk •
contribs) 16:54, 17 December 2008 (UTC)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)
I'm still fuzzy on what a closure is, and I too liked the EcmaScript examples, but I have a very minor beef with one of them. The first example in the Differences in semantics section confused for an instant. I had read the x = 0 assignment, and I didn't notice the later x =1 assignment. Now, I now this is extremely minor, but I think the readability of the example increases if the initial assignment is x = 1. It seems a bit odd that its done the way it is, and rather than assume that its for no reason, I will assume that maybe I don't understand the reason. That, and my low level of understanding of the topic, keep me from editing myself. Hopefully one of the authors will read this and do the edit or explain the reasons to me (apparently I also need things to be typed slowly &8-P). Apwith ( talk) 19:29, 16 October 2009 (UTC)
I believe that putting JavaScript examples to illustrate closures is confusing at best. Whatever this article has to say on this matter is questionable. I'm not trying to convince anyone that closures do not exist in JavaScript, but I believe that whenever you are trying to emulate them you are misusing the tool. What you call functions in JavaScript are not the first order functions, they are objects with context and properties. Of course you can say it is not a requirement for the closure to not have either of these, but, normally, you don't want to have them in closure. Besides, the examples given are in general an ill-suggested practice. This is because of how the runtime is implemented and, as I've said, it's just a wrong tool / improper use - it is never a requirement in JS to use this approach, and the alternative approach would always win in terms of code readability and performance. It looks more like if someone wanted very much that closures existed in JS, and some popular libraries, like JQuery or the Closure JS "compiler", make it look like it is there, but, I think we are dealing with the case of where the term is being used improperly to describe something similar, yet not exactly the same. (The need for closures in JS is probably because of wanting to make the code shorter overall, and it is due to the nature of JS - because it should load in the least possible time).
Additionally, earlier on this page I've noted some C# programmer confusion created by Lisp examples, which is understandable, however, it is also strange that JavaScript was suggested as a better illustration, whilst closures are definitely possible in C#, which isn't a less popular language.
Wvxvw (
talk) 20:12, 12 May 2010 (UTC)
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:
A B Carter ( talk) 19:34, 29 January 2007 (UTC)
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)
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)
(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
#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; }
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:
A B Carter ( talk) 14:32, 4 February 2007 (UTC)
I think you've done an excellent job. Gafter 07:31, 16 February 2007 (UTC)
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.
When called, the function can reference elements of the environment required for the function’s evaluation.
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.
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.
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.
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.
As a consequence closures can be used to hide state, implement higher-order functions and defer evaluation.
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:
The notion that closures are lexical is central.
--
FOo 07:36, 16 April 2007 (UTC)
Ok, i don't really know much about closures, but it seems to me that this sentence is not referring to private variables, but to static ones:
Can you tell I was raised on OO? —Preceding unsigned comment added by 206.83.243.126 ( talk) 20:28, 25 June 2008 (UTC)
That metaphor about closures connected with space and time is totally useless and just confuses more the issue.
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)
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
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)
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)
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)
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)
I'm trying to figure out what the etomology of the word "closure" is in this context. Is this a Lisp started term? -- RobertGary1 ( talk) 23:12, 4 September 2008 (UTC)
What is a lexical enclosure? It should be mentioned in this article. Fresheneesz ( talk) 18:42, 28 October 2008 (UTC)
I think a small blurb about free variables is warranted. The linked article heavily concerns mathematical free variables and only has one small out of the way line saying "oh by the way free variables in computer science are references to non local variables" and that line even has a citation needed marking. My brain somehow parsed over that line and left me confused on the definition of closures for hours. 75.23.252.148 ( talk) 02:40, 8 July 2009 (UTC)
I removed the majority of the "in language x" examples from the article ( diff). As a rule of thumb, at most one example (in either Scheme or JavaScript, as per earlier consensus?) should be sufficient to illustrate any given concept: repeating it in everyone's favorite programming language just clutters the article. — Piet Delport 2009-08-25 10:57
In the "Implementation and theory" section a sentence begins "In function languages with immutable data (like Erlang),...". Shouldn't this begin with "In functional languages with immutable data (like Erlang),..."? Or am I misunderstanding, and it is correctly missing the "al"? Whoever reads this and knows, please feel free to update it if necessary, as I don't know the subject very well. -- Donkeydonkeydonkeydonkey ( talk) 19:56, 23 July 2010 (UTC)
The example given is an example of closures in C, as amended by Apple's additions to the C language, and currently under review for inclusion in the C standard. It works in pure .c files under the gcc and clang, at least on Apple platforms. The only lines in the example that use Objective-C are the NSLog statements, which could be replaced with printf statements to have a pure C closure example. It is worth renaming (and repositioning up higher) the section "Closures in C (gcc, clang)" or somesuch. —Preceding unsigned comment added by Hyperjeff ( talk • contribs) 09:23, 18 September 2010 (UTC)
I think that the complicated definition of closure in current version [13] is not explanatory, hardly understandable and must be improved. Please don't get me wrong, I do not question the correctness of the definition. It may be technically 100% right. The problem is that it does not really explains but confuses those who check Wikipedia while trying to understand what a closure is. Simply google for "closure explained", and you'll find some articles and blog posts saying more or less the same about Wikipedia's definition [14] [15] [16].
I suggest to move most of the first sentences down, and to place a simple definition from [17] instead:
A closure is a function/method that has the following two properties: * You can pass it around like an object (to be called later) * It remembers the values of all the variables that were in scope when the function was created. It is then able to access those variables when it is called even though they may no longer be in scope.
How cool is that?! Check how human-friendly and explanatory it is comparing to the current one:
a closure is a first-class function with free variables that are bound in the lexical environment. Such a function is said to be "closed over" its free variables. A closure is defined within the scope of its free variables, and the extent of those variables is at least as long as the lifetime of the closure itself.
Any thoughts on that?
Thanks! Alex Ex ( talk) 15:52, 1 April 2011 (UTC)
this
, target of return>
and break
, ...) as well. The current lead doens't mention this yet. —
Ruud 12:52, 2 April 2011 (UTC)Python 3.1.2 (release31-maint, Sep 17 2010, 20:27:33)
GCC 4.4.5 on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def f():
... x = 0
... def g():
... nonlocal x
... x = x + 1
... return x
... def h():
... nonlocal x
... x = x + 1
... return x
... return g, h
...
>>> a,b = f()
>>> c,d = f()
>>> a()
1
>>> a()
2
>>> b()
3
>>> a()
4
>>> c()
1
>>> d()
2
Agree, it's bad. One problem not addressed here is; the target audience is only experienced computer scientists. Doesn't that violate the Wiki policy of addressing non-experts first? ( "Provide an accessible overview" )...particularly in the lead section? ...with the resulting pitfall of making true statements rather than explanations or definitions. (Sometimes almost as if people were creating test questions or facts lists, or being worried about violating little nit-picky "experts," loudly-proudly waving tightly clutched brand new syntax guides.)
For example, first sentence;
"a closure ...is a function together with a referencing environment for the nonlocal names (free variables) of that function." is technically true, but it's utterly dependent on jargon and highly specialized training to have any meaning....as if a definition for already-experts...to satisfy experts...huh?
All that a typical person wants from the intro is to loosely grasp the concept of closure. Only after that required goal is met is any other goal useful or desired. The intro should concentrate on teaching, not technical correctness. There should be an opening sentence like, "The purpose/advantage of closure is..." so people have an orderly place to hang and orient the abstract definitions, --to help solidify them.
It's important to remember that many/most people come here as the result of following a hyperlink with the goal only of understanding another article. They will never read beyond the first sentence, paragraph or the lead section. In that context, hit-wise, the intro is the most valuable part of the article. See:
Wikipedia:Manual of Style (lead section)
--
69.227.84.108 (
talk) 19:42, 28 May 2011 (UTC)Doug Bashford
I came to this article because I have read statements like, "Language X has Closures," and "The Closure of function f is...," and "By line x, closure has occurred." Is Closure a noun or a verb? This article didn't clear it up at all, obviously, both, but then the first line of the abstract, treating it as a noun, keeps other parts of the abstract unclear. Someone knowledgeable should clarify this, and all editors should keep this in mind. (This is in no way a problem limited to this article alone.) -- Limited Atonement ( talk) 18:07, 30 August 2011 (UTC)
How the first paragraph reads to someone with little formal training in programming:
In computer science, a closure (also lexical closure, function closure or function value) is a function together with a NOUN for the NOUN (NOUN) of that function. Such a function is said to be "ADJECTIVE PHRASE" its NOUNS. The NOUN VERBS the NOUNS to the NOUNS in scope at the time the closure is created, additionally extending their lifetime to at least as long as the lifetime of the closure itself.
I don't really know what a closure is from this article. I read something on stack overflow ( explain JavaScript Closures to a 6 year old), and I think something like this might be more clear (if someone could make it more accurate, since like I said, I don't really understand yet):
In computer science, a closure is a function which returns another function. Importantly, the returned function has access to the variables contained in the returning function's scope. — Preceding unsigned comment added by 204.87.16.4 ( talk) 18:50, 20 September 2011 (UTC)
Please note that I have never written a line of code in python and have no idea how variables are initialized and values assigned. But I am worried that the following snippet that is used as the first example in the article may have an error. Can someone please help me understand where the value for 'y' is initialized in the incrementer() function? I understand that the lambda function would have access to 'x', which is defined within it's parent function. But, in the first call to (initialization of) incrementer, the value of y=undefined, but the snippet seems to indicate that it is initialized to 0(int).
def incrementer(x=1): return lambda y: x+y incr1 = incrementer(1) print incr1(2) # 3 incr2 = incrementer(2) print incr2(3) # 5
166.248.77.56 ( talk) 03:26, 11 February 2012 (UTC)
lambda arguments: expression
is an unnamed function that behaves as if defined like this:def name(arguments): return expression
incrementer(1)
is itself a function which adds 1 to its argument (named y
).
Johnuniq (
talk) 06:12, 11 February 2012 (UTC)counter
is an impure function, printing different values for calls on the same argument. The fact that the state captured in a closure can be mutable is important, and should be mentioned somewhere in the article, but presenting this as a canonical example is likely to mislead readers into thinking that closures are by nature impure (misleading since purely functional languages like Haskell of course allow closures as well). —
Smerdis 27 February 2014 — Preceding
undated comment added 20:26, 27 February 2014 (UTC)For one thing it frequently bases its assertions about whether some language x, has closures with how they are implemented in said language. For example, when one says that D and C# use delegates in this context, one suggests that delegates are somehow fundamentally related to the semantics of closures. Delegates are a technique to implement function references in object a fashion which implicitly captures the object to which the method belongs, allowing it to be invoked in a type safe and polymorphic manner on the correct instance/static. C# captures represents references to functions via delegates, but that is not why it has closures. It has closures because its function values are lexically scoped such that, when invoked, they execute in the lexical context in which they were defined. The fact that they can be, and usually are, stored in delegate instances is merely a low level detail.
Additionally the question of purity vs impurity of functions is a broader topic. Aluan Haddad ( talk) 08:47, 20 March 2014 (UTC)Rahab_Rx
I think that the first example with function startAt(x) should explain from where the variable y comes and how it gets its value changed. This is implicitly told below the example by giving the result for closure1
& closure2
, but a verbal explanation is missing.--
Sae1962 (
talk) 12:12, 5 February 2015 (UTC)
Closures typically appear in languages in which functions are first-class values—in other words, such languages enable functions to be passed as arguments, returned from function calls, bound to variable names, etc., just like simpler types such as strings and integers.
Earlier, it is indicated that 'c' is not such a language, and does not allow nested functions, but, in essence, via pointers, it does. You cannot expressly pass a function, but you can pass a pointer to a function, and this allows you to do some stuff that looks remarkably indistinguishable from those used in the examples of legitimate usage of closures.
I'm not arguing agains the claim, but suggesting that it would be good to discuss this somewhere as to how it differs. 167.230.96.8 ( talk) 20:04, 13 May 2015 (UTC)
I'm confused about the claim that C doesn't support nested functions; recursion is a standard technique in C, so it clearly does support nested functions. It doesn't directly support passing a function as a value, so they aren't first-class values. It doesn't support closures, due to not being able to execute the function after the enclosing function has exited, but that is the other case. This wording seems almost like a typo, but I'm not fluent enough in Algol to make that edit. Perhaps the source of my confusion is that C doesn't allow nested function definitions. If so, perhaps clarifying that would help other readers with a similar confusion.-- Wcoole ( talk) 23:08, 21 October 2015 (UTC)
@ Maggyero: I'm not sure if I completely agree with these changes to the lead section. These changes allow for the possibility of a closure capturing variables by value instead of by reference. If feel this distinction is overly pedantic for the lead section, and makes it even harder to understand. Especially considering that the distinction only makes sense at all in imperative languages/language where variables are mutable, and even more so since C++ is the only language I'm aware of that allows capturing by value. Instead I'd suggest assuming immutable variables/capture-by-reference semantics in the lead and go into more detail on capture-by-value in a footnote and/or separate section on closures in imperative languages. — Ruud 15:08, 14 July 2016 (UTC)
Hi, these two seemed to me as typos but I'm not sure, and this is my first attempt to contribute to wp.. In Delegates (C#, D) section, the sentence "For example, the above code will not work correctly, because the variable a is on the stack, and after returning from test(),..." it is not clear to which function test() refers, test1(), test2() or both? And in the last sentence "The same is true for inner's class methods that..." should it be "inner" instead of "inner's class methods" or am I missing something? -- S.POROY ( talk) 19:45, 15 May 2017 (UTC)
I was reading this article and found this mismatch in section "Lexical environment". There is no foo
function nor f
or g
variables. I think the text is referring to the example in section "Anonymous functions". Example and text follows:
'use strict'
function makeFunc() {
const name = "Closure";
function displayName() {
console.log(name);
}
return displayName;
};
const runFunc = makeFunc();
runFunc(); //Closure
Note how functionfoo
and the closures referred to by variables f
and g
all use the same relative memory location signified by local variable x
.
This article is rated C-class on Wikipedia's
content assessment scale. It is of interest to the following WikiProjects: | |||||||||||||||||||||||||||||||
|
To-do list for Closure (computer programming):
|
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?
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?
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)
Scope != closure. A scope is an environment where you can get at a particular value via a particular variable name; a closure is a coderef that remembers the lexical scope where it was born. A lexical scope arises every time execution passes into a given block (or file), but you don't create a closure (at least in Perl 5) until you take a reference to a function that uses a lexical from its environment. That function has to be able to see that lexical in order to run, so the coderef has to wrap up (a piece of) the current lexical scope along with the function. It is this wrapping of state with functionality that makes a closure. (Which is more general than objects: You can take two or more coderefs that close over the same variable, if you want.) eritain ( talk) 07:27, 26 October 2010 (UTC)
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.
That's a scope, but I'd hesitate to call it a closure. The distinctive thing about closures is that you can (potentially) take multiple references to the same sub, and get it wrapped up with a different environment each time. In this example, we know from compile time that there is one and only one %cache, so no matter how many times I say \&fib there is never a need to clarify which %cache we mean, and therefore no reason to wrap any environment with the coderef. eritain ( talk) 07:27, 26 October 2010 (UTC)
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)
Im going to add a perl example back to the page unless somebody protests. Demerphq 17:05, 10 April 2006 (UTC) Seriously? no mention at all of Perl in the article? 159.83.196.1 ( talk) 18:30, 14 May 2018 (UTC)
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)
Java has no first class functions, therefore has no closures.
Actually that java example on the anonymous class is overcomplicated for its result. The following code performs the same function without the need of creating an embedded runnable class. This is because the embedded Runnable classes run method is just called from the Thread classes run. Anyone who does threading in java knows this, which is why we can just extend thread instead of implementing Runnable. In such a case as this, it would be better formed code to just extend the thread into an anonymous, instead of creating an embedded runnable.
class CalculationWindow extends JFrame {
private volatile int result;
...
public void calculateInSeparateThread(final URI uri) {
// The expression "new Thread() { ... }" is an anonymous class.
new Thread() {
public void run() {
// It can read final local variables:
calculate(uri);
// It can access private fields of the enclosing class:
result = result + 10;
}
}.start();
}
}
76.235.207.239 ( talk) 09:11, 29 May 2011 (UTC)
Scala compiles to Java and supports Clousures. Not sure if this is an imperative language or not, but if so please append Scala to the list of "modern garbage-collected imperative languages support closures" — Preceding
unsigned comment added by
Jcalfee (
talk •
contribs) 16:47, 22 August 2013 (UTC)
Python does not have closures and shouldn't even be listed among the list of languages that do have closures, let alone used as the example language to demonstrate what they are. Using Python to demonstrate what closures are is completely misleading and damaging to a reader's understanding of what closures are. Can we just swap the example language and remove Python from the list? — Preceding unsigned comment added by Mmachenry ( talk • contribs) 06:14, 25 June 2014 (UTC)
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
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. :)
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)
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.
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)
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)
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)
Yeah, I also found the focus on state rather weird, especially in the introductory paragraph. - Chinju 03:22, 24 January 2006 (UTC)
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)
c'mon, what are you tlaking about? I will kindly remove the reference if not explained =) -- Euyyn 7-2-05
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)
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?
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)
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)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:
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)
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)
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:
Any suggestions/corrections/objections? -- int19h 19:26, 31 January 2007 (UTC)
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)
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. ;)throw
instead of return
and capture the result as an exception, wherever you need it.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// // 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);
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)if
or cond
expression can be used".proc
'ifying the block to an object).
-- int19h 05:39, 30 January 2007 (UTC)ifcond()
twice, which if ifcond()
alters any variables or calls any functions that alter anything, could result in incorrect state. Additionally, if something changes such that the second call to ifcond()
does not return the same result as the first, both (or neither) of ifblock()
and elseblock()
could be evaluated. —Preceding
unsigned comment added by
Evildeathmath (
talk •
contribs) 16:54, 17 December 2008 (UTC)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)
I'm still fuzzy on what a closure is, and I too liked the EcmaScript examples, but I have a very minor beef with one of them. The first example in the Differences in semantics section confused for an instant. I had read the x = 0 assignment, and I didn't notice the later x =1 assignment. Now, I now this is extremely minor, but I think the readability of the example increases if the initial assignment is x = 1. It seems a bit odd that its done the way it is, and rather than assume that its for no reason, I will assume that maybe I don't understand the reason. That, and my low level of understanding of the topic, keep me from editing myself. Hopefully one of the authors will read this and do the edit or explain the reasons to me (apparently I also need things to be typed slowly &8-P). Apwith ( talk) 19:29, 16 October 2009 (UTC)
I believe that putting JavaScript examples to illustrate closures is confusing at best. Whatever this article has to say on this matter is questionable. I'm not trying to convince anyone that closures do not exist in JavaScript, but I believe that whenever you are trying to emulate them you are misusing the tool. What you call functions in JavaScript are not the first order functions, they are objects with context and properties. Of course you can say it is not a requirement for the closure to not have either of these, but, normally, you don't want to have them in closure. Besides, the examples given are in general an ill-suggested practice. This is because of how the runtime is implemented and, as I've said, it's just a wrong tool / improper use - it is never a requirement in JS to use this approach, and the alternative approach would always win in terms of code readability and performance. It looks more like if someone wanted very much that closures existed in JS, and some popular libraries, like JQuery or the Closure JS "compiler", make it look like it is there, but, I think we are dealing with the case of where the term is being used improperly to describe something similar, yet not exactly the same. (The need for closures in JS is probably because of wanting to make the code shorter overall, and it is due to the nature of JS - because it should load in the least possible time).
Additionally, earlier on this page I've noted some C# programmer confusion created by Lisp examples, which is understandable, however, it is also strange that JavaScript was suggested as a better illustration, whilst closures are definitely possible in C#, which isn't a less popular language.
Wvxvw (
talk) 20:12, 12 May 2010 (UTC)
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:
A B Carter ( talk) 19:34, 29 January 2007 (UTC)
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)
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)
(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
#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; }
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:
A B Carter ( talk) 14:32, 4 February 2007 (UTC)
I think you've done an excellent job. Gafter 07:31, 16 February 2007 (UTC)
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.
When called, the function can reference elements of the environment required for the function’s evaluation.
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.
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.
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.
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.
As a consequence closures can be used to hide state, implement higher-order functions and defer evaluation.
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:
The notion that closures are lexical is central.
--
FOo 07:36, 16 April 2007 (UTC)
Ok, i don't really know much about closures, but it seems to me that this sentence is not referring to private variables, but to static ones:
Can you tell I was raised on OO? —Preceding unsigned comment added by 206.83.243.126 ( talk) 20:28, 25 June 2008 (UTC)
That metaphor about closures connected with space and time is totally useless and just confuses more the issue.
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)
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
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)
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)
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)
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)
I'm trying to figure out what the etomology of the word "closure" is in this context. Is this a Lisp started term? -- RobertGary1 ( talk) 23:12, 4 September 2008 (UTC)
What is a lexical enclosure? It should be mentioned in this article. Fresheneesz ( talk) 18:42, 28 October 2008 (UTC)
I think a small blurb about free variables is warranted. The linked article heavily concerns mathematical free variables and only has one small out of the way line saying "oh by the way free variables in computer science are references to non local variables" and that line even has a citation needed marking. My brain somehow parsed over that line and left me confused on the definition of closures for hours. 75.23.252.148 ( talk) 02:40, 8 July 2009 (UTC)
I removed the majority of the "in language x" examples from the article ( diff). As a rule of thumb, at most one example (in either Scheme or JavaScript, as per earlier consensus?) should be sufficient to illustrate any given concept: repeating it in everyone's favorite programming language just clutters the article. — Piet Delport 2009-08-25 10:57
In the "Implementation and theory" section a sentence begins "In function languages with immutable data (like Erlang),...". Shouldn't this begin with "In functional languages with immutable data (like Erlang),..."? Or am I misunderstanding, and it is correctly missing the "al"? Whoever reads this and knows, please feel free to update it if necessary, as I don't know the subject very well. -- Donkeydonkeydonkeydonkey ( talk) 19:56, 23 July 2010 (UTC)
The example given is an example of closures in C, as amended by Apple's additions to the C language, and currently under review for inclusion in the C standard. It works in pure .c files under the gcc and clang, at least on Apple platforms. The only lines in the example that use Objective-C are the NSLog statements, which could be replaced with printf statements to have a pure C closure example. It is worth renaming (and repositioning up higher) the section "Closures in C (gcc, clang)" or somesuch. —Preceding unsigned comment added by Hyperjeff ( talk • contribs) 09:23, 18 September 2010 (UTC)
I think that the complicated definition of closure in current version [13] is not explanatory, hardly understandable and must be improved. Please don't get me wrong, I do not question the correctness of the definition. It may be technically 100% right. The problem is that it does not really explains but confuses those who check Wikipedia while trying to understand what a closure is. Simply google for "closure explained", and you'll find some articles and blog posts saying more or less the same about Wikipedia's definition [14] [15] [16].
I suggest to move most of the first sentences down, and to place a simple definition from [17] instead:
A closure is a function/method that has the following two properties: * You can pass it around like an object (to be called later) * It remembers the values of all the variables that were in scope when the function was created. It is then able to access those variables when it is called even though they may no longer be in scope.
How cool is that?! Check how human-friendly and explanatory it is comparing to the current one:
a closure is a first-class function with free variables that are bound in the lexical environment. Such a function is said to be "closed over" its free variables. A closure is defined within the scope of its free variables, and the extent of those variables is at least as long as the lifetime of the closure itself.
Any thoughts on that?
Thanks! Alex Ex ( talk) 15:52, 1 April 2011 (UTC)
this
, target of return>
and break
, ...) as well. The current lead doens't mention this yet. —
Ruud 12:52, 2 April 2011 (UTC)Python 3.1.2 (release31-maint, Sep 17 2010, 20:27:33)
GCC 4.4.5 on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def f():
... x = 0
... def g():
... nonlocal x
... x = x + 1
... return x
... def h():
... nonlocal x
... x = x + 1
... return x
... return g, h
...
>>> a,b = f()
>>> c,d = f()
>>> a()
1
>>> a()
2
>>> b()
3
>>> a()
4
>>> c()
1
>>> d()
2
Agree, it's bad. One problem not addressed here is; the target audience is only experienced computer scientists. Doesn't that violate the Wiki policy of addressing non-experts first? ( "Provide an accessible overview" )...particularly in the lead section? ...with the resulting pitfall of making true statements rather than explanations or definitions. (Sometimes almost as if people were creating test questions or facts lists, or being worried about violating little nit-picky "experts," loudly-proudly waving tightly clutched brand new syntax guides.)
For example, first sentence;
"a closure ...is a function together with a referencing environment for the nonlocal names (free variables) of that function." is technically true, but it's utterly dependent on jargon and highly specialized training to have any meaning....as if a definition for already-experts...to satisfy experts...huh?
All that a typical person wants from the intro is to loosely grasp the concept of closure. Only after that required goal is met is any other goal useful or desired. The intro should concentrate on teaching, not technical correctness. There should be an opening sentence like, "The purpose/advantage of closure is..." so people have an orderly place to hang and orient the abstract definitions, --to help solidify them.
It's important to remember that many/most people come here as the result of following a hyperlink with the goal only of understanding another article. They will never read beyond the first sentence, paragraph or the lead section. In that context, hit-wise, the intro is the most valuable part of the article. See:
Wikipedia:Manual of Style (lead section)
--
69.227.84.108 (
talk) 19:42, 28 May 2011 (UTC)Doug Bashford
I came to this article because I have read statements like, "Language X has Closures," and "The Closure of function f is...," and "By line x, closure has occurred." Is Closure a noun or a verb? This article didn't clear it up at all, obviously, both, but then the first line of the abstract, treating it as a noun, keeps other parts of the abstract unclear. Someone knowledgeable should clarify this, and all editors should keep this in mind. (This is in no way a problem limited to this article alone.) -- Limited Atonement ( talk) 18:07, 30 August 2011 (UTC)
How the first paragraph reads to someone with little formal training in programming:
In computer science, a closure (also lexical closure, function closure or function value) is a function together with a NOUN for the NOUN (NOUN) of that function. Such a function is said to be "ADJECTIVE PHRASE" its NOUNS. The NOUN VERBS the NOUNS to the NOUNS in scope at the time the closure is created, additionally extending their lifetime to at least as long as the lifetime of the closure itself.
I don't really know what a closure is from this article. I read something on stack overflow ( explain JavaScript Closures to a 6 year old), and I think something like this might be more clear (if someone could make it more accurate, since like I said, I don't really understand yet):
In computer science, a closure is a function which returns another function. Importantly, the returned function has access to the variables contained in the returning function's scope. — Preceding unsigned comment added by 204.87.16.4 ( talk) 18:50, 20 September 2011 (UTC)
Please note that I have never written a line of code in python and have no idea how variables are initialized and values assigned. But I am worried that the following snippet that is used as the first example in the article may have an error. Can someone please help me understand where the value for 'y' is initialized in the incrementer() function? I understand that the lambda function would have access to 'x', which is defined within it's parent function. But, in the first call to (initialization of) incrementer, the value of y=undefined, but the snippet seems to indicate that it is initialized to 0(int).
def incrementer(x=1): return lambda y: x+y incr1 = incrementer(1) print incr1(2) # 3 incr2 = incrementer(2) print incr2(3) # 5
166.248.77.56 ( talk) 03:26, 11 February 2012 (UTC)
lambda arguments: expression
is an unnamed function that behaves as if defined like this:def name(arguments): return expression
incrementer(1)
is itself a function which adds 1 to its argument (named y
).
Johnuniq (
talk) 06:12, 11 February 2012 (UTC)counter
is an impure function, printing different values for calls on the same argument. The fact that the state captured in a closure can be mutable is important, and should be mentioned somewhere in the article, but presenting this as a canonical example is likely to mislead readers into thinking that closures are by nature impure (misleading since purely functional languages like Haskell of course allow closures as well). —
Smerdis 27 February 2014 — Preceding
undated comment added 20:26, 27 February 2014 (UTC)For one thing it frequently bases its assertions about whether some language x, has closures with how they are implemented in said language. For example, when one says that D and C# use delegates in this context, one suggests that delegates are somehow fundamentally related to the semantics of closures. Delegates are a technique to implement function references in object a fashion which implicitly captures the object to which the method belongs, allowing it to be invoked in a type safe and polymorphic manner on the correct instance/static. C# captures represents references to functions via delegates, but that is not why it has closures. It has closures because its function values are lexically scoped such that, when invoked, they execute in the lexical context in which they were defined. The fact that they can be, and usually are, stored in delegate instances is merely a low level detail.
Additionally the question of purity vs impurity of functions is a broader topic. Aluan Haddad ( talk) 08:47, 20 March 2014 (UTC)Rahab_Rx
I think that the first example with function startAt(x) should explain from where the variable y comes and how it gets its value changed. This is implicitly told below the example by giving the result for closure1
& closure2
, but a verbal explanation is missing.--
Sae1962 (
talk) 12:12, 5 February 2015 (UTC)
Closures typically appear in languages in which functions are first-class values—in other words, such languages enable functions to be passed as arguments, returned from function calls, bound to variable names, etc., just like simpler types such as strings and integers.
Earlier, it is indicated that 'c' is not such a language, and does not allow nested functions, but, in essence, via pointers, it does. You cannot expressly pass a function, but you can pass a pointer to a function, and this allows you to do some stuff that looks remarkably indistinguishable from those used in the examples of legitimate usage of closures.
I'm not arguing agains the claim, but suggesting that it would be good to discuss this somewhere as to how it differs. 167.230.96.8 ( talk) 20:04, 13 May 2015 (UTC)
I'm confused about the claim that C doesn't support nested functions; recursion is a standard technique in C, so it clearly does support nested functions. It doesn't directly support passing a function as a value, so they aren't first-class values. It doesn't support closures, due to not being able to execute the function after the enclosing function has exited, but that is the other case. This wording seems almost like a typo, but I'm not fluent enough in Algol to make that edit. Perhaps the source of my confusion is that C doesn't allow nested function definitions. If so, perhaps clarifying that would help other readers with a similar confusion.-- Wcoole ( talk) 23:08, 21 October 2015 (UTC)
@ Maggyero: I'm not sure if I completely agree with these changes to the lead section. These changes allow for the possibility of a closure capturing variables by value instead of by reference. If feel this distinction is overly pedantic for the lead section, and makes it even harder to understand. Especially considering that the distinction only makes sense at all in imperative languages/language where variables are mutable, and even more so since C++ is the only language I'm aware of that allows capturing by value. Instead I'd suggest assuming immutable variables/capture-by-reference semantics in the lead and go into more detail on capture-by-value in a footnote and/or separate section on closures in imperative languages. — Ruud 15:08, 14 July 2016 (UTC)
Hi, these two seemed to me as typos but I'm not sure, and this is my first attempt to contribute to wp.. In Delegates (C#, D) section, the sentence "For example, the above code will not work correctly, because the variable a is on the stack, and after returning from test(),..." it is not clear to which function test() refers, test1(), test2() or both? And in the last sentence "The same is true for inner's class methods that..." should it be "inner" instead of "inner's class methods" or am I missing something? -- S.POROY ( talk) 19:45, 15 May 2017 (UTC)
I was reading this article and found this mismatch in section "Lexical environment". There is no foo
function nor f
or g
variables. I think the text is referring to the example in section "Anonymous functions". Example and text follows:
'use strict'
function makeFunc() {
const name = "Closure";
function displayName() {
console.log(name);
}
return displayName;
};
const runFunc = makeFunc();
runFunc(); //Closure
Note how functionfoo
and the closures referred to by variables f
and g
all use the same relative memory location signified by local variable x
.