In programming languages, a closure is a function that refers to free variables in its lexical context.
A closure typically comes about when one function is declared entirely within the body of another, and the inner function refers to local variables of the outer function. At run time, when the outer function executes, a closure is formed. It consists of the function code, and references to any variables in the outer function's scope that the closure needs.
Closures are commonly used in functional programming to defer calculation, to hide state, and as arguments to higher-order functions.
A closure combines the code of a function with a special lexical environment bound to that function (scope). Closure lexical variables differ from global variables in that they do not occupy the global variable namespace. They differ from object oriented member variables in that they are bound to function invocations, not object instances.
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 (Will Clinger 1981).
For example, consider the following Lisp function:
(defun best-selling-books (threshold) "Return a list of all books with at least THRESHOLD copies sold." (filter #'(lambda (book) (>= (book-sales book) threshold)) *book-list*))
Here the lambda expression (lambda (book) (>= (book-sales book) threshold)) appears within the function best-selling-books. When the lambda expression is evaluated, Lisp creates a closure consisting of the code for the lambda and a reference to the threshold variable, which the lambda uses.
The closure is then passed to the filter function, which calls it repeatedly to determine which books are to be added to the result list and which are to be discarded. Because the closure itself has a reference to threshold, it can use that variable each time filter calls it. filter might be defined in a completely separate file.
A function may create a closure and return it. The following example is a function that returns a function.
(defun derivative (f dx) "Return a function that approximates the derivative of f using an interval of dx, which should be appropriately small." #'(lambda (x) (/ (- (funcall f (+ x dx)) (funcall f x)) dx)))
Because the closure in this case outlives the scope of the function that creates it, the variables f and dx live on after the function derivative returns. In languages without closures, the lifetime of a local variable coincides with the execution of the scope where that variable is declared. In languages with closures, variables continue to exist as long as any existing closures have references to them.
Note: Some speakers call any data structure that binds a lexical environment a closure, but the term usually refers specifically to functions.
Eiffel has a notion of agent. An agent is an object wrapping a routine, with some arguments possibly evaluated ("closed") and others left for evaluation at the time of call ("open"). Eiffel agents are extensively used in GUI programming, numerical applications, database manipulation, and reflection.
Though semantics vary greatly, many modern, general-purpose programming languages have lexical scoping and some variation on closures.
void * pointer to arbitrary data of the user's choice. Each time the library executes the callback function, it passes in the data pointer. This allows the callback to maintain state and to refer to information captured at the time it was registered. The idiom is similar to closures in functionality, but not in syntax.
Several object-oriented techniques and language features simulate some features of closures. For example:
operator(). These objects behave somewhat like functions in a functional programming language. They may be created at runtime and may contain state. But, they do not implicitly capture local variables as closures do. Two proposals to introduce C++ language support for closures (both proposals call them lambda functions) are being considered by the C++ Standards Committee [http://val.samko.info/lambda/. The main difference between these proposals is that one stores a copy of all the local variables in a closure by default, and another stores references to original variables. Both provide functionality to override the default behaviour. If some form of these proposals is accepted, one would be able to write
class CalculationWindow extends JFrame { private JButton btnSave; ... public final calculateInSeparateThread(final URI uri) { // The expression "new Runnable() { ... }" is an anonymous class. Runnable runner = new Runnable() { void run() { // It can access final local variables: calculate(uri); // It can access private fields of the enclosing class: btnSave.setEnabled(true); } }; new Thread(runner).start(); } }
A language implementation cannot easily support full closures if its run-time memory model allocates all local variables on a linear stack. In such languages, a function's 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. This explains why typically languages that natively support closures use garbage collection.
A typical modern Scheme implementation allocates local variables that might be used by closures dynamically and stores all other local variables on the stack.
Closure | Fermeture | Chiusura (informatica) | Замыкание (программирование) | ส่วนปิดคลุม (วิทยาการคอมพิวเตอร์) | Closure
This article is licensed under the GNU Free Documentation License.
It uses material from the
"Closure (computer science)".
Home Page • arts • business • computers • games • health • hospitals • home • kids & teens • news • physicians • recreation• reference • regional • science • shopping • society • sports • world