Clojure。 Intellij。延迟。同时。从头开始的 Clojure
Clojure. Intellij. Delay. Concurrent. Clojure from the Ground Up
我正在尝试解决 Clojure From the Ground Up 第 6 章末尾的练习。
这是我遇到的第一个问题...
(defn sum [start end] (delay (reduce + (range start end)))) ;; Define sum.
=> #'chapter6.core/sum
(time (sum 0 1e7)) ;; Start sum but it delays, so almost no time elapses.
"Elapsed time: 0.2808 msecs"
=> #object[clojure.lang.Delay 0x2656db01 {:status :pending, :val nil}]
(deref sum) ;; Ask for the result. This should take some time. Only it doesn't. It errors right away.
Execution error (ClassCastException) at chapter6.core/eval1595 (form-init10872915734268438705.clj:1).
class chapter6.core$sum cannot be cast to class java.util.concurrent.Future (chapter6.core$sum is in unnamed module of loader cloju-re.lang.DynamicClassLoader @7c650722; java.util.concurrent.Future is in module java.base of loader 'bootstrap')
我是新来的。我对 "bootstrap" 或 "module" 或...
我究竟做错了什么?先感谢您。
顺便说一句,练习是否有“...从头开始”的答案?
成功:
(deref (sum 0 1e7))
您的函数仅 returns 延迟 调用时 。在 (deref sum)
中,没有任何东西调用它(事实上,你永远不会提供参数值将强制包含 were 它调用)。相反,您尝试取消引用函数 sum
本身,这是非法的,因为函数不是延迟。
创建项目比在 REPL 中 运行 更容易看到细节。考虑将您的代码添加到 this template project:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require [tupelo.misc :as misc]))
(defn sum
[start end]
(delay (reduce + (range start end)))) ;; Define sum.
(dotest
(time (sum 0 1e7)) ;; Start sum but it delays, so almost no time elapses.
(let [delay-val (sum 0 1e7)] ; sum returns a delay
(spyxx delay-val) ; print name & type of `delay-val`
(time (deref delay-val)) ; `deref` forces the computation of the sum
(spyxx (deref delay-val)) ; print expression & type
))
结果:
-------------------------------
Clojure 1.10.1 Java 13
-------------------------------
Testing tst.demo.core
"Elapsed time: 0.140221 msecs" ; from first `time`
delay-val => <#clojure.lang.Delay #object[clojure.lang.Delay 0x455cd186 {:status :pending, :val nil}]>
"Elapsed time: 189.021064 msecs" ; from 2nd `time`
(deref delay-val) => <#java.lang.Long 49999995000000>
还有更多文档 in the README and the API docs。
尝试添加:
(spyxx sum)
产生:
sum => <#tst.demo.core$sum #object[tst.demo.core$sum 0x539edd3 "tst.demo.core$sum@539edd3"]>
这就是Clojure如何"prints"函数的值。
如果您犯了一个错误,您可以在错误消息中得到一个行号,这对您有很大帮助。取消引用一个函数是不合法的,所以我们得到一个错误:
(deref sum) ; on line #17 of my file
产生:
ERROR in (dotest-line-9) (core.clj:2298)
Uncaught exception, not in assertion.
expected: nil
actual: java.lang.ClassCastException: class tst.demo.core$sum cannot be cast to class java.util.concurrent.Future (tst.demo.core$sum is in unnamed module of loader clojure.lang.DynamicClassLoader @67af3485; java.util.concurrent.Future is in module java.base of loader 'bootstrap')
at clojure.core$deref_future.invokeStatic (core.clj:2298)
clojure.core$deref.invokeStatic (core.clj:2320)
clojure.core$deref.invoke (core.clj:2306)
tst.demo.core$fn__21007.invokeStatic (core.clj:17) # ***** error line number *****
tst.demo.core/fn (core.clj:9)
clojure.test$test_var$fn__9737.invoke (test.clj:717)
clojure.test$test_var.invokeStatic (test.clj:717)
<...snip...>
更新
不要忘记在 project.clj
下的 :dependencies
:
中包含此行
[tupelo "0.9.198"]
有关示例,请参阅 this template project。
我正在尝试解决 Clojure From the Ground Up 第 6 章末尾的练习。 这是我遇到的第一个问题...
(defn sum [start end] (delay (reduce + (range start end)))) ;; Define sum.
=> #'chapter6.core/sum
(time (sum 0 1e7)) ;; Start sum but it delays, so almost no time elapses.
"Elapsed time: 0.2808 msecs"
=> #object[clojure.lang.Delay 0x2656db01 {:status :pending, :val nil}]
(deref sum) ;; Ask for the result. This should take some time. Only it doesn't. It errors right away.
Execution error (ClassCastException) at chapter6.core/eval1595 (form-init10872915734268438705.clj:1).
class chapter6.core$sum cannot be cast to class java.util.concurrent.Future (chapter6.core$sum is in unnamed module of loader cloju-re.lang.DynamicClassLoader @7c650722; java.util.concurrent.Future is in module java.base of loader 'bootstrap')
我是新来的。我对 "bootstrap" 或 "module" 或... 我究竟做错了什么?先感谢您。 顺便说一句,练习是否有“...从头开始”的答案?
成功:
(deref (sum 0 1e7))
您的函数仅 returns 延迟 调用时 。在 (deref sum)
中,没有任何东西调用它(事实上,你永远不会提供参数值将强制包含 were 它调用)。相反,您尝试取消引用函数 sum
本身,这是非法的,因为函数不是延迟。
创建项目比在 REPL 中 运行 更容易看到细节。考虑将您的代码添加到 this template project:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require [tupelo.misc :as misc]))
(defn sum
[start end]
(delay (reduce + (range start end)))) ;; Define sum.
(dotest
(time (sum 0 1e7)) ;; Start sum but it delays, so almost no time elapses.
(let [delay-val (sum 0 1e7)] ; sum returns a delay
(spyxx delay-val) ; print name & type of `delay-val`
(time (deref delay-val)) ; `deref` forces the computation of the sum
(spyxx (deref delay-val)) ; print expression & type
))
结果:
-------------------------------
Clojure 1.10.1 Java 13
-------------------------------
Testing tst.demo.core
"Elapsed time: 0.140221 msecs" ; from first `time`
delay-val => <#clojure.lang.Delay #object[clojure.lang.Delay 0x455cd186 {:status :pending, :val nil}]>
"Elapsed time: 189.021064 msecs" ; from 2nd `time`
(deref delay-val) => <#java.lang.Long 49999995000000>
还有更多文档 in the README and the API docs。
尝试添加:
(spyxx sum)
产生:
sum => <#tst.demo.core$sum #object[tst.demo.core$sum 0x539edd3 "tst.demo.core$sum@539edd3"]>
这就是Clojure如何"prints"函数的值。
如果您犯了一个错误,您可以在错误消息中得到一个行号,这对您有很大帮助。取消引用一个函数是不合法的,所以我们得到一个错误:
(deref sum) ; on line #17 of my file
产生:
ERROR in (dotest-line-9) (core.clj:2298)
Uncaught exception, not in assertion.
expected: nil
actual: java.lang.ClassCastException: class tst.demo.core$sum cannot be cast to class java.util.concurrent.Future (tst.demo.core$sum is in unnamed module of loader clojure.lang.DynamicClassLoader @67af3485; java.util.concurrent.Future is in module java.base of loader 'bootstrap')
at clojure.core$deref_future.invokeStatic (core.clj:2298)
clojure.core$deref.invokeStatic (core.clj:2320)
clojure.core$deref.invoke (core.clj:2306)
tst.demo.core$fn__21007.invokeStatic (core.clj:17) # ***** error line number *****
tst.demo.core/fn (core.clj:9)
clojure.test$test_var$fn__9737.invoke (test.clj:717)
clojure.test$test_var.invokeStatic (test.clj:717)
<...snip...>
更新
不要忘记在 project.clj
下的 :dependencies
:
[tupelo "0.9.198"]
有关示例,请参阅 this template project。