I’m trying to work through some of the exercises in SICP using Clojure, but am getting an error with my current method of executing Simpson’s rule (ex. 1-29). Does this have to do with lazy/eager evalution? Any ideas on how to fix this? Error and code are below:
java.lang.ClassCastException: user$simpson$h__1445 cannot be cast to java.lang.Number
at clojure.lang.Numbers.divide (Numbers.java:139)
Here is the code:
(defn simpson [f a b n]
(defn h [] (/ (- b a) n))
(defn simpson-term [k]
(defn y [] (f (+ a (* k h))))
(cond
(= k 0) y
(= k n) y
(even? k) (* 2 y)
:else (* 4 y)))
(* (/ h 3)
(sum simpson-term 0 inc n)))
You define
has a function of no arguments, and then try to use it as though it were a number. I’m also not sure what you’re getting at with(sum simpson-term 0 inc n); I’ll just assume thatsumis some magic you got from SICP and that the arguments you’re passing to it are right (I vaguely recall them defining a generic sum of some kind).The other thing is, it’s almost always a terrible idea to have a
defordefnnested within adefn. You probably want eitherlet(for something temporary or local) or another top-leveldefn.Bearing in mind that I haven’t written a
simpsonfunction for years, and haven’t inspected this one for algorithmic correctness at all, here’s a sketch that is closer to the “right shape” than yours: