Functional programming 公共Lisp:编译与评估
在带有sbcl的Emacs+Slime上,一旦我在文件中定义了一个(或多个)函数,我有两个选择:Functional programming 公共Lisp:编译与评估,functional-programming,lisp,common-lisp,sbcl,Functional Programming,Lisp,Common Lisp,Sbcl,在带有sbcl的Emacs+Slime上,一旦我在文件中定义了一个(或多个)函数,我有两个选择: 评估:例如,使用C-M-x评估defun 编译:例如,使用C-C M-k编译文件 第二个也会生成一个.fasl文件 两者之间有什么区别? 当我编译定义/文件时,引擎盖下发生了什么? 每种方法的优点和缺点是什么?计算表达式时实际发生的情况是,它被发送到sbcl,在sbcl中,必须解析表达式的文本,然后将其编译为本机代码,这些代码将存储在公共Lisp环境中的内存中 第二个方法将执行相同的操作,但将所
- 评估:例如,使用C-M-x评估defun
- 编译:例如,使用C-C M-k编译文件
每种方法的优点和缺点是什么?计算表达式时实际发生的情况是,它被发送到sbcl,在sbcl中,必须解析表达式的文本,然后将其编译为本机代码,这些代码将存储在公共Lisp环境中的内存中 第二个方法将执行相同的操作,但将所有代码编译到文件中。您希望编译代码的原因是为了更快地加载代码;无需解析代码的语法和语义并再次生成代码,只需将其加载到内存中即可运行 因此,编译的好处就是加快加载速度,节省计算机工作
在编辑已编译的文件的情况下,您可以评估defun以仅在内存中重新创建函数,这可能比编译整个文件更快。这并不是直接回答您的问题,但这对于注释来说也太长了 大多数情况下,如果我们谈论SLIME和Emacs,您都不想使用这两种选项,您可能会使用C-C-C(或M-x SLIME编译defun)。这将弹出(如果尚未打开)编译缓冲区,显示编译错误和警告,并突出显示代码中的问题。这同样适用于Flymake cursor(一旦您导航到有问题的区域,它将在minibuffer中显示问题的具体内容) 编译文件发生在一种罕见的情况下,即当您实际拥有一个以后要使用的产品时。或者,最有可能的是,您希望其他人使用它,而不必设置它。例如,如果您有一个web服务器,并且您希望系统管理员能够根据需要(重新)启动它—管理员不需要知道您的软件如何工作,只需要知道如何启动它
评估一个defun只是-它将文本发送给SWANK,但不分析结果。当然,在你这样做之后,你的口齿不清会把一些东西打印回来,但是SLIME会站在一边。也许一个隐喻会更容易理解 假设你有一些工作要做,有一个工人可以做。不幸的是,这个工人不懂你的语言。假设你说英语,而他只懂法语。所以你需要翻译。好的,没问题,你也有翻译。这里有两个选项:
还要注意,在SBCL REPL编译(写入文件)中,有一个评估的副作用。因此,在这种特定情况下,唯一的区别是写入文件 首先,有一个函数
eval
[],允许在语言运行时计算(即执行)任意CL表单。CL实现可能有两种不同的操作模式:编译模式和解释模式。编译模式意味着,在计算之前,表单首先在内存中编译。此外,在CL中,评估不是在文件级别上进行的,而是在单个表单级别上进行的。因此,eval
可以编译和解释表单,具体取决于操作模式。(例如,默认情况下,SBCL始终编译,除非您通过将sb ext:*计算器模式*
设置为:exploration
,而CLISP始终进行解释来指示它不编译)
现在,还有一个方便的函数compile file
[],它允许在某个文件中编译所有表单,并将结果保存在另一个文件中。此不会触发对这些表单的评估
CL还定义了程序生命周期的3个不同时间:编译时间、加载时间和执行时间。而且,当使用一个最(如果不是最)神秘的CL特殊运算符eval when
[]时,可以控制发生的情况