2

以下の最後の2行に不一致があるのはなぜですか?評価例外はREPLから貼り付けられます。Clojure1.4を使用しています

(println "foo") ;; evals to nil

(nil)  ;; CompilerException java.lang.IllegalArgumentException: Can't call nil
((println "foo")) ;; NullPointerException
4

1 に答える 1

8

1つはコンパイル時の例外です。もう1つは、実行時の例外です。

コンパイラの場合、(nil)あなたが関数呼び出しを行おうとしていることを確認しnil、コンパイルエラーを出します。

コンパイラの場合((println "foo"))、内部フォームが何を返すかを推測しようとはしません(println "foo")。関数を返す可能性があることはわかっているので、コンパイル時にチェックは行われません。例外は、実行時に実際にaをprintln返し、nilそれを呼び出そうとしたときに発生します。

動的言語であるということは、通常、コンパイル時に変数の型エラーを検出しようとしないことを意味します。

観察:

(.setDynamic #'println)

(binding [println 
           (fn [x] 
             (when (pos? (rand-int 2)) 
               (fn [] (print "bar\n"))))] 
  ((println "foo")))

これは、ランダムに「バー」をnil出力して実行時例外なしで戻るか、何も出力せずに実行時をスローしますNullPointerException。ここで、この考案されprintlnたものには、コンパイラが検出する静的な戻り型がないことは明らかです。

ただし、コンパイラは、値のみを含むタイプエラーを検出できます。

于 2013-02-15T22:46:19.830 に答える