Clausura (informática)

En informática, un cierre es una función que tiene un entorno propio. En este entorno, hay al menos una variable vinculada (un nombre que tiene un valor, como un número). El entorno de la clausura mantiene las variables ligadas en memoria entre los usos de la clausura.

Peter J. Landin dio a esta idea el nombre de cierre en 1964. El lenguaje de programación Scheme popularizó los cierres después de 1975. Muchos lenguajes de programación hechos después de esa época tienen cierres.

Las funciones anónimas (funciones sin nombre) a veces se denominan erróneamente cierres. La mayoría de los lenguajes que tienen funciones anónimas también tienen cierres. Una función anónima también es un cierre si tiene un entorno propio con al menos una variable vinculada. Una función anónima sin entorno propio no es un cierre. Un cierre con nombre no es anónimo.

Cierres y funciones de primera clase

Los valores pueden ser números o algún otro tipo de datos, como letras, o estructuras de datos formadas por partes más simples. En las reglas de un lenguaje de programación, los valores de primera clase son los que se pueden dar a las funciones, devolver por las funciones y ligar a un nombre de variable. Las funciones que toman o devuelven otras funciones se llaman funciones de orden superior. La mayoría de los lenguajes que tienen funciones como valores de primera clase también tienen funciones de orden superior y cierres.

Por ejemplo, eche un vistazo a la siguiente función de Scheme:

; Devuelve una lista de todos los libros con al menos el umbral de copias vendidas. (define (umbral de libros más vendidos) (filtro (lambda (libro) (>= (libro-venta) umbral)) lista de libros))

En este ejemplo, la expresión lambda (lambda (libro) (>= (libro-ventas) umbral)) forma parte de la función libros-ventas. Cuando la función se ejecuta, Scheme debe hacer el valor de la lambda. Lo hace creando un cierre con el código de la lambda y una referencia a la variable umbral, que es una variable libre dentro de la lambda. (Una variable libre es un nombre que no está ligado a un valor).

La función de filtro ejecuta entonces el cierre en cada libro de la lista para elegir qué libros devolver. Como el propio cierre tiene una referencia al umbral, el cierre puede utilizar ese valor cada vez que el filtro ejecuta el cierre. La función filtro en sí misma puede ser escrita en un archivo completamente separado.

Aquí está el mismo ejemplo reescrito en ECMAScript (JavaScript), otro lenguaje popular con soporte para cierres:

// Devuelve una lista de todos los libros con al menos el "umbral" de copias vendidas. function bestSellingBooks(threshold) { return bookList. filter( function(book) { return book. sales >= threshold; }     ); }

ECMAScript utiliza aquí la palabra function en lugar de lambda, y el método Array.filter en lugar de la función filter, pero por lo demás el código hace lo mismo de la misma manera.

Una función puede crear un cierre y devolverlo. El siguiente ejemplo es una función que devuelve una función.

En el esquema:

; Devuelve una función que aproxima la derivada de f ; usando un intervalo de dx, que debe ser apropiadamente pequeño. (define (derivada f dx) (lambda (x) (/ (- (f (+ x dx)) (f x)) dx))

En ECMAScript:

// Devuelve una función que aproxima la derivada de f // usando un intervalo de dx, que debe ser apropiadamente pequeño. function derivative(f, dx) { return function(x) { return (f(x + dx) - f(x)) / dx; }; }

El entorno de cierre mantiene las variables delimitadas f y dx después de que la función adjunta (derivada) regrese. En lenguajes sin cierres, estos valores se perderían después de que la función de cierre retorne. En los lenguajes con cierres, una variable ligada debe mantenerse en memoria mientras cualquier cierre la tenga.

No es necesario que un cierre se forme utilizando una función anónima. El lenguaje de programación Python, por ejemplo, tiene un soporte limitado para las funciones anónimas pero tiene cierres. Por ejemplo, una forma de implementar el ejemplo de ECMAScript anterior en Python es:

# Devuelve una función que aproxima la derivada de f # usando un intervalo de dx, que debe ser apropiadamente pequeño. def derivative(f, dx): def gradient(x): return (f(x + dx) - f(x)) / dx return gradiente

En este ejemplo, la función llamada gradiente hace un cierre junto con las variables f y dx. La función exterior que la encierra, llamada derivada, devuelve este cierre. En este caso, una función anónima también funcionaría.

def derivada(f, dx): return lambda x: (f(x + dx) - f(x)) / dx

Python debe utilizar a menudo funciones con nombre porque sus expresiones lambda sólo pueden contener otras expresiones (código que devuelve un valor) y no declaraciones (código que tiene efectos pero no valor). Pero en otros lenguajes, como Scheme, todo el código devuelve un valor; en Scheme, todo es una expresión.

Usos de los cierres

Los cierres tienen muchos usos:

  • Los diseñadores de bibliotecas de software pueden permitir a los usuarios personalizar el comportamiento pasando cierres como argumentos a funciones importantes. Por ejemplo, una función que ordena valores puede aceptar un argumento de cierre que compare los valores a ordenar según un criterio definido por el usuario.
  • Dado que los cierres retrasan la evaluación -es decir, no "hacen" nada hasta que se les llama- pueden utilizarse para definir estructuras de control. Por ejemplo, todas las estructuras de control estándar de Smalltalk, incluidas las ramas (if/then/else) y los bucles (while y for), se definen utilizando objetos cuyos métodos aceptan cierres. Los usuarios también pueden definir fácilmente sus propias estructuras de control.
  • Se pueden producir múltiples funciones que se cierren sobre el mismo entorno, lo que les permite comunicarse en privado alterando ese entorno (en los lenguajes que permiten la asignación).

En el esquema

(define foo #f) (define bar #f) (let ((mensaje-secreto "ninguno")) (set! foo (lambda (msg) (set! mensaje-secreto msg)) (set! bar (lambda () mensaje-secreto)) (display (bar)) ; imprime "ninguno" (newline) (foo "nos vemos en el muelle a medianoche") (display (bar)) ; imprime "nos vemos en el muelle a medianoche"
  • Los cierres pueden utilizarse para implementar sistemas de objetos.

Nota: Algunos hablantes denominan cierre a cualquier estructura de datos que vincule un entorno léxico, pero el término suele referirse específicamente a las funciones.

Preguntas y respuestas

P: ¿Qué es un cierre en informática?


R: Un cierre es una función que tiene un entorno propio.

P: ¿Qué contiene el entorno de un cierre?


R: El entorno de un cierre contiene al menos una variable ligada.

P: ¿Quién dio nombre a la idea de cierre?


R: Peter J. Landin dio nombre a la idea de cierre en 1964.

P: ¿Qué lenguaje de programación popularizó los cierres a partir de 1975?


R: El lenguaje de programación Scheme popularizó los cierres después de 1975.

P: ¿Son lo mismo las funciones anónimas y los cierres?


R: Las funciones anónimas a veces se denominan erróneamente cierres, pero no todas las funciones anónimas son cierres.

P: ¿Qué hace que una función anónima sea un cierre?


R: Una función anónima es un cierre si tiene un entorno propio con al menos una variable ligada.

P: ¿Un cierre con nombre es anónimo?


R: No, un cierre con nombre no es anónimo.

AlegsaOnline.com - 2020 / 2023 - License CC3