Paul Graham写道:"关于Lisp的不寻常之处 - 事实上,Lisp的定义质量 - 就是它可以自己编写." 但这对我来说似乎没有什么不寻常或明确的.
ISTM,编程语言由两个东西定义:它的编译器或解释器,它通过fiat定义语言的语法和语义,以及它的标准库,它在很大程度上定义了熟练用户将使用的习语和技术.用语言编写代码.
除了一些特定的例外(例如,.NET系列的非C#成员),大多数语言的标准库都是用这种语言编写的,原因有两个:因为它将共享同一组语法定义,函数调用约定,以及语言的一般"外观和感觉",并且因为可能为编程语言编写标准库的人是其用户,特别是其设计者.所以那里没什么特别的; 这是非常标准的.
再一次,语言编译器本身就没有什么独特或不寻常的东西.C编译器用C语言编写.Pascal编译器用Pascal编写.Mono的C#编译器是用C#编写的.哎呀,即使是一些脚本语言也有"自己编写"的实现.
那么Lisp在编写本身时是不寻常的意味着什么呢?
保罗的意思可能是Lisp 语法作为Lisp 值的表示是标准化和普遍的.也就是说,Lisp程序只是一种特殊的S表达式,编写操作Lisp代码的Lisp代码非常容易.在Lisp中编写Lisp解释器是一种特殊情况,并不像对代码和数据进行统一表示的一般能力那样令人兴奋.
我刚刚删除了很长的回复,这可能不合适.
但请考虑:
LISP没有"语法",如果你的意思是它具有C/Java/Pascal等语言的含义...... Common LISP阅读器有一个(初始但可自定义的)语法,但这是另一回事(LISP,Graham正在谈论的不是普通的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中你可以找到McCarthy如何描述eval[e, a]
在纸上首先发现的一个有趣的理论结果(一个"通用功能"实现整理器而不是一个通用的图灵机)只有数据结构和基本的本机功能已经为该组正在构建的Lisp语言布局.这个手写功能由SR Russell在机器代码中手动实现,并开始作为第一个Lisp解释器提供服务.
那么,你提供的链接会继续说,如果你继续阅读,他会详细回答你的问题.
关于Lisp的不寻常的事情 - 实际上,Lisp的定义质量 - 就是它可以自己编写.为了理解麦卡锡的意思,我们将回溯他的步骤,将他的数学符号转换为运行Common Lisp代码.
他并不是说Lisp可以用来编写Lisp编译器.他说这种语言是由自己的数据结构组成的.因此,虽然您无法使用C数据结构构建C函数,但您可以在Lisp中执行此操作.程序由您的计算机执行的列表组成,这些列表的效果可以是创建随后执行的其他列表,这些列表的效果可以是创建更多要执行的列表.C没有这个属性.例如,C代码不能操纵自己的AST.