¿Cuáles son algunos ejemplos de un lenguaje de ámbito dinámico? ¿Y cuáles son las razones para elegir ese diseño? ¿Es porque es fácil de implementar?Además de Logo y Emacs Lisp, ¿cuáles son otros lenguajes de ámbito dinámico puro?
Respuesta
Bueno, hay un montón de sitios web que hablan sobre los pro y los contras, así que no iré allí.
Un lenguaje interesante que tiene algunas características que se asemejan ligeramente al alcance dinámico es XSLT; aunque las plantillas y variables de XSLT y similares tienen un alcance léxico, XSLT es, por supuesto, todo sobre XML, y la posición actual en el árbol xml tiene "alcance dinámico" en el sentido de que el nodo de contexto es global y por lo tanto las expresiones XPath no se evalúan de acuerdo con el alcance léxico de XSLT, pero de acuerdo con su evaluación dinámica.
Mathematica es otro lenguaje que tiene un alcance dinámico, a través del constructo Block
. Esto es realmente bastante útil cuando se trabaja con fórmulas. Se le permite escribir cosas como
In[1]:= expr = a*t^2 + b*t+ c;
In[2]:= Block[{a = 1, b = -1, c = 2}, Table[expr, {t, 5}]]
Out[2]= {2, 4, 8, 14, 22}
que no funcionaría en absoluto si variables como a
y t
se scoped léxico. Funciona particularmente bien con el sistema de reescritura de reglas de Mathematica, que, entre otras cosas, dejará las variables sin evaluar (como expresiones simbólicas) si no tiene una definición existente para ellas.
Mathematica puede simular el alcance léxico con el constructo Module
, pero lo que realmente hace es reescribir la expresión en términos de nuevo símbolo supuestamente único (puede causar enfrentamientos si predice cuál será el próximo símbolo único, lo cual es fácil en la mayoría de los casos). Esto significa
Module[{x = 4},
Table[x * t, {t, 5}]]
se convirtió en algo como esto:
Block[{x$134 = 4},
Table[x$134 * t, {t, 5}]
Emacs Lisp, en una de sus bibliotecas, tiene una construcción (en realidad una macro Lisp) llamada lexical-let
que tira exactamente el mismo truco fingir alcance léxico
Existen ventajas de rendimiento en el alcance léxico real cuando compila el idioma que no obtiene con los léxicos falsos de ELisp o Mathematica, ya que necesita un mapeo entre la variable dinámica y su valor actual, lo que significa haciendo búsquedas (a través de una tabla hash o lista de propiedades o algo así) y capas adicionales de direccionamiento indirecto.
EDITAR: Si tiene sólo las variables léxicas, que pueda ámbito dinámico falsa almacenando el valor original de una variable global, léxica integrarse en el ámbito y garantizar que el valor anterior se restaura al salir del ámbito de aplicación. Para garantizar eso, necesitará algo como el bloque UNWIND-PROTECT
de Lisp o un bloque finally
. He visto esto hecho usando destructores C++ también, principalmente como un ejercicio.
Los idiomas de ámbito dinámico son mucho más fáciles de implementar. Para acceder a las variables que no están en el marco actual de grabación/pila de activación, uno simplemente sigue los enlaces de control. Los enlaces de acceso estático/léxico no son necesarios, lo que hace que los marcos de pila sean más pequeños.
Las variables dinámicas pueden ser "impredecibles" en el tiempo de ejecución, porque es necesario saber en qué orden las estructuras de pila reales sabrán qué variable se utilizará. Esta información no está disponible con solo mirar la estructura estática del código. Uno podría quedar atrapado fácilmente si el gráfico de llamadas real del programa no es fácil de predecir en el momento de la implementación.Es por eso que la mayoría de los idiomas actuales tienen un alcance estático (la mayoría de los sistemas de excepción, sin embargo, son dinámicos ya que es el más práctico).
Sin embargo, en algunos casos, las variables de ámbito dinámico son muy útiles. Por ejemplo, al redirigir la salida, podría usar variables dinámicas para establecer el resultado estándar para el código local y todo el código llamado a partir de allí.
(let ((*standard-output* *some-other-stream*))
(stuff))
En este ejemplo común-lisp (de Seibel), la salida estándar está obligado a otro flujo para la duración de la forma let, (dentro de sus parens de cerramiento). Cuando la ejecución abandona el let, vuelve a ser lo que fue de antemano. Ver http://gigamonkeys.com/book/variables.html Peter Seibels libre y excelente libro, Practical Common Lisp, para una buena discusión. En palabras propias de Seibel:
Los enlaces dinámicos hacen que las variables globales sean mucho más manejables, pero es importante notar que todavía permiten la acción a distancia. La vinculación de una variable global tiene dos efectos de distancia: puede cambiar el comportamiento del código descendente y también abre la posibilidad de que el código descendente asigne un nuevo valor a un enlace establecido más arriba en la pila. Debe usar variables dinámicas solo cuando necesite aprovechar una o ambas de estas características.
El alcance dinámico es/fue más fácil de implementar con intérpretes. La mayoría de los primeros intérpretes de Lisp usaban el alcance dinámico. Después de varios años, se descubrió que el alcance léxico tenía una ventaja, pero primero se implementó principalmente en los compiladores Lisp. Aparecieron varias implementaciones que implementaron el alcance dinámico en el código interpretado y el alcance léxico en el código compilado. Algunos proporcionaron una construcción de lenguaje especial para proporcionar cierres. Los dialectos de Lisp como Scheme y Common Lisp requerían entonces que no existiera diferencia entre el código interpretado y el compilado y, por lo tanto, las implementaciones basadas en interpretación tenían que implementar el alcance léxico.
Implementaciones Early Smalltal implementadas en el alcance dinámico. Todos los tipos de implementaciones de dialectos Lisp implementaron alcance dinámico (Interlisp, UCI Lisp, Lisp Machine Lisp, MacLisp, ...).
Casi todos los nuevos dialectos Lisp de los últimos 20 años usan el alcance léxico por defecto o incluso exclusivamente. Varias publicaciones han descrito en detalle cómo implementar Lisp con alcance léxico, por lo que no hay excusa para no usar el ámbito léxico.
Todos los lenguajes de shell (bash, ksh, etc.) utilizan el alcance dinámico.
- 1. ¿Qué tan viable es emacs LISP además de editar emacs?
- 2. ¿Cuáles son las principales diferencias entre Emacs Lisp y Common Lisp?
- 3. ¿Cómo convivir con el alcance dinámico de Emacs Lisp?
- 4. ¿Cuáles son las nuevas reglas para el alcance variable en Emacs 24?
- 5. ¿Cuáles son los otros valores de NaN?
- 6. Ámbito dinámico en Clojure?
- 7. ¿Cuáles son los IDE "ricos" buenos para Lisp?
- 8. ¿Hay otros idiomas además de D con static si?
- 9. ¿Cuáles son los lenguajes de programación para GPU
- 10. Además de singletons, ¿cuáles son algunas de las razones convincentes para usar métodos estáticos en PHP?
- 11. Usos tanto para lenguajes fuertes estáticos como Haskell como para lenguajes dinámicos (fuertes) como Common LIsp
- 12. ¿Cuáles son los populares lenguajes de programación funcionales 'listos para la web'?
- 13. Técnicas de solución de problemas para Emacs y Emacs Lisp
- 14. Diferencia de estructura entre lisp común y emacs lisp
- 15. Otros protocolos comunes además de HTTP?
- 16. ¿Cómo crear variables de ámbito dinámico en Python?
- 17. Además del registro y la gestión de transacciones, ¿cuáles son algunas aplicaciones prácticas de AOP?
- 18. ¿Cuáles son algunos de los lenguajes más 'puros' orientados a objetos?
- 19. ¿Cuáles son las ventajas de usar Prolog en otros idiomas?
- 20. Fechas y horas en Emacs Lisp
- 21. Análisis en Emacs Lisp
- 22. Cuáles son las desventajas de Typed DataSets
- 23. ¿Cuáles son las bibliotecas y utilidades esenciales de Java para un usuario de lenguaje dinámico recurrente?
- 24. Emacs Lisp resaltado de sintaxis
- 25. dejó y flet en Emacs Lisp
- 26. ¿Cuáles son tus encuadernaciones de teclas globales favoritas en emacs?
- 27. ¿Hay un modo de Emacs HTML5 puro?
- 28. PINTURA en Emacs Lisp?
- 29. Emacs sin Lisp
- 30. Interesado en VM para lenguajes parecidos a lisp en el sistema de 8 bits
Érase una vez, todas las versiones de Lisp que conocía tenían un alcance dinámico. elisp es uno de los últimos supervivientes de ese momento. –