2010-09-10 19 views
7

Creo que entiendo por qué existe el peligro de permitir cierres en un idioma con alcance dinámico. Es decir, parece que podrá cerrar la variable OK, pero cuando intente leerla solo obtendrá el valor en la parte superior de la pila global. Esto podría ser peligroso si otras funciones usan el mismo nombre en el ínterin.¿Cierres y alcance dinámico?

¿He echado en falta alguna otra sutileza?

Respuesta

6

Sí, ese es el problema básico. El término "cierre" es la abreviatura de "cierre léxico", sin embargo, que by definition captures its lexical scope. Llamaría a las cosas en un lenguaje de ámbito dinámico algo más, como LAMBDA. Las lambdas son perfectamente seguras en un lenguaje dinámicamente definido siempre que no intentes devolverlas.

(Para un experimento interesante, comparar el problema de la devolución de un lambda de ámbito dinámico en Emacs Lisp al problema de devolver una referencia a una variable de pila asignado en C, y cómo ambos son imposibles en el Esquema.)

Hace mucho tiempo, cuando los idiomas con alcance dinámico eran mucho menos raros que hoy, esto se conoce como funargs problem. El problema que mencionas es el problema de los piratas ascendentes.

+3

No editaré la respuesta, pero: "Normalmente" es incorrecta: los cierres son siempre "cierre léxico", denominados así porque cierran la expresión sobre su entorno léxico En cuanto a que las lambdas son seguras, no poder usar lambdas como cierres está disminuyendo enormemente su valor, pero incluso sin eso, el alcance dinámico es intrínsecamente malo para la salud de tu programa, ya que no puedes estar seguro del significado de ninguna vinculación. –

+0

Gracias por el enlace de funargs. Nunca aprendí esto antes. –

+0

@Eli Barzilay: Tienes razón, estaba siendo demasiado desechable. Eliminaré 'generalmente'. En cuanto a la salud general del programa, estoy totalmente de acuerdo, pero la pregunta no es general. Como dije, las lambdas de alcance dinámico son casi tan seguras como las punteros sin restricciones ... –

7

Me doy cuenta de que llevo años respondiendo esto, pero acabo de encontrarme con esta pregunta mientras hacía una búsqueda en la web y quería corregir alguna información errónea que se publica aquí.

"Cierre" solo significa un objeto invocable que contiene tanto código como un entorno que proporciona enlaces para variables libres dentro de ese código. Ese entorno suele ser un entorno léxico, pero no existe una razón técnica por la que no pueda ser un entorno dinámico.

El truco está en cerrar el código sobre el entorno y no en los valores particulares. Esto es lo que hizo Lisp 1.5, y también lo que MACLisp hizo por "funargs descendentes".

se puede ver cómo Lisp 1.5 hizo esto mediante la lectura del manual de 1.5 Lisp en http://www.softwarepreservation.org/projects/LISP/book

Prestar especial atención en el Apéndice B a cómo maneja eval FUNCIÓN y cómo aplicar las manijas FUNARG.

Puede conseguir el sabor básico de programación utilizando cierres dinámicos de http://c2.com/cgi/wiki?DynamicClosure

Usted puede obtener una en la introducción profundidad a las cuestiones de aplicación de ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-199.pdf

moderna de ámbito dinámico idiomas utilizan generalmente poco profunda unión, donde la corriente el valor de cada variable se mantiene en una ubicación global, y las llamadas a función guardan los valores antiguos en la pila. Una forma de implementar cierres dinámicos con enlace poco profundo se describe en http://www.pipeline.com/~hbaker1/ShallowBinding.html

+0

Me doy cuenta de que podría tardar años preguntándome esto: P, pero ¿te importaría explicar qué son 'make-adder',' addx' y 'do-test' de este [enlace] (http: //wiki.c2.com/?DynamicClosure) a los que se hace referencia? Según el manual de Lisp 1.5, no son cierres de funciones aunque definidos con 'lambda'. Parecen más macros y se sustituyen por meras expresiones (es decir, sin entornos asociados). – wlnirvana

+0

Son funciones normales con un alcance dinámico. Cuando se les llama, tienen acceso a variables dentro de su alcance dinámico. El único cierre/funarg en este programa es el creado por FUNCTION. – Glomek

+0

Muy bien, tal vez esto sea solo una cuestión de nomenclatura, pero prefiero decir que no hay tal cosa llamada "cierres dinámicos" (que personalmente creo que es confuso que aclarar). El documento AIM-199.pdf hace referencia al origen de la palabra cierre, que sugiere que primero se usó solo para expresiones lambda "cerradas". Las funciones de ámbito dinámico, cuyas variables libres escapan al entorno de tiempo de ejecución actual, no se cierran en este sentido, por lo que se denominan "expresiones lambda abiertas" en ese documento. – wlnirvana