发现Common Lisp的“核心”实体和宏

5
阅读彼得·塞贝尔所著的《实用Common Lisp》时,我了解到,除了列表处理和求值等语言的核心部分外,还有像loopdo等宏是使用这些核心构造编写的。
我的问题有两个方面。第一个是Lisp的“核心”到底是什么?哪些是最基本的,如果需要的话可以从中重新创建其他东西?第二个部分是,在哪里可以查看作为Common Lisp的一部分但实际上是用Lisp编写的宏的代码?另外一个问题是,当一个人编写Lisp实现时,他会用什么语言呢?

你可以从书本中学习到这些,比如流行的《计算机程序的构造和解释》(SICP),我也很喜欢。一些 Lisp 书籍:http://www.communitypicks.com/r/lisp - Ehvince
2个回答

5
“Lisp 的核心究竟是什么?如果需要,最基本的东西可以从哪里重新创建出来?”
CLtL 把一组最小的句法运算符称作 "special forms"。这个术语在 ANSI CL 中改名为 "special operators"。它们共有 24 个,在 CLtL section "Special Forms" 中有很好的解释。在 ANSI CL 中它们有 25 个。
“在哪里可以看到作为 Common Lisp 一部分但实际上是用 Lisp 写的宏代码?”
许多通用Lisp实现都是自由软件(list),您可以查看它们的源代码。例如,这里是SBCL,这里是GNU clisp等。

当一个人编写Lisp实现时,他使用什么语言?

通常,Lisp实现由以下部分组成:
  • 一个低级部分,用系统编程语言编写。该部分包括函数调用机制的实现和24个特殊形式的运行时部分。和
  • 一个更高级别的部分,使用Lisp本身,因为用系统编程语言编写所有内容会太繁琐。这通常包括宏和编译器。
系统编程语言的选择取决于具体情况。例如,对于基于Java虚拟机的实现,自然的选择是Java。对于包含自己内存管理的实现,通常使用C语言,或者一些类似于C语言语义的Lisp扩展(即具有固定宽度的整数类型、显式指针等)。

3

首先,什么是Lisp的“核心”?如果需要,其他东西可以从哪些最基本的东西中重新创建出来?

大多数Lisp都有一个原始结构的核心,通常用C(或者可能是汇编语言)编写。选择这些语言的通常原因是性能。从其他事物可以重新创建的最基本要素取决于你想要达到的最简要素。也就是说,你不需要太多的图灵完备性。您只需要lambda就可以让您的语言拥有最基本的要素,从而可以创建其他东西。尽管通常人们还包括defmacroconddefun等。这些东西并不是严格必要的,但可能是您所说的“最基本”的内容,也是人们通常作为原始语言结构包含的内容。

第二部分是在哪里查看作为Common Lisp一部分但实际上是用Lisp编写的宏的代码?
通常,您需要查看语言的Lisp源代码。但有时,您的宏不是真正的宏,而是原始语言结构。对于这种情况,您可能还需要查看C源代码,以了解这些“真正”的原语是如何实现的。
当然,如果您的Lisp实现不是开源的,则需要反汇编其二进制文件并逐个查看它们,以了解原语的实现方式。
作为一个旁问,当一个人编写Lisp实现时,他使用什么语言?
如我上面所说,C是一个常见的选择,汇编曾经更常见。虽然,有些Lisp是用高级语言(如Ruby、Python、Haskell甚至Lisp本身)编写的。这里的权衡是性能与可读性和可理解性。
如果您想查看一个相对规范的 Lisp 示例,而且它完全是开源的,请查看 Emacs 的源代码。 当然,这不是 Common Lisp,尽管在 Emacs 核心中有一个 cl,实现了相当大的 Common Lisp 子集。

我猜大多数Lisp实现本身就是用Lisp编写的。通常,Lisp编译器将使用Lisp实现并创建C或机器代码。甚至Lisp本身也是如此。 - Rainer Joswig
我建议不要学习elisp。相反,可以看看其中一个开源的CL(Common Lisp),或者Scheme衍生语言,实际上,去查看任何不像elisp那么古老和特殊的编程语言实现的源代码都是可行的。 - user5920214
@tfb 我认为 Emacs Lisp 的缺点有些被夸大了,但是考虑其他 Lisp 方言也绝不是一个坏主意。我建议使用 Racket、Chicken 或 Gambit 来处理 Scheme 衍生语言。对于 Common Lisp,我还推荐使用 CCL 或 SBCL。 - GDP2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接