5

据我所知,Lisp 语法代表 AST,但采用高级格式,以便人类轻松阅读和修改,同时也使机器易于处理源代码。

出于这个原因,在 Lisp 中,据说代码就是数据,数据就是代码,因为代码(s-epxression)本质上就是 AST。我们可以将更多的 AST(这是我们的数据,只是 lisp 代码)插入到其他 AST(lisp 代码)中,或者独立地扩展其功能并在运行时(运行时)对其进行操作,而无需重新编译整个操作系统以集成新的代码。在其他语言中,我们必须重新编译以将人类语言源代码转换为有效的 AST,然后才能将其编译为代码。

这是否是 Lisp 语法首先被设计成它的原因(代表一个 AST,但它是人类可读的,以满足人类和机器的需求)?为了实现人机之间更强大(即时 - 运行时)以及更简单(无需重新编译,更快)的通信?

我听说 Lisp 机器只有一个地址空间来保存所有数据。在Linux这样的操作系统中,程序员只有虚拟地址空间,假装它是真实的物理地址空间,可以为所欲为。Linux 中的数据和代码是分开的区域,因为实际上,数据就是数据,数据就是代码。在用 C(或类似 C 的语言)编写的普通操作系统中,如果我们只为整个系统操作一个地址空间并且将数据与代码混合会非常混乱,这将是非常混乱的。

在 Lisp Machine 中,由于代码是数据,数据是代码,这是否是只有一个地址空间(没有虚拟层)的原因?既然我们有 GC 并且没有指针,那么在不破坏物理内存的情况下操作物理内存是否安全(因为只有 1 个单独的空间要简单得多)?

编辑:我问这个是因为据说Lisp的优点之一是单一地址空间:

安全的语言意味着一个可靠的环境,无需将任务分离到它们自己单独的内存空间中。

Unix 的“明确分离的进程”模型特征在处理可能不可靠到不安全的软件时具有强大的优点,例如用 C 或 C++ 编写的代码,其中无效的指针访问可以“取消系统。” 从这个意义上说,MS-DOS 及其继承者非常不可靠,几乎任何程序错误都可能导致整个系统崩溃;《蓝屏死机》之类的。

如果整个系统都是用 Lisp 构建和编码的,那么这个系统就和 Lisp 环境一样可靠。通常这是非常安全的,因为一旦您到达符合标准的层,它们就非常可靠,并且不提供允许系统自毁的直接指针访问。

健全个人计算第三定律

易失性存储设备(即 RAM)应专门用作非易失性存储设备的读/写缓存。从除操作系统之外的所有软件的角度来看,机器必须呈现一个可以被认为是非易失性的单一地址空间。没有任何计算机系统遵守这一定律,它需要比电灯更长的时间才能从电源中断中完全恢复其状态。

如前所述,单个地址空间将所有正在运行的进程保存在同一内存空间中。我只是好奇为什么人们坚持认为单一地址空间更好。我将它与类似 AST 的 Lisp 语法联系起来,试图解释它如何适合单空间模型。

4

1 回答 1

7

您的问题并不能非常准确地反映现实,尤其是在 Linux 和其他操作系统中关于代码/数据分离的部分。实际上,这种分离不是在操作系统级别执行的,而是由编译器/程序加载器执行的。在操作系统级别,只有内存页面可以设置不同的保护位(如可执行、只读等),在此级别之上,存在不同的可执行格式(如 Linux 中的 ELF),它们指定了对程序内存不同部分的限制。

回到 Lisp,据我所知,从历史上看,Lisp 的创建者使用 S 表达式格式,因为他们想专注于语言的语义,将语法搁置一段时间。有一个计划最终为 Lisp 创建一些语法(参见 M 表达式),并且有一些基于 Lisp 的语言有更多的语法,比如 Dylan。但是,总的来说,Lisp 社区已经达成共识,即 S 表达式的好处超过了它们的缺点,所以他们坚持了下来。

将代码视为数据,这并不严格绑定到 S 表达式,因为其他代码也可以视为数据。这整个方法称为元编程,并且在不同级别和多种语言的不同机制上得到支持。每种支持eval(Perl、JavaScript、Python)的语言都允许将代码视为数据,只是表示几乎总是一个字符串,而在 Lisp 中它是一棵树,这更方便并且促进了高级的东西,比如宏。

于 2012-07-04T07:08:15.473 回答