Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Main page
Recent changes
Random page
Help about MediaWiki
Special pages
Niidae Wiki
Search
Search
Appearance
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
Closure (computer programming)
(section)
Page
Discussion
English
Read
Edit
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
View history
General
What links here
Related changes
Page information
Appearance
move to sidebar
hide
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== Implementation and theory == Closures are typically implemented with a special [[data structure]] that contains a [[function pointer|pointer to the function code]], plus a representation of the function's lexical environment (i.e., the set of available variables) at the time when the closure was created. The referencing environment [[name binding|binds]] the non-local names to the corresponding variables in the lexical environment at the time the closure is created, additionally extending their lifetime to at least as long as the lifetime of the closure. When the closure is entered at a later time, possibly with a different lexical environment, the function is executed with its non-local variables referring to the ones captured by the closure, not the current environment. A language implementation cannot easily support full closures if its run-time memory model allocates all [[automatic variable]]s on a linear [[Stack-based memory allocation|stack]]. In such languages, a function's automatic local variables are deallocated when the function returns. However, a closure requires that the free variables it references survive the enclosing function's execution. Therefore, those variables must be allocated so that they persist until no longer needed, typically via [[heap allocation]], rather than on the stack, and their lifetime must be managed so they survive until all closures referencing them are no longer in use. This explains why, typically, languages that natively support closures also use [[Garbage collection (computer science)|garbage collection]]. The alternatives are manual memory management of non-local variables (explicitly allocating on the heap and freeing when done), or, if using stack allocation, for the language to accept that certain use cases will lead to [[undefined behaviour]], due to [[dangling pointer]]s to freed automatic variables, as in lambda expressions in C++11<ref>''[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2550.pdf Lambda Expressions and Closures]'' C++ Standards Committee. 29 February 2008.</ref> or nested functions in GNU C.<ref>{{cite web |work=GCC Manual |url=https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html |title=6.4 Nested Functions |quote=If you try to call the nested function through its address after the containing function exits, all hell breaks loose. If you try to call it after a containing scope level exits, and if it refers to some of the variables that are no longer in scope, you may be lucky, but it's not wise to take the risk. If, however, the nested function does not refer to anything that has gone out of scope, you should be safe.}}</ref> The [[funarg problem]] (or "functional argument" problem) describes the difficulty of implementing functions as first class objects in a stack-based programming language such as C or C++. Similarly in [[D (programming language)|D]] version 1, it is assumed that the programmer knows what to do with [[delegation (programming)|delegates]] and automatic local variables, as their references will be invalid after return from its definition scope (automatic local variables are on the stack) β this still permits many useful functional patterns, but for complex cases needs explicit [[heap allocation]] for variables. D version 2 solved this by detecting which variables must be stored on the heap, and performs automatic allocation. Because D uses garbage collection, in both versions, there is no need to track usage of variables as they are passed. In strict functional languages with immutable data (''e.g.'' [[Erlang (programming language)|Erlang]]), it is very easy to implement automatic memory management (garbage collection), as there are no possible cycles in variables' references. For example, in Erlang, all arguments and variables are allocated on the heap, but references to them are additionally stored on the stack. After a function returns, references are still valid. Heap cleaning is done by incremental garbage collector. In ML, local variables are lexically scoped, and hence define a stack-like model, but since they are bound to values and not to objects, an implementation is free to copy these values into the closure's data structure in a way that is invisible to the programmer. [[Scheme (programming language)|Scheme]], which has an [[ALGOL]]-like lexical scope system with dynamic variables and garbage collection, lacks a stack programming model and does not suffer from the limitations of stack-based languages. Closures are expressed naturally in Scheme. The lambda form encloses the code, and the free variables of its environment persist within the program as long as they can possibly be accessed, and so they can be used as freely as any other Scheme expression.{{citation needed|date=December 2014}} Closures are closely related to Actors in the [[Actor model]] of concurrent computation where the values in the function's lexical environment are called ''acquaintances''. An important issue for closures in [[concurrent programming]] languages is whether the variables in a closure can be updated and, if so, how these updates can be synchronized. Actors provide one solution.<ref>''[https://dspace.mit.edu/handle/1721.1/6935 Foundations of Actor Semantics]'' Will Clinger. MIT Mathematics Doctoral Dissertation. June 1981.</ref> Closures are closely related to [[function object]]s; the transformation from the former to the latter is known as [[defunctionalization]] or [[lambda lifting]]; see also [[closure conversion]].{{Citation needed|date=September 2011}}
Summary:
Please note that all contributions to Niidae Wiki may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Encyclopedia:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Search
Search
Editing
Closure (computer programming)
(section)
Add topic