保罗格雷厄姆写道"The unusual thing about Lisp-- in fact, the defining quality of Lisp-- is that it can be written in itself."但这对我来说似乎没有那么不寻常或明确。
ISTM,编程语言由两个东西定义:它的编译器或解释器,它通过fiat定义语言的语法和语义,以及它的标准库,它在很大程度上定义熟练用户的习语和技术在用语言编写代码时会使用。除了一些特定的例外(例如,.NET系列的非C#成员),大多数语言的标准库都是用这种语言编写的,原因有两个:因为它将共享同一组语法定义,函数调用约定以及语言的一般“外观和感觉”,并且因为可能为编程语言编写标准库的人是其用户,尤其是其设计者。所以那里没什么特别的;这是非常标准的。
再一次,语言编译器本身就没有什么独特或不寻常的东西。 C编译器用C语言编写.Pascal编译器用Pascal编写。 Mono的C#编译器是用C#编写的。哎呀,即使some scripting languages也有“自己编写”的实现。
那么Lisp在编写本身时是不寻常的意味着什么呢?
答案 0 :(得分:11)
Paul可能意味着Lisp 语法作为Lisp 值的表示是标准化和普遍的。也就是说,Lisp程序只是一种特殊的S表达式,编写操作Lisp代码的Lisp代码非常容易。在Lisp中编写Lisp解释器是一种特殊情况,并不像对代码和数据进行统一表示的一般能力那样令人兴奋。
答案 1 :(得分:7)
我刚刚删除了一个很长的回复,这可能不合适。
但请考虑:
LISP没有“语法”,如果你的意思是它的含义 像C / Java / Pascal这样的语言...有一个(初始但可自定义) Common LISP reader 的语法,但这是另一回事(LISP 格雷厄姆所说的不是 Common LISP ,而是一个(读者) 不是LISP语言,而是一个程序)。 像“(lambda(x)(* x 2))”这样的东西是不是 LISP代码, 但是文本,例如CL标准阅读器可以转换为LISP代码。
LISP不仅 可以 用LISP编写(如果你的意思是“bootstrap”能力) 但 它实际上就是以这种方式存在 。第一个实现 20世纪50年代后期的eval用LISP写在纸上,然后转换 手动进入机器语言(1):LISP起初只是一个纯粹的理论思想 意在实施。我不知道其他的计算机语言 那条路。例如,C ++被认为是C编译器的预处理器 并且是用C语言编写的,它不是后来转换为C的C ++程序 能够运行它。
LISP还有许多其他方面与不同,我认为掌握它的最佳方法是实际实现一个玩具LISP解释器(这是一个比一个小的工作如果您的“机器语言”是像Python这样的高级动态类型语言,我会特别想到。
(1)在http://www-formal.stanford.edu/jmc/history/lisp/node3.html中你可以找到麦卡锡如何描述eval[e, a]
在纸上被发现作为一个有趣的理论结果(一个比通用图灵机更整洁的“通用功能”实现)已经为该小组正在构建的Lisp语言布置了数据结构和基本本机函数。这个手写功能由S.R.手工实施。 Russell在机器代码中开始为它们提供第一个Lisp解释器。
答案 2 :(得分:6)
嗯,您提供的链接会继续说,如果您继续阅读,他会详细回答您的问题。
关于Lisp的不寻常的事情 - 在 事实上,Lisp的定义质量 - 是它可以写自己。 要了解麦卡锡的意思 这个,我们要追溯他的 步骤,用他的数学符号 翻译成运行Common Lisp 代码。
答案 3 :(得分:6)
他并不是说Lisp可以用来编写Lisp编译器。他说这种语言是由自己的数据结构组成的。因此,虽然您无法使用C数据结构构建C函数,但您可以在Lisp中执行此操作。程序由您的计算机执行的列表组成,这些列表的效果可以是创建随后执行的其他列表,这些列表的效果可以是创建更多要执行的列表。 C没有这个属性。例如,C代码不能操纵自己的AST。
答案 4 :(得分:4)
主要思想是Lisp语言有一个非常小的内核函数,主要的评估机制可以在一个页面上的代码中写下来。
这是Lisp的核心。
要理解语言的基本工作原理,只需要查看单页代码:它解释变量如何工作,函数调用如何工作,如何创建新函数等等。
考虑一下您可以从语言实现中删除多少以获得基础知识。什么是最小基元集,什么是最小执行引擎。要在Lisp中编写一个Lisp,你几乎什么都没有。
如果你看一下PASCAL实现(作为一个例子),它不是在PASCAL中实现的,而是在PASCAL +中提供了大量的代码,它们提供了表示语言实体,解析器,编译器,a的必要数据结构。运行时,... - 开箱即用PASCAL没有提供太多 - 必须构建这些(或使用库)。
Wirth(Pascal的创建者)编写了一本书,解释了一种非常小的类Pascal语言的实现 - 你仍然需要编写实质代码来实现该语言 - 解析器,代码生成器,运行时,加载器,...相比之下,在Lisp中,Lisp源代码具有自然表示,而评估Lisp代码的核心例程只是一个Lisp函数。这可能不是真正的或实际的Lisp实现,它仍然不同于PASCAL情况,其中源代码没有有用的表示(除了字符串或文件),执行引擎是更多的代码。
所以在Lisp中我们有:
源代码的简单表示(符号列表)
在单个小函数中简单实现求值程序
除此之外,在Lisp中实现Lisp评估器不需要任何东西。