Lisp.编译(Compilation)

来源:互联网 发布:长春华玺集软件 编辑:程序博客网 时间:2024/05/08 08:26

Common Lisp 函数可以单独被编译,也可以通过编译一个文件的形式被编译。如果你仅仅是在toplevel中键入了一个defun表达式,

[1]> (defun foo (x) (+ x 1))FOO

很多实现都会创建一个解释的函数。你可以通过将一个函数作为参数传递给compiled-function-p来判断它是不是已经被编译了:

[2]> (compiled-function-p #'foo)NIL

如果你把函数名foo传递给compile

[3]> (compile 'foo)FOO ;NIL ;NIL

foo的定义就会被编译,而后解释性的定义会被编译后的定义取代。编译和解释的函数有着同样的行为,唯一的不同点是它们对于函数compiled-function-p是不同的。


你也可以将列表作为参数传递给compile。这种用法暂且不讲。


有这样一种类型的函数,你是不能将它作为参数传递给compile的:一个类似stamp或者reset的函数,这些函数被键入到toplevel中,它们拥有一个独特的词汇上下文(比如一个let)。先将这些函数定义到一个文件里,然后编译并载入(load)这个文件,这个是没有问题的!这种限制是出于实现原因,强加在解释型代码上的,而和在独特的词汇上下文中定义函数是无关的。


编译Lisp代码的通常方式不是单独地编译函数,而是通过compile-file来编译整个文件。这个函数接受一个文件名作为参数,会产生一个编译后的源文件——通常是一个带有不同扩展名的文件。当编译后的文件被载入后,compile-function-p对于定义在这个文件中的每个函数都会返回真。

当一个函数出现在另一个函数的内部,外围的函数被编译了,那么内部的函数也会被编译。所以当make-adder函数被编译后,它也将返回编译后的函数:

> (compile 'make-adder)MAKE-ADDER> (compiled-function-p (make-adder 2))T