una que pasado internas interna hemos grado externas escala enlace economía economias economia definicion alcance scope lexical-scope dynamic-scope

scope - que - hemos pasado de una economía de escala a una economía de alcance



¿Cuáles son las ventajas del alcance dinámico? (10)

Aprendí que el alcance estático es la única forma sensata de hacer las cosas, y que el alcance dinámico es la herramienta del diablo, y solo se obtiene a partir de implementaciones deficiente de intérpretes / compiladores.

Luego vi este fragmento de un artículo de Common Lisp vs. Scheme :

Both Lexically and Dynamically Lexical scope only, per the standard. scoped special vars. Common Dynamically scoped vars are provided Lisp just wins on this point. by some implementations as an extension but code using them is not portable. (I have heard the arguments about whether Dynamic scoping is or is not a Bad Idea in the first place. I don''t care. I''m just noting that you can do things with it that you can''t easily do without it.)

¿Por qué Common Lisp "solo gana en este punto"? ¿Qué cosas son más fáciles de hacer con el alcance dinámico? Realmente no puedo justificar que alguna vez lo necesite / verlo como algo bueno.


El riesgo principal con alcance dinámico son las consecuencias involuntarias. El alcance dinámico hace que el alcance siga la pila de tiempo de ejecución, lo que significa que el conjunto de símbolos en el alcance es mucho más grande y está lejos de ser obvio en el momento en que se usa un símbolo. Las variables de ámbito dinámico se parecen mucho a las variables globales, solo que puede haber más de una versión de cada variable con solo la última definición visible, que oculta todas las demás.

Alcance dinámico, en la medida en que sea útil, es útil para el comportamiento que debe ser sensible a la pila de tiempo de ejecución. Por ejemplo (y hablando en general, no específico para Lisp o variantes):

  • manejo de excepciones: el bloque de captura más alto es el que está "dentro del alcance" cuando ocurre una excepción
  • seguridad: la seguridad basada en código .NET toma decisiones sobre el acceso de ciertas API privilegiadas según el código que lo haya llamado.

El problema de confiar en él para otros usos es que crea dependencias implícitas y el acoplamiento entre piezas de código lexíticamente distantes. De esta forma, también es similar a las variables globales, solo que puede ser peor (debido a las definiciones reemplazadas dinámicamente).


El alcance dinámico permite la definición de funciones contextuales. En ese sentido, es bastante similar a la inyección de dependencia en los marcos modernos. (Por ejemplo, considere cuando anota una clase Java con definiciones de inyección de dependencia para permitir la inicialización transparente de varias referencias. (Cf spring, o JPA, etc.))

Obviamente, el alcance dinámico hace ciertas suposiciones con respecto a las características de tiempo de ejecución del sitio de invocación para una función dada que no se puede garantizar en el tiempo de compilación (o diseño). De nuevo, siguiendo el ejemplo de un componente de framework moderno (Java), si crea una instancia de dicha clase fuera del entorno controlado (runtime) de un contenedor, es muy posible que la clase no pueda funcionar dado que sus dependencias requeridas no se habrá inicializado (también conocido como inyectado).

Pero igualmente obvio, los sistemas componentes (como solo un ejemplo) se benefician claramente de los mecanismos dinámicos de enlace. La inyección de dependencia es un medio de nivel de marco para lograr esto. El alcance dinámico es un medio de nivel de idioma del mismo.


Las variables de ámbito dinámico son una herramienta poderosa, pero a veces poco intuitiva y peligrosa.

Imagine que desea tener variables globales específicas de subprocesos, es decir, cada subproceso tiene su propio conjunto de variables globales. Esto se puede hacer fácilmente con un alcance dinámico. Simplemente cambie las referencias a estas variables en la inicialización del hilo.

O piense en excepciones: tienen un alcance dinámico en la mayoría de los idiomas. Si tuviera que crear un sistema de excepciones desde cero, podría hacerlo fácilmente con variables de ámbito dinámico.


Como todo lo demás, Dynamic Scoping es simplemente una herramienta. Si se usa bien, puede facilitar ciertas tareas. Si se usa mal, puede provocar errores y dolores de cabeza.

Ciertamente puedo ver algunos usos para eso. Uno puede eliminar la necesidad de pasar variables a algunas funciones.

