изменение взаимодействия связывания и pmap?

Есть несколько старых сообщений в блогах, в которых рекомендуется соблюдать осторожность при смешивании динамических переменных, binding и 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

Но это не то, что происходит, когда я запускаю этот код (меняя первую строку на (def ^:dynamic *foo* 5)). Я получаю три 15 в качестве вывода (используя Clojure 1.4), как и можно было бы наивно ожидать, то есть с изменением формы привязки, наблюдаемой функцией, переданной в pmap. Изменился ли способ взаимодействия локальных привязок потока и pmap? Я нигде не могу найти это задокументировано.


person ben w    schedule 24.08.2012    source источник


Ответы (1)


начиная с версии 1.3 набор локальных привязок отправляется в pmap вместе с функцией. Так что, пока вы отмечаете var ^: dynamic, это больше не проблема. Эта функция называется Binding Conveyance и включена в журнал изменений версии 1.3:

из: 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"
person Arthur Ulfeldt    schedule 24.08.2012
comment
Спасибо! где это задокументировано? его нет в dev.clojure.org/display/doc/1.3 - person ben w; 25.08.2012