在Lisp中,表单和文件之间的关系是什么?

时间:2014-03-12 18:49:39

标签: clojure lisp common-lisp

我在理解Lisp时遇到了一点小问题。根据Common Lisp标准,表单是要评估的原子或列表。这似乎很容易。

在现实世界中,我们目前将程序存储在文件中。 SBCL,Clojure等都具有可以评估的文件的概念。

这是怎么理解的?最终处理的文件最终就像要评估的单个表单一样,它是一个表单集合吗?出于某种原因,这让我很困惑。

3 个答案:

答案 0 :(得分:11)

根据CLHS

load sequentially executes each form it encounters in the file
named by filespec

表示文件是一系列表单。

答案 1 :(得分:6)

文件是存储表单的地方。打开文件(使用OPENWITH-OPEN-FILE)提供了一个流,READ函数可以将流中的表单读取到可以评估或编译的对象中。

在Common Lisp中,重要的是要意识到程序的语义是在读取产生的对象上定义的,而不是存储在文件中的 text

http://l1sp.org/cl/3.2.3可能有助于从编译角度理解它。

http://l1sp.org/cl/24.1.1谈论加载。

答案 2 :(得分:3)

  

我在理解Lisp方面有一点小问题。根据Common Lisp标准,表单是要评估的原子或列表。这似乎很容易。

请注意,这基本上是基于数据的。 EVAL将表单作为数据而非文本 - 作为其评估的参数。我们必须首先阅读文本,为EVAL创建一个表单。如果我们在文件中讨论表单,这基本上是一个简短的方法:从文件中读取表单。

  

在现实世界中,我们目前将程序存储在文件中。 SBCL,Clojure等都有一个文件的概念,也可以评估。

Common Lisp是现实世界的一部分。代码主要存储在文本文件中。不一定如此,但他的是这样的。这就是为什么Common Lisp具有OPENWITH-OPEN-FILEREADLOADCOMPILE-FILE等功能的原因。

不,Lisp中的文件无法评估'。 EVAL是评估者,它将Lisp表单作为参数,而不是文件。在Lisp中,可以加载文件。加载文件意味着:打开文件进行阅读,从文件中读取文件并按表单评估表单。

在Common Lisp文件中也可以编译以创建一个“fasl”文件。 (快速加载)文件。使用类似SBCL的东西,该文件将包含机器代码和数据。也可以加载此文件。加载将逐个执行每个表单的生成代码。

因此,Common Lisp可以加载两种类型的文件:带有Lisp代码的文本文件和带有编译代码的FASL文件。

您还可以打开一个文本文件进行阅读,使用Lisp阅读器阅读表格,并根据结果做任何您想做的事情。您还可以打开一个文本文件进行编写,并将Lisp表单作为文本写入该文件。

将源代码存储在文件中是Lisp中的常见做法。

有例外:

  • 大多数Common Lisp实现(并非全部)允许我们保存图像。该图像是正在运行的Lisp系统的当前内存状态的转储。因此,您可以将Lisp表单作为正在运行的程序中的数据,然后转储该映像,稍后重新启动映像。重新启动的图像仍将包含所有数据,这意味着存储为数据的代码仍然存在。

  • 像Interlisp-D这样不再广泛使用的Lisp系统,也有一个Common Lisp实现。 Interlisp-D在程序控制下将源代码存储在文本文件中。因此,文本文件更像数据库使用。

  • 一些Lisp系统也支持自动加载。调用一个函数,该函数未知,然后它查找其他地方(数据库,源代码)来定位源代码,加载它然后重试调用现在已知的函数。这样,用户无需加载文件,Lisp系统在后台执行。在早期的Lisp系统中使用自动加载来节省主存储器中的空间,而不是加载所有内容。即使是较新的Lisp实现也可能使用某种形式的自动加载来实现某些功能。