Por ejemplo, puedo configurar la pantalla al comienzo del programa, y ​​cada operación gráfica solo asume esta pantalla.

Si deseo configurar una ventana dentro de esa pantalla, entonces puedo ''agregar'' esa ventana a la pila variable que de otra manera especifica la pantalla, y cualquier operación gráfica realizada mientras esté en este estado irá a la ventana en lugar de la pantalla como una todo.

Es un ejemplo inventado que se puede hacer igualmente bien al pasar parámetros a las funciones, pero cuando observa algo del código que este tipo de tarea genera, se da cuenta de que las variables globales son realmente mucho más fáciles de seguir, y el alcance dinámico le da una gran parte de la cordura de las variables globales con la flexibilidad de los parámetros de función .

-Adán


El alcance dinámico rompe la transparencia referencial , lo que significa que ya no puede razonar sobre el programa. DS es básicamente variables globales en esteroides.


También tenga en cuenta que la combinación

  • el concepto de alcance léxico (que, creemos, es una buena cosa para un lenguaje de programación, a diferencia del alcance dinámico )
  • con definiciones de funciones (expresiones lambda) incrustadas profundamente en el código (también se podría llamar a tales definiciones "funciones anidadas" como cortas)

puede llegar a ser un esfuerzo complejo, tanto desde el punto de vista de la implementación del lenguaje como desde el punto de vista del programador. Incluso hay un nombre especial para esta cosa compleja: cierre .

Como Wikipedia escribe :

La correcta implementación del alcance estático en lenguajes con funciones anidadas de primera clase no es trivial, ya que requiere que cada valor de función lleve consigo un registro de los valores de las variables de las que depende (el par de la función y este entorno se llama un cierre ).

Esto no solo es no trivial para implementar en un lenguaje con variables globales y / o variables (como C o Java; piense en asegurar un acceso correcto en el momento de la evaluación de un cierre al estado mutable que estaba en el alcance en el lugar de la definición de función anidada. Una sola cosa: los objetos usados ​​no deberían haber sido destruidos y recolectados en la basura cuando evalúes el cierre en algún momento en el futuro), pero tampoco es trivial conceptualmente que un programador piense cómo el el cierre funcionará en una situación compleja y cuál (exactamente) afectará exactamente (por la misma razón: debe pensar en la interacción del cierre con todo el estado mutable que estaba en el alcance cuando definió el cierre, por ejemplo : Cuando refiere dentro de una definición de cierre a una variable mutable externa que está dentro del alcance, ¿realmente desea acceder al valor que tenía la variable en el momento de la definición del cierre, es decir, desea tener un valor de solo lectura? copia de la variable, o si desea ¿Acceso continuo al estado mutable de la variable en el futuro en el momento de una evaluación del cierre? )

En los lenguajes funcionales puros, es mucho más simple pensar en las definiciones de función anidadas y sus usos, por lo que tener solo alcance léxico no es un problema para ellos. Pero si su idioma no es funcional, no es tan trivial. (Creo que es una de las razones por las que se debatió durante mucho tiempo cómo agregar cierres a Java: no parecían ser lo suficientemente triviales como para que un programador lo entendiera, aunque solo se basan en el concepto agradable de alcance léxico .)

Pensar en funciones anidadas en lenguajes no puramente funcionales es más simple con un alcance dinámico (aunque el alcance dinámico no es bueno: obtienes menos verificaciones en tiempo de compilación y garantías sobre el comportamiento correcto de tu programa con alcance dinámico).

Por lo tanto, creo que la ventaja de tener un alcance dinámico disponible en un idioma también puede ser la posibilidad de programar algunas cosas de una manera simple si uno quiere y se atreve a hacer esto dados todos los peligros del alcance dinámico.

Notas

En cuanto a la larga historia de (no) cierres en Java (y que a los programadores no les gustó el concepto) - http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg04030.html :

Fecha: jue, 14 de agosto de 2003, 08:05:44 -0700

De: Michael Vanier

Asunto: Re: enlaces y asignaciones (fue: Re: continuaciones)

Fecha: jue, 14 de agosto de 2003 10:45:34 -0400

De: "David B. Tucker"

