0

I'm trying to solve the Exercises at the end of Chapter 6 of Clojure From the Ground Up. Here's what happens to me on the Very First Problem there...

  (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')

I'm new. I know nothing of "bootstrap" or "module" or... What am I doing wrong? Thank you in advance. BTW, is there a "...From The Ground Up" Answer Key for the Exercises?

4

2 回答 2

2

做了:

(deref (sum 0 1e7))

您的函数仅在调用时返回延迟。在(deref sum)中,没有任何东西调用它(事实上,如果调用它,您永远不会提供参数值将是强制性的。相反,您尝试取消引用函数sum本身,这是非法的,因为函数不是延迟。

于 2020-03-10T19:27:34.773 回答
-1

如果您创建项目而不是在 REPL 中运行,则更容易查看详细信息。考虑将您的代码添加到此模板项目中:

(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>  

READMEAPI 文档中有更多文档。


尝试添加:

(spyxx sum)

产生:

sum => <#tst.demo.core$sum #object[tst.demo.core$sum 0x539edd3 "tst.demo.core$sum@539edd3"]>

这就是 Clojure 如何“打印”函数值的方式。


如果您犯了错误,您可以在错误消息中获得一个行号,这对您有很大帮助。deref 一个函数是不合法的,所以我们得到一个错误:

(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.cljunder中:dependencies

 [tupelo "0.9.198"]

有关示例,请参阅此模板项目。

于 2020-03-10T19:58:17.457 回答