Common Lisp的:编译VS评价(Common Lisp: compilation vs ev

2019-07-30 18:35发布

在Emacs的+泥和SBCL,一旦我定义一个函数(或更多)在一个文件中我有两个选择:

  • 评价 :例如用CMx的EVAL-defun定义
  • 编译 :例如用抄送的Mk编译文件

第二个产生.fasl文件了。

什么是两者之间的区别是什么?

这是怎么回事引擎盖下当我编译一个定义/文件?

什么是每个人的优点和缺点?

Answer 1:

首先,有一个功能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的缓冲区,但无法评估它的内容。



Answer 2:

也许一个隐喻会有点更容易理解。

试想一下,你有一些工作要做,有一个工人谁可以做到这一点。 不幸的是,这名工人不知道你的语言。 比方说,你讲英文,他知道只有法国。 所以,你需要翻译 。 OK,没问题,你翻译过。 在这里,你有2种选择:

  1. 住在附近的工人,告诉翻译做什么,看看工人是怎么做的。
  2. 请翻译写的任务分解到纸上,然后每次需要执行的工作时间给这个纸工人。

如果您需要完成一次任务,也没有大的差别走什么样的方式。 但是,如果你想同样的事情做了很多次,可能由不同的工人(法国所有的),您可能需要使用转换后的指令来获取文件。

所以现在编程。 你用一种语言(如Common Lisp的)写程序,但计算机本身并不了解它。 它“说话”只有它的内部语言 - 本机代码。 所以,你需要某种翻译的。 而这也正是编译器进入游戏。 编译器编译(编译)你的代码转换为本地代码,以便计算机可以执行它。

正如例如与法国工人,你有两个选择:

  1. 告诉计算机,当你需要它做什么而已 。 在这种情况下,编译器将翻译指令,计算机将执行他们,都将它立即忘记。 这就是所谓的评估
  2. 写文件的说明 ,然后用它来告诉计算机做什么每次你需要它的时候。 这通常被称为编译

请注意, 在混乱的术语 :实际上,编译器工作在这两种情况下,但是当你比较评价和编制,后者仅指第二种情况。 在其他情况下的术语可能会有所不同,所以尽量在阅读这样的事情评价,编制,解释和对一般的翻译来了解潜在的工艺。

还要注意,在SBCL REPL编译(写入文件)具有评价的副作用。 因此,在这种特殊情况下,唯一的区别是在写入文件。



Answer 3:

什么,当你计算表达式的是,它被送到SBCL在您表达的文本将被解析并编译成将被存储在内存中的Common Lisp环境的本机代码实际情况。

第二个方法将做相同的,但编译所有的代码到文件中。 你想编译代码的原因是为了让人们能够更快加载; 有没有必要来分析你的代码的语法和语义,并再次生成的代码,它可以简单地加载到内存中准备运行。

所以编译的好处是装载的不仅仅是速度,节省了计算机的工作。

在编辑一个已经编译虽然一个文件的情况下,你可以EVAL-defun定义重新在只读存储器的功能,这可能比编译整个文件更快。



Answer 4:

这不是直接回答你的问题,但是这是在评论太过漫长。

大部分的时间你不希望使用任何一个选项,如果我们谈论泥和Emacs -你会使用CC CC(MX煤泥编译defun定义 )。 这将弹出(如果尚未打开)编译缓冲,这表明编译错误和警告+它会突出你的代码中存在的问题。 这也适用尼斯之类的东西Flymake光标(一旦你浏览到有问题的区域,将在迷你精确显示了什么问题)。

编译文件发生在极少数情况下,当你确实有你想要的,因为它是后来使用产品。 或者说,最有可能,你希望别人用它的w / o你不必设置它。 例如,如果你有一个Web服务器,并且希望系统管理员可以(重新)根据需要启动它 - 需要管理员不知道您的软件功能,她只需要知道如何启动它。

Eval'ing一个defun定义就是这样 - 它发送文本SWANK,但不分析的结果。 当然,你的Lisp将打印的东西还给你,你这样做之后,但泥将会站在一旁。



文章来源: Common Lisp: compilation vs evaluation