John McCarthy:LISP-关于它的过去和未来的记录-1980

John McCarthy:LISP-关于它的过去和未来的记录-1980

本文翻译自John McCarthy 于1980年写的《LISP-NOTES ON ITS PAST AND FUTURE-1980》,原文地址:http://www-formal.stanford.edu/jmc/lisp20th/lisp20th.html

摘要

Lisp 已经存活了21年,因为它是编程语言领域的一个近似局部最优。然而,它已经积累了很多应该被挂掉的藤壶,并且一些长期存在的改进的机遇已经被忽视。它将受益于一些合作维护,特别是在创建和维护程序库。对于纯LISP和一些扩展,现在可以用计算机检查程序正确性的证明,但是,在我们能够充分利用LISP的数学基础之前,还需要更多的理论和语言本身的一些平滑处理。

1999年记录:这篇文章被包含在1980年在斯坦福举行的Lisp会议中。因为它几乎完全符合我现在的观点,所以我应该要求在1998年Lisp用户会议记录中重印它,在那次会议上,我用同样的标题做了一次演讲。

引言

在Lisp大约21周年的时候,毫无疑问,成年是有意义的,但是一门编程语言的平均寿命是70年,这一点似乎值得怀疑。事实上,Lisp似乎是继Fortran之后现存的第二古老的存活编程语言,所以,也许我们应该计划举行一次这样的报纸采访,在采访中,爷爷被问到他把活到了100岁归为什么。不管怎样,LISP的早期历史已经在[McC81]中有所涉及,它是1977年ACM编程语言历史会议记录的重印本。

因此,这些记录首先回顾了LISP的一些显著特性及其与长期生存的关系,并指出LISP从未得到过计算机公司的支持。LISP有一个部分合理的名声,那就是它比大多数计算机语言更基于理论,大概源于它的函数形式,它对lambda符号的使用,以及解释器基于一个通用函数。

从一开始,我就想开发一种技术,使LISP程序的计算机可校验证明成为可能,现在这对于大部分LISP来说是可能的。还有其他现有和拟议的工具在理论上处于更神秘的状态。最后,我将对LISP中可能出现的改进和用更好的语言取代LISP的前景做一些评论。

LISP的生存

作为一种编程语言,LISP的特点是:

  1. 使用符号表达式而不是数字进行计算。
  2. 用列表结构表示计算机内存中的符号表达式和其他信息。
  3. 在纸上、键盘上和其他外部媒体上对信息的表示,主要是通过多级列表,有时是s -expression。重要的是,任何类型的数据都可以用单一的通用类型表示。
  4. 一小套表示为函数的选择器和构造器操作,例如, car, cdr 和 cons。
  5. 函数的组合作为形成更复杂函数的工具。
  6. 使用条件表达式得到函数定义的分支。
  7. 条件表达式的递归使用作为构建可计算函数的充分工具。
  8. 使用lambda来命名函数。
  9. 原子属性列表上信息的存储。
  10. LISP程序作为LISP数据的表示,可以被对象程序操作。这就防止了系统程序员和应用程序程序员之间的分离。每个人都可以“改进”自己的LISP,而这些“改进”中有许多已经发展成为对语言的改进。
  11. 布尔连接词的条件表达式解释。
  12. LISP函数eval既可以作为该语言的正式定义,也可以作为解释器。
  13. 垃圾收集作为擦除的手段。
  14. 对声明的最低要求,以便LISP语句可以在在线环境中执行,而无需准备。
  15. LISP语句作为在线环境中的命令语言。

当然,上面并没有提到LISP在“程序特性”中与大多数编程语言相同的特性。

所有这些特性都是可行的,在编程语言的空间中,组合必须是某种近似局部最优的,因为LISP在几次试图取代它的尝试中幸存了下来,有些是相当确定的。也许有必要回顾一下其中的一些,并猜测一下为什么他们没能成功。

  1. SLIP在Fortran中包含列表处理。它使用双向列表,不允许递归函数或条件表达式。双向列表只在少数几个应用程序中提供了优势,但在其他方面占用了空间和时间。它不鼓励在线使用,因为Fortran不鼓励。

  2. Formac是另一种基于Fortran的语言,IBM的一部分曾经推动过它。 它致力于处理用Fortran风格编写的一类代数公式,还面向批处理。

  3. Algol公式是一种语言双关语,即基本运算可以看作是对数字或公式的运算。其思想是,如果变量x没有值,那么对涉及x的表达式的操作必须被视为对公式的操作。可以编写一些程序,但是这个双关语并不能作为编写实质性程序的基础。

  4. LISP最有趣的竞争对手之一是POP-2。它拥有LISP所拥有的一切,除了它的语句是用类似algol的形式编写的,并且没有任何列表结构的内部形式。因此,POP-2程序只能以字符串的形式生成其他的POP-2程序。这使得系统程序员和应用程序程序员之间的区别比LISP更加明显。例如,在LISP中,任何人都可以创建自己喜欢的宏识别器和扩展器。

  5. Microplanner是一种比LISP更高级的通用语言。更高的层次涉及数据(模式匹配)和控制(目标寻找和失败机制)。不幸的是,这两个都被证明不够通用,程序员被迫进行非常复杂的构造,使用像CONNIVER这样的具有更复杂的控制特性的新语言,最终许多人回到了LISP。

    一个普遍的问题似乎是没有人充分理解模式导向计算,它总是在简单的例子上运行得很好,但当它一般化时,会导致过于复杂的系统。我们可以在LISP的某些宏扩展系统中看到这一点,比如LISP机器。

  6. 我应该提一下Prolog,但是我不太了解它,不能发表评论。

    Prolog的思想类似于Microplanner思想的一个子集。然而,Prolog是经过系统设计的,并且存活了下来,而Microplanner却没有。Prolog的关键思想是,逻辑的某个子集(Horn子句)可以作为执行回溯搜索的程序执行。在我看来,这个发现和Lisp背后的思想一样具有永恒的重要性。

