简体   繁体   中英

Clojure. Intellij. Delay. Concurrent. Clojure from the Ground Up

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?

Make it:

(deref (sum 0 1e7))

Your function only returns a delay when it's called . In (deref sum) , nothing calls it (and, indeed, you never provide argument values would would be mandatory to include were it called). Rather, you try to deref the function sum itself, which is illegal, because a function is not a delay.

The details are easier to see if you create a project rather than running in the REPL. Consider adding your code to 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
    ))

with result:

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

There are more docs in the README and the API docs .


Try adding:

(spyxx sum)

which produces:

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

This is how Clojure "prints" the value of a function.


If you make a mistake, you can get a line number in the error msg that helps greatly. It is not legal to deref a function, so we get an error:

(deref sum)   ; on line #17 of my file

produces:


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



Update

Don't forget to include this line in your project.clj under :dependencies :

 [tupelo "0.9.198"]

See this template project for an example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM