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)おおよそ より大きい入力に対してエラーが発生します(square 2718)

何か案は?

トレースバック全体で更新します (以前のものは、repl で取得したすべてです):

スレッド「メイン」での例外 java.lang.NullPointerException at clojure.lang.Numbers.lt(Numbers.java:3693) at sicp_in_clojure.chapter_one$sqrt$good_enough_QMARK___14.invoke(chapter_one.clj:40) at sicp_in_clojure.chapter_one$sqrt. sicp_in_clojure.chapter_one$sqrt.invoke(chapter_one.clj:37) で sicp_in_clojure.chapter_one$eval19.invoke(chapter_one.clj:48) で (chapter_one.clj:48) を呼び出します。 :6465) clojure.lang.Compiler.load(Compiler.java:6902) で clojure.lang.Compiler.loadFile(Compiler.java:6863) で clojure.main$load_script.invoke(main.clj:282) で clojure .main$script_opt.invoke(main.clj:342) で clojure.main$main.doInvoke(main.clj:426) で clojure.lang.RestFn.invoke(RestFn.java:408) で clojure.lang.Var. clojure.lang.AFnでinvoke(Var.java:401)。applyToHelper(AFn.java:161) at clojure.lang.Var.applyTo(Var.java:518) at 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 に答える