Me imagino, aunque no tengo evidencia estadística, que el requisito de declarar las variables locales como definitivas para hacer referencia a ellas dentro de clases internas anónimas (cierres) es casi completamente desconocido y no se usa en la práctica.

Por curiosidad, ¿alguien sabe por qué Java solo permite que las variables finales sean referenciadas desde clases anónimas?

Dave

<cynic>Otherwise you''d have the equivalent of true closures, and if you had that java would be a *really* powerful and useful language, so they obviously couldn''t do that. </cynic>

En realidad, la implementación del prototipo permitió que las variables no finales se referenciaran desde dentro de las clases internas. ¡Hubo una protesta de los usuarios , quejándose de que no querían esto! La razón era interesante: para soportar tales variables, era necesario distribuirlas, y (en ese momento, al menos) el programador Java promedio todavía estaba bastante asustado acerca de la asignación de montón y recolección de basura y todo eso. Desaprobaron el lenguaje que realizaba la asignación del montón "debajo de la mesa" cuando no aparecía la palabra clave "nueva" a la vista.

Entonces, en los primeros días, aparentemente, un "tercer" enfoque (en oposición a los dos que he mencionado en mi texto anterior) debía tomarse en Java: ni "copias de solo lectura", ni acceso real en el tiempo de la evaluación al estado variable adjunto (en el momento de la definición del cierre), sino copias mudables del estado (al menos, entiendo el pasaje citado de esta manera, o no, ¿está hablando de la asignación de montones solo las referencias? .. Entonces es la segunda opción. Bien. La tercera opción realmente no parece sensata para mí.). No estoy seguro de cómo están implementando los cierres hoy en día en Java, no he estado siguiendo las últimas novedades sobre Java.


Este clásico artículo de Richard Stallman (de GNU / Linux, Emacs, FSF) explica por qué el alcance dinámico es importante para el editor de Emacs y el lenguaje de Emacs Lisp. En resumen, es útil para personalizar.

http://www.gnu.org/software/emacs/emacs-paper.html#SEC17

Consulte también esta página en la wiki de Emacs para obtener más información sobre el uso del alcance dinámico en Emacs Lisp:


Un ejemplo que es conveniente para mí en la forma de encuadernación de Emacs: no estoy seguro si léxico o dinámico es el término correcto por cierto.

Una variable ligada dentro de un let se ve hacia abajo, no se requiere una transferencia explícita como argumento, lo que ahorra muchas pulsaciones de teclas.

(defun foo1 () (message "%s" a)) (defun foo2 () (let ((a 2)) (message "%s" a))) (defun foo3 () (let ((a 1)) (foo1) (foo2))) ==> 1 2

El enlace dentro de foo2 es de interés, ya que el uso de valores predeterminados podría instalarse aquí

(let ((a (if (eq something a) asigne lo contrario ...


Creo que el alcance dinámico en Common LISP es una analogía de Global Variable en C. Su uso en funciones funcionales es problemático.


El alcance dinámico es útil en algunos lenguajes específicos de dominio. En particular, puede ser práctico en lenguajes de hojas de estilo. Mi experiencia es del lenguaje de hojas de estilo GNU TeXmacs .

En este lenguaje, los parámetros de visualización se almacenan en variables de ámbito dinámico. Esas variables afectan la representación de cada átomo en su alcance, incluidos los átomos que son producidos por funciones llamadas en el alcance.

El alcance dinámico en TeXmacs también se usa, entre otras cosas, para etiquetar referencias cruzadas. Los anclajes utilizados para referencias cruzadas obtienen su etiqueta de su entorno. Por ejemplo, un ancla incluida en un bloque de fórmula usará el número de fórmula como etiqueta, en lugar del número de sección para un anclaje ubicado después de la fórmula.

Ahora que lo pienso, las variables de entorno de Unix también son variables de ámbito dinámico. Sin embargo, los ámbitos internos no pueden alterar el valor de las variables en los ámbitos externos.

Como observó Barry Kelly, el alcance dinámico también puede ser útil para implementar funciones de lenguaje que se preocupen por el alcance de la llamada, como el manejo de excepciones o el manejo de permisos dependiente del contexto. En presencia de continuaciones, los alcances se pueden ingresar y salir sin pasar por la pila de llamadas.