『実践Common Lisp』20.6 EVAL-WHEN

「20.6 EVAL-WHEN」に書いてある内容がどう考えてもおかしくて、これは翻訳のミスじゃないかと思って調べてみたら、やはり正誤表に載っていた。とはいえ多分、そもそも原文も分かりにくいのだろうと思う。HyperSpecの説明の方がずっと分かりやすい。

:compile-toplevel と :load-toplevel が意味を持つのは、次の2つの条件が揃ったときだけだ。

  1. COMPILE-FILE でlispファイルをコンパイルするとき
  2. EVAL-WHEN がトップレベルフォームとして現れる場合

:comile-toplevel が指定されていれば、コンパイル時に評価される。:load-toplevel が指定されていれば、faslファイルを LOAD したときに評価される。

上の2条件が揃わない場合は、「:execute が指定されていれば評価される」「:execute が指定されていないと評価されない」という、ごく単純な動作になる。

HyperSpecに載っている例よりも、さらに直接的な例を考えてみた。

(eval-when (:execute)
  (defun foo ()
    "foo-execute"))
 
(eval-when (:compile-toplevel)
  (defun foo ()
    "foo-compile-toplevel"))
 
(eval-when (:load-toplevel)
  (defun foo ()
    "foo-load-toplevel"))
 
(defmacro foo-macro()
  (foo))
 
(defun main()
  (format t "~a~%" (foo))
  (format t "~a~%" (foo-macro)))

LOAD でlispファイルを読み込めば、

foo-execute
foo-execute

と表示される。COMPILE-FILEでコンパイルしたfaslファイルを読み込めば、

foo-load-toplevel
foo-compile-toplevel

と表示される。

Leave a Reply