Closure (computer programming)

This product was added to computer science because of the content, defects on the quality assurance side of the editor. This is done to bring the quality of the articles from the computer science subject area to an acceptable level. Help us to eliminate the substantive shortcomings of this article and take part you in the discussion! ( ) Justification: See talk page - Pjacobi 23:20, March 16 2009 ( CET )

A Closure ( or functional termination ) is a function, or a reference to a function that has access to its own build context. When you call the function then accesses this creation context. This context (memory area, state) is not referenced outside the function, that is not visible.

Closure includes also reference to the function and the creation of context - the function and the associated memory structure are completed in a reference inseparable (closed term). It is similar to an object with "private" attributes and "public" method (s): it contains an (implicit) identity, a state and a behavior.

In the programming language syntax, this is often achieved by means of two nested features - the main function is enclosed by a further function (" completed "). This " final " function contains the storage structure required ( see examples below) and provides the reference - the Closure.

Origin

Closures are a concept that comes from the functional programming languages ​​, appeared for the first time in LISP and was first fully supported in his dialect Scheme. Then it was (about Haskell, Ocaml ) also supported in most subsequent functional programming languages ​​.

Advantages and Features

With Closures not visible, but controlled variable regions can be created, for example, can be implemented so that data encapsulation is realized or currying, though there is no other language constructs.

A closure can be seen as an anonymous class that only has one method and it usually is only one instance. Trapped in the closure the variables from the generating area can be used by the closure as attributes.

The creation of a closure is associated with significantly less work than creating a class with only one method.

Implementations

There are also non-functional programming language that supports this feature. Here would be Ada, Object Pascal (Delphi ), JavaScript, Smalltalk, Python, Lua, Ruby, C #, Visual Basic (only. NET ), C to call ( only in Standard C 11), Groovy, Go, PHP and Perl. The object-oriented programming language Java supports a limited variant of function statements in the form of anonymous and local classes. Apple has the gcc and Clang to Closures - called block literal - extended for C and suggested this to standardization.

Examples of implementations

Pseudocode

In the following example, a function is first defined native function. This function sets a local variable named cake and defines a local function called child function.

Functional native function {    put cake = ' apple pie '    functional child function {      gib_aus ' I eat cake # { }'    }    gib_zurück child functioning } When called, they are the local function back child function.

The global variable so child gets the function assigned to child functioning, so that the subsequent call to child consequently child function is executed. Although no global variable exists cake, child function the string is ' I eat apple pie ', because they can access their creation context in which the variable is defined cake with ' apple pie '. Important to note: Although native function has already returned a value - the context so actually no longer exists - can access child working on it - that child function is a closure function.

Set kind = rufe_auf mother function rufe_auf child I eat apple pie With a change in the code now, the value of the variable is anzahl_kuchen in the native function with each access increased to the closure function by one, bringing a counter can be realized. The value in anzahl_kuchen is protected against tampering and can only be increased by eating.

Functional native function {    set anzahl_kuchen = 0    functional child function {      set anzahl_kuchen = anzahl_kuchen 1      gib_aus ' I am eating # { } anzahl_kuchen cake '    }    gib_zurück child functioning } Calling can be accessed on an otherwise non-visible region and within the child functional calculations can be made with other non-changeable values ​​- these are the main advantages of closures.

Sit eat = rufe_auf mother function rufe_auf eat rufe_auf eat rufe_auf eat I eat 1 cake I eat 2 cakes I eat three cakes Perl

The context of an arbitrary code fragment is determined inter alia by the available symbols:

# pragma   use strict;     sub function {     my ($ var1, $ var2 ) = @ _; # Copy arguments into named variables     # Blockcode       ...   } In the example shown above, the variables $ var1 and $ var2 are at any point of the function valid and visible. When you exit the function, they are cleaned up along with the abandoned block ( " go " out of scope) and are then unknown. Each additional access would be a mistake.

Closures now offer the possibility of extending the scope of such variables on its official end addition. For this purpose, in the Scope, a function is simply defined that uses the variables in question:

# pragma   use strict;     sub function {     my ($ var1, $ var2 ) = @ _;     return sub { print " Vars: $ var1, $ var2 \ n ."};   }     my $ f = function ( "Hello", 8);   my $ g = function ( " bar", " Y ");     # Call of $ f   $ f -> ();     # Call of $ g   $ g -> (); The runtime system is now leaving the function function determines that there are still references to the block variables $ var1 and $ var2 - the return value is an anonymous subroutine, which in turn contains references to the block variables. $ var1 and $ var2 therefore remain with their current values ​​. Since the function of these variables, the preserved, it becomes the closure.

In other words, you can always run the call $ f -> () and the call $ g -> () also after leaving the actual scope of the variables and will always be displayed that were valid during the definition of the functions values ​​of the variables in the result get.

This gives the output:

