Concurrency 没有deref就无法实现副作用
来自clojure的勇敢与真诚:Concurrency 没有deref就无法实现副作用,concurrency,clojure,Concurrency,Clojure,来自clojure的勇敢与真诚: (defmacro enqueue [q concurrent-promise-name & work] (let [concurrent (butlast work) serialized (last work)] `(let [~concurrent-promise-name (promise)] (future (deliver ~concurrent-promise-name (do ~@concur
(defmacro enqueue
[q concurrent-promise-name & work]
(let [concurrent (butlast work)
serialized (last work)]
`(let [~concurrent-promise-name (promise)]
(future (deliver ~concurrent-promise-name (do ~@concurrent)))
(deref ~q)
~serialized
~concurrent-promise-name)))
(defmacro wait
"Sleep `timeout` seconds before evaluating body"
[timeout & body]
`(do (Thread/sleep ~timeout) ~@body))
(time @(-> (future (wait 200 (println "'Ello, gov'na!")))
(enqueue saying (wait 400 "Pip pip!") (println @saying))
(enqueue saying (wait 100 "Cheerio!") (println @saying))))
如果我注释掉(deref~q)
行,则只打印“Cheerio!”。为什么我需要deref来获得其他副作用 如果您注释掉(deref~q)
,则与q
一起传递的代码永远不会被计算,因此嵌套的未来不会出现
宏观扩张:
(macroexpand '(-> (future (wait 200 (println "'Ello, gov'na!")))
(enqueue saying (wait 400 "Pip pip!") (println @saying))
(enqueue saying (wait 100 "Cheerio!") (println @saying))))
;;-> ....
(clojure.pprint/pp)
(let*
[saying (clojure.core/promise)]
(clojure.core/future
(clojure.core/deliver saying (do (wait 100 "Cheerio!"))))
;; no code ended up here...
(println @saying)
saying)
我不太明白这段代码应该实现什么。但这可能不是有意的:第一个
排队
接收未来
作为其第一个参数,第二个排队
接收在第一个排队
中创建的承诺。还有什么是说的
?说的
只是承诺的一个名称。当然,您可以使用任何其他名称。如果其他任何人发现自己在这方面遇到了障碍,那么deref
在这里并不是最重要的:它根本就是引用了q
参数<如果将deref
替换为do
、println
或各种其他功能,则code>enqueue
将继续按预期工作。