2012-08-24 8 views
5

Existen varias publicaciones de blog algo antiguas que aconsejan precaución al mezclar variables dinámicas, binding y pmap, p. Ej. here, donde obtenemos el siguiente fragmento de código:cambio de interacción vinculante y pmap?

user=> (def *foo* 5) 
#'user/*foo* 
user=> (defn adder 
      [param] 
      (+ *foo* param)) 
#'user/adder 
user=> (binding [*foo* 10] 
     (doseq [v (pmap adder (repeat 3 5))] 
      (println v))) 
10 
10 
10 
nil 

Pero eso no es lo que sucede cuando corro ese código (cambiando la primera línea de (def ^:dynamic *foo* 5)). Obtengo tres 15 s como salida (usando Clojure 1.4), tal como lo esperaría ingenuamente —, es decir, con el cambio en la forma de enlace visto por la función pasada a pmap. ¿Han cambiado las vinculaciones locales de subprocesos y pmap? No puedo encontrar esto documentado en ningún lado.

Respuesta

5

comenzando en 1.3 el conjunto de enlaces locales se envían a pmap junto con la función. Por lo tanto, siempre que marque el var ^: dinámico esto ya no es un problema. Esta característica se llama Traspaso de encuadernación y está incluido en la lista de cambios 1.3:

de: https://github.com/clojure/clojure/blob/1.3.x/changes.txt

 
Clojure APIs that pass work off to other threads (e.g. send, send-off, pmap, future) now convey the dynamic bindings of the calling thread: 

    (def ^:dynamic *num* 1) 
    (binding [*num* 2] (future (println *num*))) 
    ;; prints "2", not "1" 
+0

gracias! ¿Dónde está esto documentado? no está en http://dev.clojure.org/display/doc/1.3 –

+0

edición para incluir referencias –

+0

¡Gracias! Apreciado. –