6

在 Clojure 中实现一些初始 SICP 代码时,我遇到了意外的 NullPointerException。特别是,我想实现第 1.1.7 节中的迭代平方根过程。

这是代码:

(defn square [x] (* x x))

(defn abs [x]
  (cond 
    (< x 0) (- x)
    :else x))

(defn average [x y]
  (/ (+ x y) 2))

(defn sqrt
  ([x] (sqrt 1.0 x))
  ([guess x]
    (letfn [(good-enough? [guess]
              (< (abs (- (square guess) x)) 0.001))
            (improve [guess]
              (average guess (/ x guess)))]
      (if (good-enough? guess)
        guess
        (recur (improve guess) x)))))

这适用于足够小的值,例如(sqrt 16). NullPointerException clojure.lang.Numbers.lt (Numbers.java:3693)对于任何大于 about 的输入,我都会收到错误消息(square 2718)

有任何想法吗?

更新整个回溯(前一个是我在 repl 中得到的全部内容):

在 sicp_in_clojure.chapter_one$sqrt$good_enough_QMARK___14.invoke(chapter_one.clj:40) 在 sicp_in_clojure.chapter_one$sqrt 的 clojure.lang.Numbers.lt(Numbers.java:3693) 的线程“main”java.lang.NullPointerException 中的异常。在 sicp_in_clojure.chapter_one$eval19.invoke(chapter_one.clj:48) 的 sicp_in_clojure.chapter_one$sqrt.invoke(chapter_one.clj:37) 调用(chapter_one.clj:43)。 :6465) at clojure.lang.Compiler.load(Compiler.java:6902) at clojure.lang.Compiler.loadFile(Compiler.java:6863) at clojure.main$load_script.invoke(main.clj:282) at clojure .main$script_opt.invoke(main.clj:342) at clojure.main$main.doInvoke(main.clj:426) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.lang.Var。在 clojure.lang.AFn 调用(Var.java:401)。applyToHelper(AFn.java:161) 在 clojure.lang.Var.applyTo(Var.java:518) 在 clojure.main.main(main.java:37)

4

2 回答 2

1

不确定这是否仍然相关,但我认为值得尝试使用LightTable Playground应用程序,让您了解事物的解释方式:

上述代码的灯台演示截图

您是否尝试过最近的构建,比如新的Clojure 1.4.0版本?

于 2012-06-26T23:29:27.427 回答
0

嘿,对我来说效果很好。我正在使用 clojure 1.3.0。以下是终端输出。代码工作正常。

[user@myhost ~]$ clj 
Clojure 1.3.0
user=> (defn square [x] (* x x))
#'user/square
(defn abs [x]
  (cond 
    (< x 0) (- x)
    :else x))
#'user/abs
(defn average [x y]
  (/ (+ x y) 2))
#'user/average
(defn sqrt
  ([x] (sqrt 1.0 x))
  ([guess x]
    (letfn [(good-enough? [guess]
              (< (abs (- (square guess) x)) 0.001))
            (improve [guess]
              (average guess (/ x guess)))]
      (if (good-enough? guess)
        guess
        (recur (improve guess) x)))))
#'user/sqrt
user=> (sqrt 16)
4.000000636692939
user=> (sqrt 2718)
52.134441897781194
user=> (sqrt 3000)
54.77225658092904
于 2011-10-13T17:43:44.720 回答