| p:abstract
| - In computer science, a closure is a function that is evaluated in an environment containing one or more bound variables. When called, the function can access these variables. The explicit use of closures is associated with functional programming and with languages such as ML and Lisp. Constructs such as objects in other languages can also be modeled with closures. In some languages, a closure may occur when a function is defined within another function, and the inner function refers to local variables of the outer function. At runtime, when the outer function executes, a closure is formed, consisting of the inner function’s code and references to any variables of the outer function required by the closure. A closure can be used to associate a function with a set of "private" variables, which persist over several invocations of the function. The scope of the variable encompasses only the closed-over function, so it cannot be accessed from other program code. However, the variable is of indefinite extent, so a value established in one invocation remains available in the next. As a consequence, closures can be used to hide state, and thus to implement object-oriented programming. The term closure is often mistakenly used to mean anonymous function. This is probably because most languages implementing anonymous functions allow them to form closures and programmers are usually introduced to both concepts at the same time. These are however distinct concepts. The concept of closures was developed in the 1960s and was first fully implemented as a language feature in the programming language Scheme. Since then, many languages have been designed to support closures. (en)
- Замыкание (англ. closure) в программировании — процедура, которая ссылается на свободные переменные в своём лексическом контексте. Замыкание, так же как и экземпляр объекта, есть способ представления функциональности и данных, связанных и упакованных вместе. Замыкание — это особый вид функции. Она определена в теле другой функции и создаётся каждый раз во время её выполнения. В записи это выглядит как функция, находящаяся целиком в теле другой функции. При этом вложенная внутренняя функция содержит ссылки на локальные переменные внешней функции. Каждый раз при выполнении внешней функции происходит создание нового экземпляра внутренней функции, с новыми ссылками на переменные внешней функции. Замыкание связывает код функции с её лексическим окружением . Лексические переменные замыкания отличаются от глобальных переменных тем, что они не занимают глобальное пространство имён. От переменных в объектах они отличаются тем, что привязаны к функциям, а не объектам. Пример работы замыканий на Scheme: <source lang=scheme> ; а n - свободная; делаем процедуру для прибавления 1 ; печатает 11; делаем процедуру для вычитания 1 (sub1 10) ; печатает 9 </source> (ru)
- En Informática, una clausura es una función que es evaluada en un entorno conteniendo una o más variables dependientes de otro entorno. Cuando es llamada, la función puede acceder a estas variables. El uso explícito de clausuras se asocia con programación funcional y con lenguajes como el ML y el Lisp. Construcciones como los objetos en otros lenguajes pueden ser también modelados con clausuras. En algunos lenguajes, una clausura puede aparecer cuando una función está definida dentro de otra función, y la función más interna refiere a las variables locales de la función externa. En tiempo de ejecución, cuando la función externa se ejecuta, una clausura se forma, consistiendo en el código de la función interna y referencias a todas las variables de la función externa que son requeridas por la clausura. Una clausura puede ser usada para asociar una función con un conjunto de variables "privadas", que persisten en las invocaciones de la función. El ámbito de la variable abarca solo al de la función definida en la clausura, por lo que no puede ser accedida por otro código del programa. No obstante, la variable mantiene su valor de forma indefinida, por lo que un valor establecido en una invocación permanece disponible para la siguiente. Como consecuencia, las clausuras pueden ser usadas para esconder estados e implementar programación orientada a objetos. El concepto de clausura fue desarrolla en los años 60 y completamente implementada por primera vez como una característica del lenguaje de programación Scheme. Desde entonces, muchos otros lenguajes han sido diseñados para soportar clausuras. Un ejemplo, en lenguaje Perl <source lang="perl"> !/usr/bin/perl -w Aquí tenemos una función que crea otra, que nos servirá para saber si el argumento que le pasamos es superior o no al del valor de referencia con el que fue creada sub crea_funcion_mayor_que { my $limite = shift; # Valor con el que se creará la función # La variable $limite es local a la función crea_funcion_mayor_que return # Devolvemos sub { # una función return # que nos devuelve $_[0] > $limite; # verdadero si su primer argumento supera nuestro $limite. }; # A partir de este punto $limite debería desaparecer, # pero no lo hace, porque sigue siendo referenciada # por la nueva función que acabamos de crear } my $es_mayor_que_5 = crea_funcion_mayor_que 5; # Creamos una función que comparará con el valor 5 my $es_mayor_que_3 = crea_funcion_mayor_que 3; # Idem, con el valor 3 my $test = 8; # Valor a comparar if ($es_mayor_que_5->) { # Ver si $test $es_mayor_que_5 print "$test es mayor que 5 \n"; } else { print "$test no es mayor que 5 \n"; } Aquí se podría utilizar la función $es_mayor_que_3 de la misma manera. Las dos variables $limite de las dos funciones creadas son completamente independientes entre sí.</source> (es)
- Nei linguaggi di programmazione, una chiusura è una astrazione che combina una funzione e un ambiente a regole di scope lessicale legato ad essa. Le variabili nell'ambiente hanno lo scopo di conservare uno stato tra le varie chiamate alla funzione. Diversamente dalle funzioni classiche, le chiusure possono salvare informazioni tra le diverse chiamate. Le variabili lessicali conservate nell'ambiente della chiusura, differiscono dalle variabili globali per il fatto che non occupano (o inquinano) il namespace delle variabili globali e differiscono dagli attributi degli oggetti nei linguaggi orientati agli oggetti per il fatto che sono legati a funzioni e non ad oggetti. Le chiusure si rivelano particolarmente utili quando una funzione ha bisogno di "ricordare" informazioni derivate dalle precedenti chiamate. Un uso comune è quello di funzioni che hanno bisogno di un comportamento speciale la prima volta che vengono invocate ma non le successive; le chiusure permettono quindi alla funzione di "ricordare" che hanno già svolto quella azione "speciale" la prima volta che sono state chiamate. (it)
- Em ciência da computação e na programação uma closure é uma função que referencia variáveis livres no contexto léxico. Uma closure ocorre normalmente quando uma função é declarada dentro do corpo de outra, e a função interior referencia variáveis locais da função exterior em tempo de execução quando a função exterior é executada, então uma closure é formada. Ela consiste do código da função e referências para quaisquer variáveis no escopo da função exterior que a closure necessita. (pt)
- Als Closure oder Funktionsabschluss bezeichnet man eine Programmfunktion, die beim Aufruf ihren Definitionskontext reproduziert, selbst wenn dieser Kontext außerhalb der Funktion schon nicht mehr existiert. Closures „konservieren“ also ihren Kontext. Closures sind ein Konzept, das aus den funktionalen Programmiersprachen stammt und zum ersten mal in LISP auftrat und in seinem Dialekt Scheme zum ersten mal vollständig unterstützt wurde. Daraufhin wurde es auch in den meisten späteren funktionalen Programmiersprachen (etwa Haskell, Ocaml) unterstützt. Allerdings existieren auch nicht-funktionale Programmiersprachen, die diese Funktion unterstützen. Hier wären JavaScript, Smalltalk, Python, Lua, Ruby, Groovy, PHP und Perl zu nennen, das im Weiteren zur Veranschaulichung dient. Es gibt Vorschläge, nach denen die objektorientierte Programmiersprache Java ab JDK 7 Funktionsabschlüsse unterstützen soll . Der Kontext eines beliebigen Code-Fragments wird unter anderem durch die zur Verfügung stehenden Symbole bestimmt:<source lang="perl"> # pragma use strict; # function sub function { # function vars my; # code ... if { # block vars my; # block code ... } # code ... }</source>Im oben gezeigten Beispiel sind die Variablen $var1 und $var2 an jeder Stelle der Funktion gültig und sichtbar, $scopy1 und $scopy2 jedoch nur innerhalb des Blocks, in dem sie definiert wurden. Beim Verlassen dieses Bereichs werden sie zusammen mit dem verlassenen Block aufgeräumt und sind anschließend unbekannt. Jeder weitere Zugriff wäre ein Fehler. Closures bieten nun die Möglichkeit, den Gültigkeitsbereich solcher Variablen über dessen offizielles Ende hinaus auszudehnen. Dazu wird im Scope einfach eine Funktion definiert, die die betreffenden Variablen verwendet:<source lang="perl"> # pragma use strict; # function refs my; # function sub function { # function vars my; # code ... if { # block vars my; # block code $scopy1=10; $scopy2=1000; # define a closure $c1=sub {print "Scopies: $scopy1, $scopy2.\n"}; } # code ... }</source>Das Laufzeitsystem stellt jetzt beim Aufräumen des if-Blocks fest, dass noch Referenzen auf die Blockvariablen $scopy1 und $scopy2 bestehen – die weiter gültige Variable $c1 verweist auf eine anonyme Subroutine, die ihrerseits Verweise auf die Blockvariablen enthält. $scopy1 und $scopy2 bleiben deshalb mit ihren aktuellen Werten erhalten. Weil die Funktion auf diese Weise die Variablen konserviert, wird sie zur Closure. Mit anderen Worten kann man auch nach dem Verlassen des eigentlichen Gültigkeitsbereichs der Variablen jederzeit den Aufruf $c1-> ausführen und wird im Ergebnis immer wieder die bei der Definition der Funktion gültigen Werte der Variablen angezeigt bekommen.Ändern kann man diese Werte nicht mehr, da die Variablen außerhalb der Closure nicht mehr verfügbar sind. Das liegt aber vor allem an der Funktionsdefinition: natürlich hätte die Closure die Werte nicht nur ausgeben, sondern auch bearbeiten oder auch aufrufendem Code wieder per Referenz zur Verfügung stellen können. In der folgenden Variante werden beispielsweise Funktionen zum Inkrementieren und Dekrementieren eingeführt:<source lang="perl"> # pragma use strict; # function refs my; # function sub function { # function vars my; # code # ... if { # block vars my; # block code $scopy1=10; $scopy2=1000; # define closures $printer=sub {print "Scopies: $scopy1, $scopy2.\n"}; $incrementor=sub {$scopy1++; $scopy2++;}; $decrementor=sub {$scopy1--; $scopy2--;}; } # code # ... } # call the function &function; # use closures $printer->; $incrementor->; $printer->; $incrementor->; $incrementor->; $printer->;</source>Closures lassen sich also beispielsweise dazu verwenden, den Zugriff auf sensible Daten zu kapseln. Folgend ein einfaches Beispiel für einen Zähler in Python, der ohne einen Container auskommt, der den aktuellen Zählerstand speichert.<source lang="python"> def closure: __counter=[0] def inc: __counter[0]+=1 def get: return __counter[0] return inc, get</source>Das Closure wird dann auf die folgende Weise verwendet: >>>,g=closure >>> g 0 >>> i >>> i >>> print g 2 >>> __counter Traceback : File "<stdin>", line 1, in ? NameError: name '__counter' is not definedOCaml, als funktionelle Sprache, erlaubt das in folgender Weise :<source lang="OCaml">let counter, inc, reset = let n = ref 0 in, , </source>jetzt ist der Zähler wie folgt anwendbar :<source lang="OCaml"># counter;; # inc;;# counter;; # inc;inc;inc;;# counter;; # reset;;# counter;; # n;; (* n ist gekapselt *)Unbound value n</source>Statt einem Integer können natürlich auf diese Weise beliebige Objekte oder Variablen beliebiger Typen gekapselt werden. (de)
|