没有取消引用就无法实现副作用
Side effects not realized without deref
来自 clojure for the brave and true:
(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 ~q)
,通过 q
传递的代码将永远不会被计算,因此嵌套 futures 不会存在。
宏展开:
(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)
来自 clojure for the brave and true:
(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 ~q)
,通过 q
传递的代码将永远不会被计算,因此嵌套 futures 不会存在。
宏展开:
(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)