改进

像大多数语言一样,LISP有待改进。随着时间的推移,LISP的各种版本积累了许多藤壶,这些藤壶必须被刮掉,才能实现最终的标准化语言——这是一个有价值但长期的目标。同时,这里有一些改进的方向。有些是纯操作性的,有些则有更多的概念性内容。

  1. 将更多的标准函数纳入语言中,并使现有版本的标准函数合理化。

    编程语言的设计者经常建议忽略语言工具的定义,因为用户可以自己定义。结果常常是用户不能使用彼此的程序,因为每个设备和用户以不同的方式执行各种常见的任务。只要程序员使用本地库而不重写函数,那么如果他们使用不同的本地库,他们就会使用不同的语言。如果有更多的标准函数,LISP用户之间的兼容性将会大大增强。

  2. 语法导向的输入和输出

    表示符号信息的表示法可以从三个方面进行优化:一种是可以试着让它更容易编写;一种是可以试着让它读起来轻松愉快;一种是可以很容易地操作计算机程序。不幸的是,这些欲望几乎总是极不相容的。LISP的成功主要归功于对第三种优化。事实证明,用LISP列表和s表达式中某项的 car 来标识其类型,最适合作为编程的数据。当输入和输出的数量很少时,用户倾向于接受输入的不方便,并将输出视为列表或s -表达式。否则,他们就会编写出不同精细化程度的 read 和 print 程序。输入和输出程序通常是工作的主要部分,也是bug的主要来源。此外,输入程序常常必须检测并报告输入语法中的错误。

    LISP将通过标准的面向语法的输入和输出功能得到很大的改进。几年前,Lynn Quam实现了一个系统,它对输入和输出使用了相同的语法描述,但这是相当有限的。可能需要对输入和输出使用不同的语法,而输入语法应该指定报告错误的方式。这个想法是为程序员提供标准的工具来描述外部媒体中的数据和s-表达式之间的对应关系,例如,他可以这样表示

    (PLUS x … z) -> x + … + z
    (DIFFERENCE x y) -> x - y

    尽管我对这个特殊的表示没有什么要求。

  3. 语法导向的计算

    目前还不清楚这将是LISP的一个新特性还是一种新语言。然而,似乎LISP现在所具有的函数式计算形式和面向语法的特性在一种语言中都是需要的。

  4. 如果我们能找到一种方法来资助和管理一个中央机构,它可以保存库、对机器独立的改进达成一致、维护一个标准子集,并协调计算机制造商在他们的机器上开发和维护适当的 LISP, LISP 可能会受益。它应该不会太强大。(1999:只发生了部分的标准化。)

LISP程序的验证正确性

这可以通过利用LISP的理论基础来实现。

一旦纯LISP有了现在的形式,就很明显LISP函数的性质应该通过代数操作和适当的数学归纳法来证明。这产生了创建计算数学理论的目标,这将导致计算机检查证明[McC62]程序符合他们的规格。因为LISP函数是函数,所以标准的逻辑技术不能立即应用,尽管递归归纳[McC63]很快成为一种非正式的方法。[Kle52]的方法可能已经被用来证明程序的属性,只要理解它们的人受到适当的激励并理解了它们之间的联系。

第一个适当的形式化方法是基于Cartwright的论文[Car77],该论文允许将
在这里插入图片描述
这样的LISP函数定义替换为一阶语句
在这里插入图片描述
而无需首先证明程序终止于任何列表u和v。终止证明的形式与其他归纳证明完全相同。参见[CM79]。

Elephant formalism(麦卡锡,1981年出版)提供了适用于顺序LISP程序的第二种方法。Boyer和Moore[BM79]以一种不同的形式提供了证明发现和证明检查,这种形式需要证明一个函数作为接受其定义过程的一部分是完全的。

