binding clojure eval let

binding - Alcance variable+eval en Clojure



let (1)

1 .:

La razón por la que esto no funciona es (más o menos) dada en la página que vinculó:

It is an error if there is no global var named by the symbol […]

Y:

[…]

  1. Se realiza una búsqueda en el espacio de nombres actual para ver si hay una asignación del símbolo a una var. Si es así, el valor es el valor de la unión de la var a la que hace referencia el símbolo.

  2. Es un error.

eval evalúa formularios en un entorno léxico vacío ( null en CL-lingo). Esto significa que no puede acceder a los enlaces de variables léxicas desde el alcance de la persona que llama. Además, el binding crea nuevos enlaces para vars existentes, por lo que no puede usarlo "por sí mismo", sin haber declare o def las variables que intenta vincular. Además, las variables léxicas (al menos en CL, pero me sorprendería si este no fuera el caso de Clojure) ya no existían en el tiempo de ejecución: se traducen a direcciones o valores.

Véase también mi post más antiguo sobre este tema.

2 .:

Entonces, tienes que usar variables dinámicas. Puede evitar la def explícita, pero al menos todavía tiene que declare (cuáles son los nombres var de las def sin enlaces):

user=> (declare ^:dynamic x) #''user/x user=> (binding [x 10] (eval ''(prn x))) 10 nil

Por cierto: supongo que sabes por qué necesitas una evaluación y que su uso se considera malo cuando otras soluciones serían apropiadas.

En Clojure,

(def x 3) (eval ''(prn x))

imprime 3, mientras que

(let [y 3] (eval ''(prn y)))

y

(binding [z 3] (eval ''(prn z)))

generar una excepción ''No se puede resolver var''.

Según http://clojure.org/evaluation , eval , load-string , etc., generan espacios de nombres temporales para evaluar sus contenidos. Por lo tanto, esperaría que ninguno de los ejemplos de código anteriores funcione, ya que (def x 3) se realiza en mi espacio de nombres actual, no en el creado por eval .

  1. ¿Por qué funciona el primer ejemplo de código y no los dos últimos?
  2. ¿Cómo puedo eval un formulario con variables enlazadas sin usar def ?

¡Gracias!