LoginSignup
1
0

More than 1 year has passed since last update.

eval-whenの挙動を確認してみた

Posted at

eval-whenの挙動を確認してみた

common lispで、eval-whenの使いどころがイマイチぴんときません。
挙動を確認することで、理解が深まるといいなと思います。
処理系はSBCLです。

REPLで実行してみる

CL-USER> (eval-when (:execute)
  (print 'execute))

EXECUTE
EXECUTE
CL-USER> (eval-when (:load-toplevel)
  (print 'load-toplevel))

NIL
CL-USER> (eval-when (:compile-toplevel)
  (print 'compile-toplevel))

NIL

:executeのみ実行されました。ロードも、コンパイルもしていないので、これはこれで納得です。

loadしてみる

eval-when.lispに保存したうえで、ロードしてみます。

(eval-when (:execute)
  (print 'execute))

(eval-when (:load-toplevel)
  (print 'load-toplevel))

(eval-when (:compile-toplevel)
  (print 'compile-toplevel))

CL-USER> (load "eval-when.lisp")

EXECUTE
T

:executeのみevalされました。:load-toplevelがevalされないのは意外です。

compile-fileはどうか?

同じソースファイルをコンパイルしてみます。

CL-USER> (compile-file "eval-when.lisp")
; compiling file "eval-when.lisp" (written 14 APR 2022 03:24:19 AM):
; compiling (PRINT (QUOTE LOAD-TOPLEVEL))
COMPILE-TOPLEVEL

; wrote eval-when.fasl
; compilation finished in 0:00:00.001
#P"eval-when.fasl"
NIL
NIL

evalされたのは:compile-toplevel。これもまあそうかなという感じ。
ここで:load-toplevelのみがコンパイルされていますね。(3行目)

コンパイルされたファイルをloadしてみる

CL-USER> (load "eval-when.fasl")

LOAD-TOPLEVEL
T

:load-toplevelがevalされました。これはつまり、:load-toplevelのloadがコンパイルされたファイルのロードであるということですね。

小出先生のおっしゃるとおりでした。

以下、小出誠二先生のブログより引用させていただきます。
PAIP, auxfns.lisp のウォークスルー : セマンティックウェブ・ダイアリー

ここで eval-when はその囲まれたフォームをいつ評価したらよいのかを指定するための特殊形式です.もっぱら用いられるのはこのように,compile,load,eval がすべて並んだものですが,その意味はコンパイル時に評価するか(compile),コンパイルされた fasl ファイルをロードするときに評価するか(load),ソースコードを実行時に評価するか(eval) というものです.

そして compile,load,eval はそれぞれ :compile-toplevel,:load-toplevel,:execute を使うべきとされています.ではそのように直してしまいましょう.コロンをつけることをお忘れなく.
(eval-when (:execute :compile-toplevel :load-toplevel)

以前にも拝見していた記事ですが、手を動かさないと知識として定着しないということですね(反省)

1
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0