Vars: Hello, 8th Vars: bar, Y. Can change these values ​​no longer, because the variables outside of the closure are no longer available. But that is mainly due to the function definition: of course, the closure would have the values ​​not only spend but also edit or even the calling code can make by reference is available again. The following variant functions are introduced, for example to increment and decrement:

# pragma   use strict;     # function   sub function    {     my ($ var1, $ var2 ) = @ _;       return (         sub { print " Vars: $ var1, $ var2 \ n. "},         sub { $ var1 ; $ var2 ; }         sub { $ var1 -; $ var2 - ;}     );   }     # Call the function   my ($ printer, $ incrementor, $ Decrementor ) = function ( 3.5 );   # Use closures   $ printer- > ();   $ incrementor -> ();   $ printer- > ();   $ incrementor -> ();   $ incrementor -> ();   $ printer- > (); This gives the output:

Vars: 3, 5 Vars: 4, 6 Vars: 6, 8 Closures therefore can be used for example to encapsulate access to sensitive data.

Python

Following a simple example of a counter in python that does not require a ( named ) container that stores the current count.

Def closure ():      container =      def inc ( ):         Container = 1      def get ():         return container      return inc, get In the example, two function objects are created within the closure function, which both refer to the list container from their respective parent scope. If the closure function that is executed ( after a call ) and the two returned function objects continue to be referenced, then continues to exist, the container list, although the Closure Scope has already left. In this manner, the list is preserved in an anonymous scope. You can not directly access the list container. If the two function objects inc and get no longer referenced, and the container disappears.

The closure in the preceding example is then used in the following manner:

>>> I, g = closure () >>> G ( ) 0 I >>> () I >>> () >>> G ( ) 2 OCaml

OCaml permits in the following way:

Let counter, inc, reset =    let n = ref 0 in    (function () -> n ), ( * counter *)    (function () -> n: = n 1! ) (* incrementor *)    (function () -> n: = 0) ( * reset *) Now the counter is applicable as follows:

# Counter ();; (* Returns 0 *) # Inc ( );; # Counter ();; (* Returns 1 *) # Inc ( ); inc ( ); inc ( );; # Counter ();; (* Gives 4 *) # Reset (); ; # Counter ();; (* Returns 0 *) # N;; (* N is encapsulated *) Unbound value n Course instead of an integer, any objects or variables of any type can be encapsulated this way.

In the function F1, a further function is defined as f2 closure;

Var f1 = function ( ) { / / define an external function f1 ...      var value = 22; / / ... And in it create a namespace.      var f2 = function ( ) { / / define an inner function, ...          returnValue; / / ... Which extends the name space to the outside.      }      return f2; / / Return f2 by f1, f2 which is the closure. } var a = f1 (); / / A is the f1 ( ) function returns closure function, ... document.write (f1 () "
"); / / ... So: function () { return value ;} document.write ( typeof value "
"); / / Is undefined document.write (a ( ) "
"); / / Displays 22 document.write (f1 () ( ) "
"); / / Displays 22, f2 () is not available here The example above somewhat differently, the inner function is now called directly:

Var f3 = function ( ) {      var value = 23;      return function () {/ / the function f3 is equal to the closure function back!          returnValue;      }; } var b = f3 (); / / B is again the f3 () returned function ... document.write (b ( ) "
"); / / ... And now supplies as a result of 23 document.write (b "
"); / / B but remains a function call! document.write (f3 () ( ) "
"); / / Also returns 23 The embedded function is used in each case as a supplier of the defined in the parent function value.

The parent function may also be defined as an anonymous function:

Var value = 24; var c = (function ( ) { / / the external as anonymous function and ...        returnValue; / / ... Is to define the inner function.      } ()); / / The function now with (); invoke. document.write ( c "
"); / / Displays 24 The closure can also be created with a constructor:

Var d = ( new Function ( "return value ;") ) (); Define a constructor / / and call Lua

Lua has a built-in, and in terms of programming and intuitive support for Closures whose implementation is similar to that in Python:

Function adder (x ) - function generator      return function ( y) - anonymous, to adder private function          return x y - x is derived here from the external context      end end An example usage would look like this:

Add2 = adder (2) - here the closure is generated print ( add2 (10 ) ) -> Issue 12 print ( add2 (-2) ) - > Output 0 A Closure implementation in Lua is described in.

Erlang

Erlang as a functional language also has closures, which however Funs (singular Fun, by function) are called.

Do_something ( Fun) -> Fun ( 4).   main () ->      Var = 37,      F = fun (N) -> Var N end.      Result = do_something (F).      % Result =: = 41 =: = 37 4 literature

  • Offer valid Ralf H., Martin Erwig, Compiler Construction, Springer (1999), ISBN 3-540-65389-9
  • Damian Conway, Object Oriented Perl
  • Oliver Lau, Andreas Linke, Torsten T. Will: variables to go - Closures in current programming languages. In: c't 17/2013, pp. 168ff. ISSN 0724-8679
194543
de