Talk:Closure (computer programming)
![]() | This article is rated C-class on Wikipedia's content assessment scale. It is of interest to the following WikiProjects: | ||||||||||||||||||||||||||||||
|
|
Don't start with Lisp
[edit]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)
- 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)
- 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)
- Sounds good to me. --Piet Delport 15:48, 20 August 2006 (UTC)
- 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)
- 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)
- 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)
Closures in Perl
[edit]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 (talk • contribs) 13:15, 7 March 2007 (UTC).
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)
Closures and Java
[edit]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)
Closures and Python
[edit]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
- 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)
- 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)
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)
- It's been archived over here. --Piet Delport 09:31, 22 November 2006 (UTC)
- 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)
Removed "merge this with Function object" note
[edit]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)
- "it is not clear to me the difference between the two". Bully for you. But your ignorance and lack of perspicuity is no reason to merge articles about different topics. Rather, it suggests you shouldn't be editing such articles (or perhaps any articles).
- 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)
- "the example given in this article resembles the idea of a function object" -- just because function objects (which, being objects encapsulate state) and closures (which implicitly capture the values of lexically scoped variables) have overlapping application doesn't mean they are the same thing. Sheesh. -- 98.108.203.136 (talk) 07:57, 20 June 2008 (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)
- "Maybe I am missing something" -- yes, the capacity to understand. -- 98.108.203.136 (talk) 07:57, 20 June 2008 (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
[edit]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)
Focus on state
[edit]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)
closures in prolog??
[edit]c'mon, what are you tlaking about? I will kindly remove the reference if not explained =) -- Euyyn 7-2-05
Fix non-breaking space
[edit]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)
What closures aren't
[edit]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)
- "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)
- "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)
- 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)
- 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)
- 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)
- 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)
- Erm? Here's the definition of variable from R5RS:
- 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)
- "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)
- Agreed, and for that a reference to Guy Steele's "lambda the ultimate..." papers might be appropriate. Gafter 20:02, 28 January 2007 (UTC)
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)
- [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)
- 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)
- 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 writex => { return x + 1; }
, which is the same thing. -- int19h 07:20, 29 January 2007 (UTC)
- On a side note, lambdas in C# 3.0 do not take away "return", they only make it optional. You can write
- 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)
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)
- 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)
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:
- 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)
- 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)
- 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)
Any suggestions/corrections/objections? -- int19h 19:26, 31 January 2007 (UTC)
- 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)
- 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)
On ECMAScript examples
[edit]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)
- 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)
- 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)
- Simply put, it means that
- "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 usethrow
instead ofreturn
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, thethrow
keyword whould behave quite like the^
operator in Smalltalk, whilereturn
whould be the equivalent of a "normal" procedure end.--151.74.14.142 (talk) 01:21, 2 April 2008 (UTC) xeal
- "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?"
- 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)
- 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)
- 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)
- "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:
- "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)."
// // 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
- I can, however, write a function in JavaScript that can be used the same way Scheme's
if
orcond
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)
- I can, however, write a function in JavaScript that can be used the same way Scheme's
- 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
orcond
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)
- That was precisely what I meant when I wrote about "a function in JavaScript that can be used the same way Scheme's
- The above JavaScript example is broken--it calls
ifcond()
twice, which ififcond()
alters any variables or calls any functions that alter anything, could result in incorrect state. Additionally, if something changes such that the second call toifcond()
does not return the same result as the first, both (or neither) ofifblock()
andelseblock()
could be evaluated. —Preceding unsigned comment added by Evildeathmath (talk • contribs) 16:54, 17 December 2008 (UTC)
- The above JavaScript example is broken--it calls
- 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)
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)
What Are Closures
[edit]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:
- The core notion of a closure is an implementation concept rather than a language feature.
- 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.
- Scheme was designed with closures as an explicit feature of the language. Since then many languages have incorporated closures as a feature.
- Consequently a language can have higher-order functions that are implemented with closures, but not have closures as an explicit feature of the language.
- 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.
- 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.
- 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)
- 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)
- 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)
Please provide counter-examples
[edit]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)
- 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)
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)
- 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).
- --vstarre 17:12, 1 February 2007 (UTC)
- 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)
- 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)
- 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)
- 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)
- 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)
- 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)
- 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)
- 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.
Rewrite of Introduction
[edit]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:
- 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.
- Quickly provide some basic characterization that can be understood with a minimal understanding of programming language.
- Keep the typical example because it captures the notion implied by many text book definitions of a closure.
- Defer more technical discussions of closures to a yet to be written Overview section.
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)
- 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)
Intro is too confusing and inaccurate
[edit]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)
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)))
- (defun count-up ()
- 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)
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)
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)
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)
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)
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)
--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:
- A closure can be used to associate a function with a set of "private" variables, which persist over several invocations of the function.
Can you tell I was raised on OO? —Preceding unsigned comment added by 206.83.243.126 (talk) 20:28, 25 June 2008 (UTC)
- Closures cannot be realized using static variables, which would be shared by all instances of the function. Every instance of the function has its own copy of the lexically scoped variables. — Tobias Bergemann (talk) 07:13, 26 June 2008 (UTC)
That metaphor about closures connected with space and time is totally useless and just confuses more the issue.
Relate concept to broader semantics of "closure"?
[edit]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)
- 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)
Link farm
[edit]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'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)
Closures and Objects
[edit]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)
Etomology
[edit]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)
- See above. —Piet Delport 2009-08-25 08:32
- (I went ahead and added an Etymology section to the article. —Piet Delport 2009-08-25 18:36)
lexical enclosure
[edit]What is a lexical enclosure? It should be mentioned in this article. Fresheneesz (talk) 18:42, 28 October 2008 (UTC)
Free variables.
[edit]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)
Example bloat
[edit]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
Small typo? (not sure)
[edit]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)
- Yup, tyop, fixed it, thanks. - 2/0 (cont.) 00:11, 24 July 2010 (UTC)
Closures in Objective-C
[edit]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've expanded the section to refer to the fact it also applies to C and C++ in Mac. I don't think its should be moved higher or listed under C as it is a non-standard apple only extension.--Salix (talk): 10:04, 18 September 2010 (UTC)
Definition of closure (the current one is awful...)
[edit]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)
- +1 --Paddy (talk) 17:04, 1 April 2011 (UTC)
- The first sentence could be improved, but I don't think your suggestion is an improvement. You sort of try to define "first-class function" and "closing over the lexical scope", but do so in a incorrect and non-universal way. E.g. "pass around like object" probably only makes sense to people coming from an OO background. A closure doesn't "remember the values", it gives you access to the variables itself (I initially made the same mistake here). You also need to be explicit about which scope you're talking, in this case the lexical scope, not the dynamic scope. This again might be "obvious" for people coming from a particular language, but isn't universal. Your definition simply leaves out the second sentence from the current definition altogether. I think a concrete example, as in First-class function#Closures would be more instructive. —Ruud 12:43, 2 April 2011 (UTC)
- Also, closures can close over more than just the variables in the lexical scope, but other lexical entities entities (e.g.
this
, target ofreturn>
andbreak
, ...) as well. The current lead doens't mention this yet. —Ruud 12:52, 2 April 2011 (UTC)
- To see a closure does not just "remember values" try:
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
- —Ruud 13:11, 2 April 2011 (UTC)
- Also, Finkel gives a pretty similar definition to the current one: "A procedure in combination with its nonlocal referencing environment is called a closure." And then continues with "Because this idea is unfamiliar to students who mainly use C (which has no nested procedures, and therefore no nonlocal referencing environments), I will present several examples." I think we should use the same approach. —Ruud 19:31, 2 April 2011 (UTC)
- Okay. We agree the current text needs improving, yes? --Paddy (talk) 04:54, 3 April 2011 (UTC)
- Sure, it definitely suffers from a bad case of too-many-editors(-who-didn't-all-quite-grasp-the-subject), but I don't think Alex's proposal is the way to go. —Ruud 10:35, 3 April 2011 (UTC)
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
Clarify Part of Speech
[edit]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)
- The act of "closing a function over its free variables" results in an object called "a closure". It's usually a noun, but can be used as a verb. I don't think this is a very uncommon phenomena? —Ruud 18:55, 30 August 2011 (UTC)
Clarity
[edit]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)
- I've been think about this for a while, but I'm sure if it possible to explain what a closure is in a single sentence. Do the examples at First-class function#Non-local variables and closures help you to understand what the purpose of a closure is? If so, they should probably be copied to somewhere near the beginning of this article as well. If not, could you try explain what is still difficult to understand for you?
- Regarding your proposed lead sentence, a closure is not "a function which returns another function". If a functions wants to return a function it should probably return a closure instead (which is the function begin returned together with some extra data that make it possible for that returned to function to still have access to the variables contained in the returning function's scope.) Cheers, —Ruud 19:34, 20 September 2011 (UTC)
- I'm not sure I follow the examples, but are you just clarifying my lead by saying that a closure is when a function returns a function *while preserving scope*? If so, a closure sounds a bit like a class with a member function... --204.87.16.4 (talk) 13:04, 21 September 2011 (UTC)
- Basically, yes. When a function f wants to return a function g it should instead return a closure, which can be seen as a function pointer to g together with a bit of additional data that allows g to preserve its scope once it gets called.
- The main difficulty that most people have when trying to understand closures is that a lot of popular languages like C, Java and C# 1.0 don't have nested functions and therefore no non-local variables (only local and global variables). So in those languages you generally don't need a closure, a function pointer is sufficient.
- You can find a lot of discussion on the Internet on whether closures and objects are equivalent. While you can see closures as a simple kind of objects, I don't think that view is really helpful in understanding what closures are. You can do things with objects that you can't easily do with closures (have more than one member function, have public member variables, polymorphism, etc.) and things with closures that you can't easily do with objects (two closures can share the same "private member variable" and use it as a private communication channel, which objects can't directly any language I know.) There is a lot of literature on building object systems on top of closures and simulating closures using objects, but that isn't how they are primarily used in languages that support those features. —Ruud 16:43, 21 September 2011 (UTC)
- Very helpful, thank you! I think I see the dilemma now, between clarity and precision. My only recommendation is to avoid giving the reader another definition in the second sentence. Follow with very simple language to catch anyone who was left behind.
- In computer science, a closure (also lexical closure, function closure or function value) is a function together with a referencing environment for the non-local variables of that function. In other words, a closure allows a function to access some variables outside its typical scope. --204.87.16.4 (talk) 13:00, 22 September 2011 (UTC)
- Good suggestion. I think the "typical" part might still need to be changed. We are talking about variables that are still in the lexical scope, but might by outside of the dynamic scope. Most (non-LISP) programmers would probably assume "typical" refers to lexical scope here. —Ruud 13:55, 22 September 2011 (UTC)
- I'm not sure I follow the examples, but are you just clarifying my lead by saying that a closure is when a function returns a function *while preserving scope*? If so, a closure sounds a bit like a class with a member function... --204.87.16.4 (talk) 13:04, 21 September 2011 (UTC)
- "In computer science, a closure (also lexical closure, function closure, function value or functional value) is a function together with a referencing environment for the non-local variables of that function." This sentence is by far the most confusing thing I've ever seen. I'm almost on the floor laughing from how vaguely confusing it is. Firstly the usage of "together with" in this sentence is nothing more than weasel words here and add insult to injury in this confusing context. I see what you guys are trying to do here by trying to define a closure in one sentence but we shouldn't be tossing around confusing words like that before the end-user at least knows what we are talking about. If anything, I think it would be best if we flipped some things around in this sentence. Can we re-word the sentence to something more like this?: In computer science, a closure (also lexical closure, function closure, function value or functional value) is the scope of a function that that has a referencing environment for variables which are not local to it that appear in a parent, and in most cases not global, scope. --Thelazyleo (talk) 20:39, 28 December 2011 (UTC)
- In my opinion your suggestion is more confusing and less accurate than the current wording. Operationally, a closure is a data structure pairing a function (reference/pointer) with a table (the referencing environment). See for example the definition by Sussman and Steele given in the first footnote. This is a fairly unambiguous and precise definition (given that you know what a referencing environment is, what necessarily has the be explained in the following sentences.) Your proposed definition on the other hand uses the rather vague and imprecise "a closure ... is the scope of a function". Semantically, a closure has everything to do with scoping, of course, but this is what the sentences following the first try to explain. I therefore think it's only useful to whole first paragraph, not just the first sentence. —Ruud 21:45, 28 December 2011 (UTC)
- I do think that the final part of the first sentence ("for the non-local variables of that function.") needs to be clarified. In particular it might be possible to give a definition of "referencing environment" instead. Something along the lines of "a map containing bindings for the non-local variables of that function."?—Ruud 21:47, 28 December 2011 (UTC)
- I have taken the liberty to remove the terms function value and functional value from the first sentence. These terms do not usually refer to closures, except of course in the context of languages in which all function values are closures, but there are many languages in which this is not the case. Rp (talk) 12:38, 31 March 2012 (UTC)
First Example (Python)
[edit]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
- So
incrementer(1)
is itself a function which adds 1 to its argument (namedy
). Johnuniq (talk) 06:12, 11 February 2012 (UTC)
- The example was recently replaced. My old example was IMHO clearer. The other editor apparently found it too verbose, but this was intentional as it has to be understandable to non-Python programmers too. —Ruud 11:14, 11 February 2012 (UTC)
- Also, the new example fails to demonstrate that the state captured in a closure can be mutable. I'll restore the old example. —Ruud 11:19, 11 February 2012 (UTC)
- I agree that the lambda code is too mysterious to be helpful here, and the example you just restored is better. Johnuniq (talk) 01:59, 12 February 2012 (UTC)
- I find the | current example misleading since the closure returned by
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)
- This article has several significant problems.
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
First example needs one more information
[edit]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)
Functions in C -- Clarity recommended...
[edit]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)
- There is some discussion about this at First-class function#Non-local variables and closures. —Ruud 13:28, 14 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)
- Nested functions, in this contaxt, means lexically nested functions. Last time I used C, gcc supported them while standard C didn't. (The next question is then whether such functions can be closures, i.e. use variables defined in their lexical environment when invoked outside of that scope.) Rp (talk) 12:27, 20 March 2018 (UTC)
Capture-by-value in the lead section
[edit]@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)
Small typos or not?
[edit]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)
Example and text don't match
[edit]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
.
Bjacquet (talk) 11:59, 19 March 2018 (UTC)
Start a discussion about improving the Closure (computer programming) page
Talk pages are where people discuss how to make content on Wikipedia the best that it can be. You can use this page to start a discussion with others about how to improve the "Closure (computer programming)" page.
- C-Class Computer science articles
- Mid-importance Computer science articles
- WikiProject Computer science articles
- C-Class Computing articles
- Low-importance Computing articles
- C-Class software articles
- Mid-importance software articles
- C-Class software articles of Mid-importance
- All Software articles
- All Computing articles
- Wikipedia pages with to-do lists