我应该说,我不认为LCF方法是足够的,因为“可计算函数的逻辑”太弱,不能完全指定程序。

这些方法(非正式地使用)已经成功地作为LISP课程的一部分在斯坦福教授,并将在教科书中描述(麦卡锡和塔尔科特1980)。利用Richard Weyhrauch的FOL交互式一阶逻辑校核器进行机器校核也是非常可行的,但实际使用时需要一个LISP系统,将校核器与解释器和编译器集成在一起。

计算机验证的最终目标是一个系统,它将被那些没有数学倾向的人所使用,因为它可以更快地生成没有bug的程序。这需要进一步的进步,使更短的证明成为可能,并在编写程序的规格方面取得进展。

可能规范的某些部分,例如程序终止的部分,在其可检查性方面几乎是语法上的。然而,人工智能工作中使用的程序规范甚至需要新的思想来制定。我认为,最近在非单调推理中的工作在这里将是有意义的,因为AI程序有效的事实需要跳转到有关其运行环境的结论。

虽然纯粹的LISP和“程序特性”的简单形式很容易形式化,但是操作性LISP系统的许多更高级的特性,如Interlisp、Maclisp和LISP Machine LISP [WM78],却很难形式化。其中一些如 fexpr 需要更多的数学研究,但在我看来,其他的则是拼凑的,应该在数学上更加简洁,这样使用它们的程序的特性就可以很容易地得到证明,同时也可以减少普通的bug。

目前的LISP系统的以下特性和提出的扩展需要新的正确性证明方法:

  1. 涉及可重入列表结构的程序。那些不涉及rplaca和rplacd的程序,如搜索和打印程序,比那些涉及rplaca和rplacd的程序访问性更高。我有一个适用于有限图的归纳法,但我还不知道如何处理rplaca,等等。对有限图的归纳也可用于证明关于流程图程序的定理。
  2. 没有系统的方法可以正式说明和证明语法指导计算的属性。
  3. 使用宏扩展的程序在原则上是可以通过解释器的公理化来实现的,但是我不知道任何实际的形式证明。
  4. 对于涉及惰性求值程序的正确性证明,不存在任何技术。
  5. 带有函数参数的程序原则上可以通过Dana Scott的方法访问,但是不同类型的函数参数只被描述性地和非正式地处理过。
  6. 使证明检查成为有用工具的最大障碍可能是我们缺乏如何表达程序规范的知识。许多程序都有有用的部分规范-它们不应循环或修改不属于它们的存储。少数满足代数关系,其中包括编译器。然而,与世界交互的程序具有规范,其中包含对世界的假设。一般而言,人工智能程序很难指定; 他们的规范很可能涉及默认和其他非单调推理。 (请参见[McC80]。)

迷题和其他问题

  1. Daniel Friedman 和 David Wise 认为 cons 不应求值其参数,并表明这允许将某些无限列表结构视为对象。这样就避免了麻烦,因为只有在需要打印答案的情况下才会创建无限结构。我不清楚无限列表结构的具体假设域是什么。虽然他们给出了一些有趣的应用实例,但尚不清楚所提议的扩展是否具有实用价值。
  2. 许多人提出了完整lambda演算的实现。这允许更高级别的函数,即函数的函数的函数,等等,但只允许基于组合和lambda转换的操作,而不允许对函数的符号形式进行一般操作。虽然没有直接提供条件表达式,但可以通过将 true 写作 “(lambda x y.x)”, 将 false 写作 “(lambda x y.y)” 并且将 “if p then a else b” 写作 “p(a)(b)” 来表示它们(如Dana Scott在未发表的笔记中所述)。Scott的另一个巧妙的想法(从Church的一个改进而来)是通过取列表(n+1)的第(n+1)个元素的操作来识别自然数n。神秘之处在于lambda演算的扩展是否有任何实际意义,而目前最好的猜测是没有,尽管Scott的符号思想建议改变LISP的符号,并为car写0,为cadr写1,为caddr写2,等等。
  3. 如果所有列表结构都在内存中惟一地表示,那么纯LISP在概念上就会简单得多。这可以通过使用 hash cons 来实现,但是这样 rplaca 之类的就不起作用了。难道我们不能两全其美吗?
  4. 在我看来,对于LISP来说,一种语言可能会取代LISP,就像LISP对机器语言所做的那样。也就是说,它将是一种比LISP更高一级的语言,就像LISP和机器语言一样,可以引用它自己的程序。(然而,比LISP更高级别的语言可能具有如此大的声明性组件,以至于其文本可能与程序不对应。如果取代解释器的工具足够聪明,那么用户编写的文本将比程序本身更像是有关目标事实和实现目标的手段的说明性描述。)

迫在眉睫的问题是,当前可用的抽象语法和当前的模式匹配系统都难以处理包含绑定变量的表达式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值