在Emacs的+泥和SBCL,一旦我定义一个函数(或更多)在一个文件中我有两个选择:
- 评价 :例如用CMx的EVAL-defun定义
- 编译 :例如用抄送的Mk编译文件
第二个产生.fasl文件了。
什么是两者之间的区别是什么?
这是怎么回事引擎盖下当我编译一个定义/文件?
什么是每个人的优点和缺点?
在Emacs的+泥和SBCL,一旦我定义一个函数(或更多)在一个文件中我有两个选择:
第二个产生.fasl文件了。
什么是两者之间的区别是什么?
这是怎么回事引擎盖下当我编译一个定义/文件?
什么是每个人的优点和缺点?
首先,有一个功能eval
[ 1 ],其允许以评价语言运行时(即,执行)任意CL的形式。 CL的实现可能有操作的2种不同的模式:编译模式和解释模式。 编辑模式意味着,该评估前形式内存先编译。 此外,在CL评价发生不是在文件级,但对个人形式的水平。 所以eval
可以编译和解释的形式,这取决于操作模式。 (默认情况下为例如SBCL总是编译,除非你不指示通过设置sb-ext:*evaluator-mode*
到:interpret
,而CLISP总是解释)。
现在,还有一个方便的功能compile-file
[ 2 ],允许编译一些文件中的所有形式,并保存在另一个文件中的结果。 这不会触发这些形式的评估 。
也CL定义了3个不同的程序生命周期的次数:编译时,负载的时间和执行时间。 还有的控制什么用的最多一个时发生的可能性(如果不是最)神秘CL特种作业eval-when
[ 3 ]。
综上所述,CMx的EVAL-defun函数将调用eval
下光标在表格上。 它不会需要编译它,但是这是可能的,取决于实施。 抄送的Mk编译文件将compile-file
的缓冲区,但无法评估它的内容。
也许一个隐喻会有点更容易理解。
试想一下,你有一些工作要做,有一个工人谁可以做到这一点。 不幸的是,这名工人不知道你的语言。 比方说,你讲英文,他知道只有法国。 所以,你需要翻译 。 OK,没问题,你翻译过。 在这里,你有2种选择:
如果您需要完成一次任务,也没有大的差别走什么样的方式。 但是,如果你想同样的事情做了很多次,可能由不同的工人(法国所有的),您可能需要使用转换后的指令来获取文件。
所以现在编程。 你用一种语言(如Common Lisp的)写程序,但计算机本身并不了解它。 它“说话”只有它的内部语言 - 本机代码。 所以,你需要某种翻译的。 而这也正是编译器进入游戏。 编译器编译(编译)你的代码转换为本地代码,以便计算机可以执行它。
正如例如与法国工人,你有两个选择:
请注意, 在混乱的术语 :实际上,编译器工作在这两种情况下,但是当你比较评价和编制,后者仅指第二种情况。 在其他情况下的术语可能会有所不同,所以尽量在阅读这样的事情评价,编制,解释和对一般的翻译来了解潜在的工艺。
还要注意,在SBCL REPL编译(写入文件)具有评价的副作用。 因此,在这种特殊情况下,唯一的区别是在写入文件。
什么,当你计算表达式的是,它被送到SBCL在您表达的文本将被解析并编译成将被存储在内存中的Common Lisp环境的本机代码实际情况。
第二个方法将做相同的,但编译所有的代码到文件中。 你想编译代码的原因是为了让人们能够更快加载; 有没有必要来分析你的代码的语法和语义,并再次生成的代码,它可以简单地加载到内存中准备运行。
所以编译的好处是装载的不仅仅是速度,节省了计算机的工作。
在编辑一个已经编译虽然一个文件的情况下,你可以EVAL-defun定义重新在只读存储器的功能,这可能比编译整个文件更快。
这不是直接回答你的问题,但是这是在评论太过漫长。
大部分的时间你不希望使用任何一个选项,如果我们谈论泥和Emacs -你会使用CC CC(或MX煤泥编译defun定义 )。 这将弹出(如果尚未打开)编译缓冲,这表明编译错误和警告+它会突出你的代码中存在的问题。 这也适用尼斯之类的东西Flymake光标(一旦你浏览到有问题的区域,将在迷你精确显示了什么问题)。
编译文件发生在极少数情况下,当你确实有你想要的,因为它是后来使用产品。 或者说,最有可能,你希望别人用它的w / o你不必设置它。 例如,如果你有一个Web服务器,并且希望系统管理员可以(重新)根据需要启动它 - 需要管理员不知道您的软件功能,她只需要知道如何启动它。
Eval'ing一个defun定义就是这样 - 它发送文本SWANK,但不分析的结果。 当然,你的Lisp将打印的东西还给你,你这样做之后,但泥将会站在一旁。