Me he estado mojando las manos con el ceceo de emacs, y una cosa que me sobresalta a veces es el alcance dinámico. ¿Hay mucho futuro para eso? La mayoría de los idiomas que conozco usan el alcance estático (o se han movido al ámbito estático, como Python), y probablemente porque lo sé mejor tiendo a preferirlo. ¿Hay aplicaciones/instancias específicas o ejemplos donde el alcance dinámico es más útil?utiliza para el alcance dinámico?
Respuesta
Hay una buena discusión sobre este problema here. La parte más útil que pertenece a su pregunta es:
Los enlaces dinámicos son excelentes para al modificar el comportamiento de los subsistemas. Supongamos que está utilizando una función 'foo' que genera salida usando 'imprimir'. Pero a veces le gustaría capturar la salida en un búfer de su elección . Con enlace dinámico, es fácil:
(let ((b (generate-new-buffer-name " *string-output*"))))
(let ((standard-output b))
(foo))
(set-buffer b)
;; do stuff with the output of foo
(kill-buffer b))
(Y si se ha utilizado este tipo de cosas mucho , que le encapsular en una macro - pero por suerte ya se ha hecho tan 'con-salida-a-temp-buffer'.)
Esto funciona porque 'foo' utiliza el enlace dinámico del nombre 'standard-output', por lo que puede sustituir su propio unión para t sombrero nombre para modificar el comportamiento de 'foo' - y de todas las funciones que 'foo' llama.
En un lenguaje sin enlace dinámico, lo que probablemente agrega un argumento opcional a ‘foo’ para especificar un buffer y luego ‘foo’ que pasaría a cualquier llamadas a ‘imprimir’. Pero si 'foo' llama al otras funciones que a su vez llaman a 'print', también deberá modificar esas funciones . Y si 'imprimir' tenía otra opción, digamos 'nivel de impresión', , tendría que agregar eso también como argumento opcional ... Alternativamente, usted podría recordar el antiguo valor de 'salida estándar', sustituya su nuevo valor , llame a 'foo' y luego restaure el valor antiguo . Y recuerde manejar salidas no locales usando 'throw'. Cuando ha terminado con esto, verá que ha implementado el enlace dinámico !
Dicho esto, la vinculación léxica es en mi humilde opinión mucho mejor para el 99% de los casos. Tenga en cuenta que los Lisps modernos no son vinculantes dinámicos, solo como el ceceo de Emacs.
- Common Lisp es compatible con ambas formas de vinculación, aunque el léxico se utiliza mucho más
- especificación El Esquema ni siquiera se especifique vinculante (sólo un léxico) dinámico, aunque muchas implementaciones soportan ambos.
Además, los idiomas modernos como Python y Ruby que fueron un poco inspirado en Lisp por lo general apoyan léxica vinculante de una manera directa, con enlace dinámico también disponible pero menos sencillo.
Si lees el Emacs paper (escrito en 1981), hay una sección específica "Language Features for Extensibility" que trata esta cuestión. En Emacs, también existe el alcance agregado de las variables de buffer-local (archivo local).
he citado debajo de la parte más relevante:
Formal Parameters Cannot Replace Dynamic Scope
Algunos diseñadores del lenguaje creen que unión dinámica se debe evitar, y paso de argumentos explícito, deben utilizarse en lugar . Imagine que la función A vincula la variable FOO y llama a la función B , que llama a la función C, y C usa el valor de FOO. Supuestamente A debe pasar el valor como un argumento a B, que debe pasar como un argumento a C.
Esto no se puede hacer en un sistema extensible , sin embargo, porque el autor de el sistema no puede saber cuáles serán todos los parámetros . Imagine que las funciones A y C son parte de una extensión de usuario , mientras que B es parte del sistema estándar . La variable FOO does no existe en el sistema estándar; es es parte de la extensión. Para utilizar paso de argumentos explícitos habría requerir la adición de un nuevo argumento a B, lo que significa volver a escribir B y todo que llama B. En el caso más común, B es el orden del editor despachador bucle, que se llama a partir de una terrible cantidad de lugares.
Lo que es peor, C también se debe pasar un argumento adicional . B no refiere a C por nombre (C no existía cuando se escribió B ). Probablemente encuentre un puntero en C en la tabla de envío de comando . Esto significa que la misma llamada que a veces llama a C podría igualmente llamar a cualquier comando de editor definición. Por lo tanto, todos los comandos de edición deben reescribirse para aceptar e ignorar el argumento adicional. ¡Por ahora, ninguno del sistema original es dejado!
Excelente cita! Este es realmente un excelente ejemplo de cómo la vinculación dinámica es útil. ¡Gracias por compartir! –
Gracias, muy ilustrativo – hatmatrix
- 1. Tareas inadecuadas para el alcance dinámico
- 2. ¿Cierres y alcance dinámico?
- 3. ¿Utiliza llaves para un alcance adicional?
- 4. ¿Cómo convivir con el alcance dinámico de Emacs Lisp?
- 5. Symfony2 ScopeCrossingInjectionException cuando utiliza prototipo de alcance
- 6. Perder alcance cuando se utiliza ng-incluir
- 7. Alcance dinámico - Encuadernación profunda frente a Encolado poco profundo
- 8. ¿Las variables tienen un "alcance" estático o dinámico en javascript?
- 9. Alcance de Lisp común (dinámico frente a léxico)
- 10. ¿Cuál es la diferencia entre el alcance léxico y dinámico en Perl?
- 11. Especifique el alcance para eval() en JavaScript?
- 12. Función PHP use() para el alcance?
- 13. ¿Para qué se utiliza el prototipo Spring Bean?
- 14. ¿Utiliza XSL para generar XSL dinámico que se ejecuta dentro del mismo script?
- 15. CRTP para evitar el polimorfismo dinámico
- 16. ¿Qué tipo de alcance usa Haskell?
- 17. Alcance variable en PowerShell
- 18. no puede inspeccionar variables alcance cuando se utiliza el modo estricto
- 19. maven proporcionó el alcance
- 20. Valores Alcance múltiples para OAuth2
- 21. Alcance y alcance en rieles
- 22. ¿Diferencia entre 'usar' y el alcance?
- 23. poedit solución para gettext dinámico
- 24. ¿Cuáles son las nuevas reglas para el alcance variable en Emacs 24?
- 25. Asp.Net MVC: el mejor enfoque para el enrutamiento "dinámico"
- 26. Autowire primavera y el alcance
- 27. ¿Cómo pruebo para typeof (dinámico)?
- 28. ¿Determinar el alcance de sincronización?
- 29. ¿Cómo actualizar el recurso dinámico dentro de un recurso dinámico?
- 30. ¿Puede el tamaño de almacenamiento dinámico de JVM ser dinámico?
Montones de [respuestas útiles aquí] (http://stackoverflow.com/questions/321000/dynamic-scoping-why) - ¿quizás esto es lo suficientemente cerca como para ser un duplicado? –
Sí, parece que sí. Mi error. – hatmatrix