2012-08-24 13 views
5

Ci sono diversi post di blog un po 'vecchi che consigliano cautela quando si mescolano variabili dinamiche, binding e pmap, ad es. here, dove si ottiene il seguente frammento di codice:modifica interazione e 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 

Ma questo non è ciò che accade quando si esegue il codice (cambiando la prima linea a (def ^:dynamic *foo* 5)). Ottengo tre 15 s come output (usando Clojure 1.4), proprio come si potrebbe facilmente prevedere — cioè con la modifica della forma di binding vista dalla funzione passata a pmap. Hanno cambiato il modo in cui i collegamenti thread-local e pmap interagiscono? Non riesco a trovare questo documentato ovunque.

risposta

5

a partire da 1.3 il set di associazioni locali viene inviato a pmap insieme alla funzione. Quindi, fino a quando contrassegni var ^: dynamic, questo non è più un problema. Questa funzione si chiama Binding Conveyance ed è incluso nel 1.3 changelog:

da: 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

grazie! dove è documentato? non è disponibile in http://dev.clojure.org/display/doc/1.3 –

+0

per includere i riferimenti –

+0

Grazie! Apprezzato. –

Problemi correlati