我在理解Lisp时遇到了一点小问题。根据Common Lisp标准,表单是要评估的原子或列表。这似乎很容易。
在现实世界中,我们目前将程序存储在文件中。 SBCL,Clojure等都具有可以评估的文件的概念。
这是怎么理解的?最终处理的文件最终就像要评估的单个表单一样,它是一个表单集合吗?出于某种原因,这让我很困惑。
答案 0 :(得分:11)
根据CLHS:
load sequentially executes each form it encounters in the file
named by filespec
表示文件是一系列表单。
答案 1 :(得分:6)
文件是存储表单的地方。打开文件(使用OPEN
或WITH-OPEN-FILE
)提供了一个流,READ
函数可以将流中的表单读取到可以评估或编译的对象中。
在Common Lisp中,重要的是要意识到程序的语义是在读取产生的对象上定义的,而不是存储在文件中的 text
http://l1sp.org/cl/3.2.3可能有助于从编译角度理解它。
答案 2 :(得分:3)
我在理解Lisp方面有一点小问题。根据Common Lisp标准,表单是要评估的原子或列表。这似乎很容易。
请注意,这基本上是基于数据的。 EVAL
将表单作为数据而非文本 - 作为其评估的参数。我们必须首先阅读文本,为EVAL
创建一个表单。如果我们在文件中讨论表单,这基本上是一个简短的方法:从文件中读取表单。
在现实世界中,我们目前将程序存储在文件中。 SBCL,Clojure等都有一个文件的概念,也可以评估。
Common Lisp是现实世界的一部分。代码主要存储在文本文件中。不一定如此,但他的是这样的。这就是为什么Common Lisp具有OPEN
,WITH-OPEN-FILE
,READ
,LOAD
,COMPILE-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实现也可能使用某种形式的自动加载来实现某些功能。