compileとcompile-fileの生成するコードは異なることがある
compileは対象の関数のみを見て最適化を行うのに対して、
compile-fileはファイル内すべての関数/変数を見て最適化を行えるので、
両者の結果が異なるのは、当たり前といえば当たり前です。
しかし、ファイルに単一の関数しかなくても、
compileとcompile-fileの生成するコードが異なることがあります。
(defun f () (eq '(a b c) '(a b c)))
SBCLやAllegro CLにおいて、
関数compileでコンパイルした場合、(f)
の値はNILとなりました。
しかし、関数compile-fileでこの関数をコンパイルすると、(f)
の値はTとなりました。
#残念なことに、CLISP、Clozure CLではどちらの場合もNILとなりました。
さて、compile-fileした場合Tになる理由は前回のエントリを読んでください。
#前回の実験ではACLではcoalesceは行われませんでしたが、
#今回の実験ではcoalesceが行われているようです。
#恐らく、関数単位でcoalesceを行なっているのではないかと思います。
compileした場合にNILになる理由は、すばりcoalesceが行われていないからです。
では、何故coalesceが行われないかというと理由は簡単。
仕様でそう決まっているからです。
Literal objects appearing in code processed by the compile function are neither copied nor coalesced. The code resulting from the execution of compile references objects that are eql to the corresponding objects in the source code.
理由は分かるんですが、ややこしい話です。