标签 Lisp 下的文章

这是非常重要的、上古的计算机上运行的,古老软件的新版本。

LM-3 项目宣布了 MIT CADR Lisp 机器 Lisp Machine 系统软件的第 100 版,这是它的最后一个版本。它既是一个新的版本,也是一个非常 古老的版本。

前两天,IBM 的 Eric Moore 在 LinkedIn 上发布了关于这个版本的 消息,他帮助了这项恢复工作。该项目的一个更详细的 帖子 描述了这个软件是什么,以及它是从哪里恢复的。

为什么这很重要?好吧,这款软件和它所运行的机器,是一场 “重要战斗” 的标志和纪念物。那场战斗是一场战争的一个阶段:一场以 “针锋相对的方式” 制造计算机的战争。“历史是由胜利者书写的”,温斯顿·丘吉尔 不是 第一个这样说的人。

这场战争和大多数战争一样,是两个 “对手阵营” 之间的战争。一方认为,制造计算机的正确方法是用最好的语言编写最好的软件,如果有必要的话,还要设计精工巧做的计算机来运行这些软件。另一方认为制造计算机的正确方法是制造小而快、容易而简单的软件和硬件,完成大多数人当时需要的工作。

同样,像大多数战争一样,这场战争是漫长而险恶的,双方都有一些肮脏的内斗。最终,有一方取得了决定性的胜利,但已经花了太长的时间,胜利者大多是开始战斗的那些人的后代和亲属。如今,他们甚至根本不记得有这么一场战争,而胜利的一方最终吸收了很多失败一方的想法和技术。最终的结果是,软件并不小而快,也不容易而简单。胜利的一方忘记了他们在战斗,也忘记了与之战斗的对手。

当胜利者忘记他们已经胜利了,也忘记了他们在战斗,这意味着失败者可以写一些最好的战争总结。一篇著名的报道是写自 1991 年的文章,名为《Lisp:好消息,坏消息,如何大获全胜》,其中说:

这两种哲学被称为 “ 做正确的事 The Right Thing ” 和 “ 差点则更好 Worse is Better ”。

“做正确的事” 是麻省理工学院/斯坦福的设计风格。另一边呢?

早期的 Unix 和 C 就是使用这种设计流派的例子,我将把这种设计策略的使用称为“新泽西方式”。

这篇文章只有短短几页,但如果你现在没有时间,用一句话可以概况,即 “差点则更好”。

换句话说,一方从麻省理工学院和斯坦福大学开始,他们最终设计了一种叫做 Lisp 机器 Lisp Machine 的计算机。另一方建立了 Unix 和后来专用的工作站,以快速运行 Unix,这需要可以快速运行编译的 C 代码的特殊处理器,它被称为 RISC 芯片。英特尔和 AMD 将 RISC 的一些技术和方法改编为 486 和奔腾芯片,AMD 则改编为皓龙和 x86-64,结果是 x86 电脑最终将 RISC 工作站赶出了市场。不过,今天,由于高端的 苹果芯片 Mac 和低端的 RISC-V,RISC 正在复兴当中。

但是,x86、RISC 和 CISC,以及 基于 Algol 的整个语言家族,包括从 BASIC 到 C++、到 Pascal、到 Go,基本上都是胜利一方的派别。而另一方现在几乎都被遗忘了,但有两个大的例子。一个是已故伟大的 约翰·麦卡锡 John McCarthy 创造的 Lisp,以及 整个基于 Lisp 的操作系统 所运行的 Lisp 机器。另一个是 Smalltalk 和施乐公司的 Alto

Symbolics 3620 (left) and LMI Lambda Lisp machines

麻省理工学院第一次尝试建造运行 Lisp 的计算机是一台 1974 年的原型机,名为 CONS,它以 Lisp 的一个关键词命名。1979 年,它更成功的后代被称为 CADR。CADR 计算机后来成为两家商业 Lisp 机器公司 LMI 和 Symbolics 的首批产品的基础,后者拥有互联网上的第一个 .com 域名。这些公司的成立,以及它们的软件的分拆,开始了 一个叫 理查德·斯托曼 Richard Stallman 的年轻黑客的职业生涯。

这条蓝色的导火索启动了 Emacs、GNU 项目,以及 自由软件运动 Free Software movement 。该项目建立了 GCC 等工具,这些工具被用来创建 Linux,而 Linux 本身也启动了 开源运动 Open Source movement

这次恢复的软件是麻省理工学院 CADR Lisp 机器的系统软件的最终版本。该软件是从麻省理工学院 技术广场磁带 Tapes of Tech Square (ToTS)收藏中的备份磁带上提取的,但它花了十年的时间来提取数据,对其进行清理,并使其在 35 年后首次运行。这是一个庞大的 工程

是的,如今可以运行这个软件,至少在软件模拟器上可以运行,比如最初由 Brad Parker 开发的 usim。它的源代码和一些历史都在 GitHub 上。


via: https://www.theregister.com/2023/03/31/mit_cadr_software_recovered/

作者:Liam Proven 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

某个在应用中利用零日漏洞的团队已被解散

之前我们报道过,某个主流电商应用利用零日漏洞达成不可卸载、窃取用户信息等恶意功能,后被谷歌 下架。此事也被其它安全团队独立 验证。据外媒报道,该公司有上百人负责挖掘安卓漏洞,并利用这些漏洞。最初带有恶意功能的版本只针对农村和小城镇的用户,以避免被发现。通过收集用户活动的大量数据,它得以提供更具有个性化的推送通知和广告,吸引用户打开应用并下单。此事曝光发酵后,该团队被解散,大部分人员被分流。并释出了新的版本移除了漏洞利用代码,但底层代码仍保留在其中。安全专家表示,他们从未看到过一个主流应用会那样做。

消息来源:CNN
老王点评:我的理解是,这就是“知行合一”。

上古的 LISP 机系统软件 v100 恢复成功

这是 MIT CADR Lisp 机的系统软件的最后一个版本。因此,这既是一个新的版本,也是一个非常古老的版本。这款软件和它所运行的机器是一场“重要战斗”的标志和纪念物,那场战斗是一场以敌对方式制造计算机的战争。战斗的双方,MIT/斯坦福一方认为,制造计算机的正确方法是用最好的语言编写最好的软件,如果有必要的话,还要设计特殊的花哨的计算机来运行这些软件;新泽西一方认为制造计算机的正确方法是制造小而快、容易和简单的软件和硬件,做大多数人在当时需要的事情。结果我们都知道了,MIT Lisp 机已经湮没在历史中;而胜利方开发出了 Unix 和 C,建立了 RISC、CISC、X86 指令架构,和基于 Algol 的整个语言家族,包括从 BASIC 到 C++ 到 Pascal 到 Go。被恢复的是 MIT CADR Lisp 机的系统软件的最终版本,从备份磁带上花费了十年的时间提取和清理,并使其在 35 年后首次运行。

消息来源:The Register
老王点评:真是尘封的历史文物。

Tor 合作推出的新浏览器不使用洋葱网络

Tor 项目正在推出一个注重隐私的浏览器 Mullvad 浏览器,它并不是连接到去中心化的洋葱网络。该浏览器的主要目标是使广告商和其他公司更难在互联网上追踪你。默认情况下,该浏览器通过屏蔽元数据,使网站更难对你进行 “指纹” 识别。此外,它还阻止了第三方 Cookie 和跟踪器,并预装了一些插件来进一步减少你的指纹。

消息来源:The Verge
老王点评:虽然装插件也可以实现,但是开箱即用还是会方便。只是这种浏览器有时候并不太方便。

许多大型代码库中都有 Lisp 代码的身影,因此,熟悉一下这门语言是一个明智之举。

早在 1958 年,Lisp 就被发明出来了,它是世界上第二古老的计算机编程语言(LCTT 译注:最古老的编程语言是 Fortran,诞生于 1957 年)。它有许多现代的衍生品,包括 Common Lisp、Emacs Lisp(Elisp)、Clojure、Racket、Scheme、Fennel 和 GNU Guile 等。

那些喜欢思考编程语言的设计的人,往往都喜欢 Lisp,因为它的语法和数据有着相同的结构:Lisp 代码实际上是 一个列表的列表 a list of lists ,它的名字其实是 “ 列表处理 LISt Processing ” 的简写。而那些喜欢思考编程语言的美学的人,往往都讨厌 Lisp,因为它经常使用括号来定义范围;事实上,编程界也有一个广为流传的笑话:Lisp 代表的其实是 “大量烦人的多余括号” Lots of Irritating Superfluous Parentheses

不管你是喜欢还是讨厌 Lisp 的设计哲学,你都不得不承认,它都是一门有趣的语言,过去如此,现在亦然(这得归功于现代方言 Clojure 和 Guile)。你可能会惊讶于在任何特定行业的大代码库中潜伏着多少 Lisp 代码,因此,现在开始学习 Lisp,至少熟悉一下它,不失为一个好主意。

安装 Lisp

Lisp 有很多不同的实现。比较流行的开源版本有 SBCLGNU LispGNU Common Lisp(GCL)。你可以使用发行版的包管理器安装它们中的任意一个,在本文中,我是用的是 clisp(LCTT 译注:也就是 GNU Lisp,一种 ANSI Common Lisp 的实现)。

以下是在不同的 Linux 发行版中安装 clisp 的步骤。

在 Fedora Linux 上,使用 dnf

$ sudo dnf install clisp

在 Debian 上,使用 apt

$ sudo apt install clisp

在 macOS 上,使用 MacPorts 或者 Homebrew

# 使用 MacPorts
$ sudo port install clisp

# 使用 Homebrew
$ brew install clisp

在 Windows 上,你可以使用 clisp on Cygwin 或者从 gnu.org/software/gcl 上下载 GCL 的二进制文件。

虽然我使用 clisp 命令来运行 Lisp 代码,但是本文中涉及到的大多数语法规则,对任何 Lisp 实现都是适用的。如果你选择使用一个不同的 Lisp 实现,除了用来运行 Lisp 代码的命令会和我不一样外(比如,你可能要用 gclsbcl 而不是 clisp),其它的所有东西都是相同的。

列表处理

Lisp 源代码的基本单元是 “ 表达式 expression ”,它在形式上是一个列表。举个例子,下面就是一个列表,它由一个操作符(+)和两个整数(12)组成:

(+ 1 2)

同时,它也是一个 Lisp 表达式,内容是一个符号(+,会被解析成一个加法函数)和它的两个参数(12)。你可以在 Common Lisp 的交互式环境(即 REPL)中运行该表达式和其它表达式。如果你熟悉 Python 的 IDLE,那么你应该会对 Lisp 的 REPL 感到亲切。(LCTT 译注:REPL 的全称是 “Read-Eval-Print Loop”,意思是 “‘读取-求值-输出’循环”,这个名字很好地描述了它的工作过程。)

要进入到 REPL 中,只需运行 Common Lisp 即可:

$ clisp
[1]>

在 REPL 提示符中,尝试输入一些表达式:

[1]> (+ 1 2)
3
[2]> (- 1 2)
-1
[3]> (- 2 1)
1
[4]> (+ 2 3 4)
9

函数

在了解了 Lisp 表达式的基本结构后,你可以使用函数来做更多有用的事。譬如,print 函数可以接受任意数量的参数,然后把它们都显示在你的终端上,pprint 函数还可以实现格式化打印。还有更多不同的打印函数,不过,pprint 在 REPL 中的效果就挺好的:

[1]> (pprint "hello world")

"hello world"

[2]>

你可以使用 defun 函数来创建一个自定义函数。defun 函数需要你提供自定义函数的名称,以及它接受的参数列表:

[1]> (defun myprinter (s) (pprint s))
MYPRINTER
[2]> (myprinter "hello world")

"hello world"

[3]>

变量

你可以使用 setf 函数来在 Lisp 中创建变量:

[1]> (setf foo "hello world")
"hello world"
[2]> (pprint foo)

"hello world"

[3]>

你可以在表达式里嵌套表达式(就像使用某种管道一样)。举个例子,你可以先使用 string-upcase 函数,把某个字符串的所有字符转换成大写,然后再使用 pprint 函数,将它的内容格式化打印到终端上:

[3]> (pprint (string-upcase foo))

"HELLO WORLD"

[4]>

Lisp 是动态类型语言,这意味着,你在给变量赋值时不需要声明它的类型。Lisp 默认会把整数当作整数来处理:

[1]> (setf foo 2)
[2]> (setf bar 3)
[3]> (+ foo bar)
5

如果你想让整数被当作字符串来处理,你可以给它加上引号:

[4]> (setf foo "2")
"2"
[5]> (setf bar "3")
"3"
[6]> (+ foo bar)

*** - +: "2" is not a number
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead.
ABORT          :R2      Abort main loop
Break 1 [7]>

在这个示例 REPL 会话中,变量 foobar 都被赋值为加了引号的数字,因此,Lisp 会把它们当作字符串来处理。数学运算符不能够用在字符串上,因此 REPL 进入了调试器模式。想要跳出这个调试器,你需要按下 Ctrl+D 才行(LCTT 译注:就 clisp 而言,使用 quit 关键字也可以退出)。

你可以使用 typep 函数对一些对象进行类型检查,它可以测试对象是否为某个特定数据类型。返回值 TNIL 分别代表 TrueFalse

[4]> (typep foo 'string)
NIL
[5]> (typep foo 'integer)
T

stringinteger 前面加上了一个单引号('),这是为了防止 Lisp(错误地)把这两个单词当作是变量来求值:

[6]> (typep foo string)
*** - SYSTEM::READ-EVAL-PRINT: variable STRING has no value
[...]

这是一种保护某些术语(LCTT 译注:类似于字符串转义)的简便方法,正常情况下它是用 quote 函数来实现的:

[7]> (typep foo (quote string))
NIL
[5]> (typep foo (quote integer))
T

列表

不出人意料,你当然也可以在 Lisp 中创建列表:

[1]> (setf foo (list "hello" "world"))
("hello" "world")

你可以使用 nth 函数来索引列表:

[2]> (nth 0 foo)
"hello"
[3]> (pprint (string-capitalize (nth 1 foo)))

"World"

退出 REPL

要结束一个 REPL 会话,你需要按下键盘上的 Ctrl+D,或者是使用 Lisp 的 quit 关键字:

[99]> (quit)
$

编写脚本

Lisp 可以被编译,也可以作为解释型的脚本语言来使用。在你刚开始学习的时候,后者很可能是最容易的方式,特别是当你已经熟悉 Python 或 Shell 脚本 时。

下面是一个用 Common Lisp 编写的简单的“掷骰子”脚本:

#!/usr/bin/clisp

(defun roller (num)  
  (pprint (random (parse-integer (nth 0 num))))
)

(setf userput *args*)
(setf *random-state* (make-random-state t))
(roller userput)

脚本的第一行注释(LCTT 译注:称之为“ 释伴 shebang ”)告诉了你的 POSIX 终端,该使用什么可执行文件来运行这个脚本。

roller 函数使用 defun 函数创建,它在内部使用 random 函数来打印一个伪随机数,这个伪随机数严格小于 num 列表中下标为 0 的元素。在脚本中,这个 num 列表还没有被创建,不过没关系,因为只有当脚本被调用时,函数才会执行。

接下来的那一行,我们把运行脚本时提供的任意参数,都赋值给一个叫做 userput 的变量。这个 userput 变量是一个列表,当它被传递给 roller 函数后,它就会变成参数 num

脚本的倒数第二行产生了一个“随机种子”。这为 Lisp 提供了足够的随机性来生成一个几乎随机的数字。

最后一行调用了自定义的 roller 函数,并将 userput 列表作为唯一的参数传递给它。

将这个文件保存为 dice.lisp,并赋予它可执行权限:

$ chmod +x dice.lisp

最后,运行它,并给它提供一个数字,以作为它选择随机数的最大值:

$ ./dice.lisp 21

13
$ ./dice.lisp 21

7
$ ./dice.lisp 21

20

看起来还不错!

你或许注意到,你的模拟骰子有可能会是 0,并且永远达不到你提供给它的最大值参数。换句话说,对于一个 20 面的骰子,这个脚本永远投不出 20(除非你把 0 当作 20)。有一个简单的解决办法,它只需要用到在本文中介绍的知识,你能够想到吗?

学习 Lisp

无论你是想将 Lisp 作为个人脚本的实用语言,还是为了助力你的职业生涯,抑或是仅仅作为一个有趣的实验,你都可以去看看一年一度(LCTT 译注:应该是两年一度)的 Lisp 游戏果酱 Game Jam ,从而收获一些特别有创意的用途(其中的大多数提交都是开源的,因此你可以查看代码以从中学习)。

Lisp 是一门有趣而独特的语言,它有着不断增长的开发者用户群、足够悠久的历史和新兴的方言,因此,它有能力让从事各个行业的程序员都满意。


via: https://opensource.com/article/21/5/learn-lisp

作者:Seth Kenlon 选题:lkxed 译者:lkxed 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

代码英雄讲述了开发人员、程序员、黑客、极客和开源反叛者如何彻底改变技术前景的真实史诗。

什么是《代码英雄》

代码英雄 Command Line Heroes 是世界领先的企业开源软件解决方案供应商红帽(Red Hat)精心制作的原创音频播客,讲述开发人员、程序员、黑客、极客和开源反叛者如何彻底改变技术前景的真实史诗。该音频博客邀请到了谷歌、NASA 等重量级企业的众多技术大牛共同讲述开源、操作系统、容器、DevOps、混合云等发展过程中的动人故事。

本文是《代码英雄》系列播客《代码英雄》第三季(7):与机器对话音频脚本。

导读:创造一台会思考的机器在 20 世纪 50 年代似乎是科幻小说。但 John McCarthy 决定把它变成现实。他从一种叫做 LISP 的语言开始。Colin Garvey 介绍了 McCarthy 是如何创造出第一种人工智能语言的。Sam Williams 介绍了早期人们对思考机器的兴趣是如何从学术界蔓延到商业界的,以及在某些项目没有兑现承诺之后,漫长的人工智能寒冬是如何最终到来的。Ulrich Drepper 解释说,人工智能的梦想超出了当时硬件所能提供的范围。

但硬件每天都在变得更强大。Chris Nicholson 指出,今天的机器有足够的处理能力来处理人工智能的资源需求 —— 以至于我们正处于人工智能研发的革命性复苏之中。最后,Rachel Thomas 确定了 LISP 之外的人工智能语言 —— 证明了人工智能现在正准备做的不同类型的任务。

00:00:05 - 播音员

卡斯帕罗夫非常慌乱。虽然已经拼尽全力,但是他意识到,他已经输了。

00:00:12 - Saron Yitbarek

1997 年的春天,国际象棋冠军 加里·卡斯帕罗夫 Garry Kasparov 输给了计算机程序“深蓝”。对于机器智能来说,这是历史上的关键时刻。对于某些人来说,这是一次生存危机,是对人类智慧至上的挑战。但是,对于世界上的技术专家来说,这是另一种意味上的里程碑,是 人工智能 artificial intelligence (AI)领域的一次飞跃。这表明,想要真正的智慧机器诞生,或许不是太过于疯狂的梦想。

00:00:47 - 播音员

去赋予一台机器思考的能力仍然还是梦想,距离实现梦想还需要很多年的努力。此外,还需要做出不少惊人的突破。

00:00:56 - Saron Yitbarek

我们是如何抵达这一步的?是什么导致了卡斯帕罗夫那场著名的失败?我们从哪里来,又该到哪里去?我是 Saron Yitbarek,这里是《代码英雄》,一档来自红帽的原创播客节目。在本季,我们都在探索编程语言的奥秘,揭开他们的历史和发展潜力。这一期让我们关注人工智能。你会使用什么语言,来让你的机器拥有自己的思想呢?我们的编程语言如何帮助我们抵达“深蓝时刻”,甚至是更远的地方?什么样的编程语言能最适配会思考的机器?这是我们半个多世纪以来一直在尝试解决的问题。因此,我们的故事要追溯到 1940 年代,那时,人工智能这个词汇还没有被创造出来。

00:01:59:

回顾二战结束是如何结束的,我们有这样一种感觉,那就是技术帮助同盟国赢得了战争。人们乐观地认为,科技可以成就一切。整整一代人都相信计算机的力量。在这一代人中诞生了人工智能的教父,一位出色的数学家 —— 约翰·麦卡锡 John McCarthy ,他从根本上改变了我们与机器交谈的方式。我想知道他的思想的起源,以及范式的转变是如何发生的。我的意思是,对于初学者来说,当麦卡锡和他的同事们在想象智能机器的未来时,他们到底想象了什么?

00:02:43 - Colin Garvey

哇,这是一个好问题。

00:02:46 - Saron Yitbarek

我和 Colin Garvey 聊了聊。他是 伦斯勒理工学院 Rensselaer Polytechnic Institute 科学与技术研究系的历史学家。以下是我们的一些聊天内容:

00:02:58 - Colin Garvey

麦卡锡对提出 AI 究竟是什么这件事情非常谨慎。不过,举个例子来说,他可能在他最著名但并未实现的程序中描述过(这只是一个思路),人工智能是一个 接受建议者 advice taker 。接受建议者这个说法由麦卡锡于 1960 年的名为《 具有常识的程序 Programs with Common Sense 》的论文中提出的。在开始的时候,你觉得接受建议者可能是一个会学习的机器人,这是它被发明的本意,它算是一个可以接受建议的家用机器人。你说:“不,你这样做是错误的,要那样做。”它就会明白你的意思。

00:03:44 - Saron Yitbarek

那很有帮助。

00:03:45 - Colin Garvey

可能会有帮助。那时候接受建议者要实现的目标是,从办公室导航到机场。换句话说,将从办公室去机场这个建议,正式化成接受建议者机器人能够接受的程序以达成目的,得出从办公室前往机场的一系列程序。它把人类的语言正式化为一系列的合乎逻辑的陈述,即需要根据现在的情况进行合适的抉择,以达到把当前情况转变为理想情况的目标。他将这些想法伪代码化,这实际上是 LISP 的起源。然后在接下来的几年里,LISP 作为他想法的实现,或者说实现他想法的语言出现了。

00:04:39 - Saron Yitbarek

麦卡锡的 LISP 语言改变了游戏规则。它不仅能帮助机器理解命令,还能帮助机器理解一些常识性的逻辑。麦卡锡发现,他可以编写条件表达式,即体现规则的代码,而不是仅仅是直白的命令。实际上,LISP 有一堆重大的编程突破,条件表达式、垃圾回收、递归等等。LISP 在代码和数据中都使用了列表。这是一个简单但具有深远的影响的更改。这是语言范式的转变,所有这些为麦卡锡本人称之为“人工智能”的整个领域打开了大门。想象一下,在你和机器说话的时候,并不需要把每一个细节都给编写好。你可以让那台机器自己来进行推断和推理。麦卡锡希望通过他的 LISP 语言,给机器一种智慧。好了,回到我和 Colin Garvey 的聊天。

00:05:41 - Colin Garvey

LISP 是人们编写高级计算机语言的尝试的过程中,诞生的精华。

00:05:47 - Saron Yitbarek

这很有意思。因为我的下一个问题是 LISP 和人工智能之间的关系。接受建议者第一次描述了 AI 的功能,它听起来也像是 LISP 的开始。能跟我聊聊更多 LISP 和人工智能之间的关系吗?

00:06:04 - Colin Garvey

当然。这些早期的人工智能研究人员面临着一件事,那就是他们还在使用打孔卡进行编程。也许这些早期的编程人员,知道如何进行机器码级别的编程,这是非常困难且耗时的工作。因此,你需要一个更高级的编程语言,以便你可以用更加接近人类语言的方式编程。所以,像 LISP 这样,用列表的形式给出指令的语言 —— 这也是其名称的来源,基于列表的处理(LCTT 译注,LISP 全称:“LISt Processing“)。从某种意义上来说,这样用列表给出的指令更加接近于人类语言,因为他们基本上都可以用通顺的逻辑去理解。因此,如果你可以读懂 形式逻辑 formal logic ,那么基本上可以看明白 LISP 程序,或者任何基于逻辑的编程语言的程序,并对于代码中发生的事情有着更好的了解。

00:07:10 - Saron Yitbarek

所以 LISP 真的帮了大忙……嗯,我的意思是它帮助我们将我们的想法给予人工智能,让我们能够朝着实现人工智能努力,有朝一日总能达成这个梦想。不过这也让我想知道在那个时期,“智能”到底意味着什么?所以,如果我们回到 50 年代,在那个时间点上,什么是“智能”?人们是如何定义它的?因为 LISP 最初为 IBM 704 开发的,它每次做的其实只是一件事。看起来并不是很“智能”。当时的人们是如何看待“智能”的呢?

00:07:43 - Colin Garvey

有关“智能”的定义,这自然非常有争议的。就我个人,从一个普通大众的角度而言,他们的概念是非常狭窄的。但是在当时,广泛认可的定义是:能够执行被认为有智力的举动的能力。但持这个观点的这些人实际上是数学家、逻辑学家和计算机程序员。我的意思是,说句粗俗的话,下棋的能力被认为是智力的明确标志。这一代早期的 AI 人更喜欢回避这个问题,并说,“嗯,哲学家们还没有就什么是‘智力’达成一致,但如果我们制造出一台能下棋的电脑,我想我们都同意这是‘智能’。“

00:08:40 - Saron Yitbarek

不管怎样,这是一个起点。就像婴儿的第一步。

00:08:45 - Colin Garvey

麦卡锡有一个梦想,让机器可以具有常识,并像人一样聪明。本质上来说,你可以和它们交谈。他开始创造一种程序语言来实现这个梦想。这就是 LISP。它模仿了人类思想的某些方面,尤其是逻辑思维能力,并使得利用计算机放大或扩展这些思想特征成为可能。所以从数学家的角度来看,他已经在实现智能机械的道路上走得很远了。

00:09:32 - Saron Yitbarek

Colin Garvey 是伦斯勒理工学院科学技术研究系的历史学家。

随着 LISP 的推进,发展人工智能的新机会开始出现,LISP 是这一新领域的标准语言。麦卡锡离开麻省理工学院去斯坦福大学工作后,麻省理工学院的其他工程师继续从事 LISP 工作。他们把麦卡锡的语言改进成一种叫做 Maclisp 的方言版本,甚至开发了 LISP 操作系统。看起来麦卡锡对人工智能未来的梦想正在成为现实。1968 年,麦卡锡甚至和苏格兰国际象棋大师 大卫·利维 David Levy 打赌。麦卡锡打赌,10 年后,电脑将能够在国际象棋比赛中赢过利维。但是,如果事情进展得那么顺利,那就不是《代码英雄》的故事了。那时候麦卡锡还不知道,人工智能的冬天就要来了。

00:10:45 - Saron Yitbarek

当麻省理工学院的那个基于 LISP 的操作系统,从学院衍生到公司后,情况开始发生变化。其中的一家公司 Symbolix 推出了 LISP 机器,甚至从 MIT 的 AI 实验室 AI Lab 雇用了 14 名员工,而且更不切实际的研究不再是重点。

00:11:25 - Sam Williams

这些公司原本都来自 AI 实验室。

00:11:31 - Saron Yitbarek

这是记者 Sam Williams,他写了一本名为《Arguing AI》的书。

00:11:36 - Sam Williams

Symbolix 可能是最突出的一个。它得到了最多的关注、最多的风险投资。约翰·麦卡锡和他的门徒们推动了所有的创新。我想,这只是一个案例。在 70 年代末期,人们普遍认为:“好吧,我们已经在学术界做了我们能够做到的事情,让我们在商界脱颖而出,让私营企业为我们投资。”

00:12:01 - Saron Yitbarek

这在当时的环境下可以理解。那时AI 似乎即将起飞,有利可图。

00:12:07 - Sam Williams

那时候的算力便宜到中型企业也可以购买。因此,我认为许多公司看到了一个机会:“那里有一个富有潜力的市场,我们可以进入这个市场,我们可以把关于人工智能的产出卖给那些想要具有全球竞争力的企业。”他们让投资者为这个想法大肆投资。在 80 年代初期,大量的资金涌入该领域。

00:12:29 - Saron Yitbarek

我们可以讨论一下为什么这个热潮后来干涸了。但是,我现在可以肯定的一点是,事情已经被大肆炒作了。

00:12:39 - Sam Williams

大量资金流入。人们认为市场非常成熟。

00:12:44 - Saron Yitbarek

从一定来说,大量热钱涌入人工智能领域造成的繁荣,就像世纪之交时网络泡沫的前奏。

00:12:52 - Sam Williams

这在技术发展史上并不少见,人们过度投资,但最终公司未能兑现他们的希望。所以,资金供应陷入困境。公司必须通过老式的方式赚钱 —— 去拉客户,去生产东西。

00:13:08 - Saron Yitbarek

所以那时,麦卡锡的梦想轰然崩溃,回归了现实。Williams 描述了随后的人工智能冬天。

00:13:16 - Sam Williams

你会看到像 Symbolix 这样的公司市值上升到 1 亿美元,然后短短几年后就申请破产保护。在那时候有很多这样的人:“在 10 年内,我们将做到这一点,在 5 年内,你会看到这个。5 年后,你就会看到这个。”这些家伙是投机者,或者是想要从五角大楼或任何其他地方获取更多资金的学者。因为这种危险的炒作,过度炒作,让人工智能走上歧途。

00:13:48 - Saron Yitbarek

人们对于人工智能的兴趣崩塌了。基础设施不到位,或许计算速度也不够高,这使一切努力都变成了徒然。但无论如何,这之中的指导思想是正确的,它只是生在了错误的时代。到了 80 年代末,人工智能研究日渐减少。

00:14:06 - Sam Williams

我认为人们脱离人工智能这个领域的原因是,它失去了最初吸引他们进入其中时的冒险性。它曾处于技术领域的最前沿。在西海岸,很多人的精力被吸引到制造个人电脑上。从 40 年后的今天看来,试着让电脑进入美国每个家庭,比帮助财富 1000 强的企业做出更好的决策,是一个更引人注目的概念。

00:14:39 - Saron Yitbarek

Sam Williams 是《Arguing AI》的作者。我们在这里描述的是一个计算机编程的世界,它被一分为二:一方面是约翰·麦卡锡这样的人,他们试图使用 LISP 等新型语言来探究智能的本质;另一方面,也不可避免地存在着另一群人,他们更专注于解决实际问题,试图让那些愿意为其服务付款的企业轻松一些。现实情况是,世界上的那些约翰·麦卡锡们,那些抽象的梦想家们,并没有太多机会在人工智能的可能性上进行深入探索。他们所拥有的设备甚至还比不上我们今天使用的手机。他们的愿景对于手头的硬件现实来说,真的太大了。

00:15:36 - Ulrich Drepper

当初,我们在轰轰作响的庞大计算机上工作,和数不清的人、数不清的工作组抢夺它有限的性能。

00:15:46 - Saron Yitbarek

这是红帽的杰出工程师 Ulrich Drepper。他解释了早期的人工智能梦想之所以失败,只是因为没有成功所需的基本工具。

00:15:55 - Ulrich Drepper

我们有 PDP 10,PDP 11 之类的计算机(LCTT 译注:Digital Equipment Corporation 公司的大型计算机产品),但每一台都可能有另外 20 个人在同时使用。即使没有这些人将计算力分流走,它们也是真正的低能力机器,其性能不足以在支持 LISP 系统的必要功能的同时,运行一套机能齐全的用户界面。

00:16:19 - Saron Yitbarek

随着时间的推移,新开发的硬件对 LISP 也不再友好。

00:16:26 - Ulrich Drepper

我们不仅走了台式机的道路,也走了服务器的道路。在我们今天已经习惯的处理器类型中,我们的实现的一切都是基于 8 位的处理器,而我们可能有了 16 位处理器、32 位处理器之类的。想要在这样的机器上高效实现 LISP 系统,就必须绕不少圈才能成功。

00:16:56 - Saron Yitbarek

因此,计算世界的外部现实对这个脆弱的人工智能领域产生了意想不到的抑制作用。

00:17:06 - Ulrich Drepper

和大厂商生产的 CPU 相比,定制硬件的成本极为高昂,其发展也极为缓慢。

00:17:21 - Saron Yitbarek

通过创建自定义的硬件解决方案,继续使用 LISP 朝着 AI 梦想前进并非不可能。但是,事实是,令人兴奋的新硬件将很多人的注意力推向了其他工作领域。

00:17:35 - Ulrich Drepper

你只需要等待处理器的下一个版本,那个普通的处理器获得的改进,比你自己开发硬件求解,比如说实现一个 LISP 系统,所能达到的效果和收获要大得多。最终,硬件变得越来越复杂,自行定制硬件成为了一件近乎于不可能的事。

00:18:03 - Saron Yitbarek

那么,约翰·麦卡锡的远景梦想是慢慢死去,还是只在那漫长的人工智能冬天里沉睡,等待时机?在 21 世纪的第一个十年里,约翰·麦卡锡的语言 LISP 的使用者不断地流失。但是,在同一时间,发生了一件惊人的事。尽管 LISP 本身逐渐消逝,与这门语言相连的梦想却被重新点燃了。人工智能的梦想重新活了起来。

00:18:34 - Chris Nicholson

我想说的是,这次不一样。

00:18:36 - Saron Yitbarek

这是 Chris Nicholson,开源 AI 软件公司 Skymind 的创始人兼 CEO。Chris 认为,在经历了大起大落之后,人工智能或许终于要进入一个可持续发展的长夏了。

00:18:52 - Chris Nicholson

我们正处在人工智能的夏天,许多人都对 AI 可能的应用而激动不已。但是,这种兴奋是基于研究的真正进展,而这些进展是基于其他领域的进展。我们的硬件比当初好了太多太多,人们能用 GPU 替代 CPU,也能在大规模集群中使用这些 GPU 来训练巨大的机器学习模型,从而产生真正准确的预测。为了做到这一点,他们也使用了前所未有的巨大数据集,这样的数据量在 80 年代、90 年代或者之前都是闻所未闻、见所未见的。

00:19:30 - Saron Yitbarek

对于 AI 语言,巨大的数据集的兴起是关键,因为它们代表了我们理解智能的方式的关键变化。AI 研究的重点转移到了 深度学习 deep learning 方面,而深度学习似乎成为了 AI 研究的全部。

00:19:47 - Chris Nicholson

LISP 是为了操纵符号而设计的。在 LISP 诞生的时代,AI 意味着符号推理。当时,人们认为人类的思维和智力本身就是符号的操作。现代的人工智能,也就是让我们如此着迷的人工智能,远不止于此。现在的 AI,就机器学习而言,是一种可以从非结构化数据中学习的大型数据处理机器。因此,你可以让机器学习算法一点一滴地拾起文本和图像,在这个过程中,随着时间的推移,这些算法将变得越来越智能。LISP 不是那样设计的。它被设计为仅在人工干预的基础上发展。然而,对于现在的机器学习算法而言,其中的学习部分意味着它们会根据所接触的数据进行自我调整。

00:20:40 - Saron Yitbarek

这就是让机器以它们自己的方式实现智能化。但是,你知道,不仅仅是我们的机器在学习以强大的新方式思考;开源工具也让人们提高了自己的水平。克里斯认为,开源的开发方式对防止另一个人工智能冬天的到来有很大的帮助。

00:21:03 - Chris Nicholson

人工智能冬天发生的一个原因是,当创意在放缓时,网络就会崩溃,资金就会枯竭。有了现在这些免费的开源工具,我们看到的不是创意的放缓,而是一种加速。创意得以被及时地测试,得以被迅速地分享。所以,这不仅仅是工具,而是预先训练好的机器学习模型,一个研究小组可以与另一个研究小组分享,或者与广大公众分享。而创意本身也被发表在 ARXIV 这样的平台上。ARXIV 是由 康奈尔大学 Cornell University 主办的。所有这些因素汇合在一起,加快了创意流动的速度。对我来说,这是对人工智能冬天的一种保险。这些因素的交汇使得人工智能成为一个超级令人兴奋的领域,它们意味着人工智能的发展速度比炒作更快。

00:22:03 - Saron Yitbarek

Chris Nicholson是 Skymind 的创始人兼 CEO。

所以,开源能将人工智能领域从旧的专有模式所催生的寒冬中解冻出来。AI 的新时代伴随着 GPU 的巨大改进而到来。与之一并到来的还有算法上的突破,它帮助我们训练 AI 学习数据中的模式。然后,数据本身,海量的数据集正在为今天的 AI 提供动力。这一点,比任何事情都重要,这就是为什么新语言得以继续 LISP 未能完成的征途。我们向 Fast AI 的联合创始人 Rachel Thomas 询问,哪些语言适合下一代 AI。

00:22:50 - Rachel Thomas

我们目前正在探索将 Swift 用于 TensorFlow 的可能性。Swift 是 Chris Lattner 开发的一种语言,我知道也有人在使用 Julia,他们正促进着 Julia 的开发与发展。但是,就目前而言,Python 在深度学习领域有着无可比拟的巨大优势。

00:23:03 - Saron Yitbarek

这是因为 Python 非常适合处理大型数据集。

00:23:08 - Rachel Thomas

我认为过去 20 年中发生的最重要的改变是,数据量的增长和人们对于数据的越发重视。我认为,数十年前有关 AI 的许多早期工作更多地围绕一种符号系统,即某种抽象符号系统。我要说的是,目前 AI 领域中的许多工作都围绕着数据展开,例如识别图像里的某样东西,或者辨认一条影评是褒还是贬。这些都是基于数据的问题。所以,我认为,Python 成为赢家 —— 至少是早期的赢家 —— 的原因之一,是因为 NumPy、SciPy 和 pandas 的生态系统,以及 Python 中所有数据处理用的库都足够完善。

00:24:02 - Saron Yitbarek

在约翰·麦卡锡的团队还在麻省理工学院工作时,人工智能事业确实只有世界级的精英学者才能参与。但是自那时以来,语言和计算环境已经发生了巨大的发展,时至今日,每个人都能参与到 AI 的领域中来。我们在本季的第 1 期中听说过,Python 是许多初学者的第一语言。它使新手程序员能够加入 AI 的世界。

00:24:29 - Rachel Thomas

我只想告诉大家,实际上你只需要一年的编码经验。你不需要诸如“鬼才”这样的名号,也不必具有真正的声望或权威。但是,我们需要来自各个背景的人。实际上,不同背景的人才能够为这个领域提供许多新鲜的创意,你的创意也是我们所需要的。

00:24:52 - Saron Yitbarek

Rachel Thomas 是 Fast AI 的联合创始人,也是旧金山大学数据研究所的教授。我喜欢她为我们提供的信息。

AI 的故事是发现截然不同的人们之间的共同语言的故事。这是我们真正的任务,为充满 AI 的世界开发语言解决方案,开发能使所有人共同努力以实现下一个突破的解决方案。

00:25:22 - 播音员 1

各位,你们看到了今天在这里创造的历史。AlphaGo 以伟大的风格赢得了比赛。

00:25:32 - 播音员 2

是的,它甚至向我们展示了它的代码。

00:25:34 - 发言者 7

甚至向我们展示了它的代码。我想要祝贺这个计划。

00:25:40 - Saron Yitbarek

2015 年,就在 加里·卡斯帕罗夫 Garry Kasparov 在国际象棋比赛中输给深蓝的几十年后,围棋世界冠军李世乭被谷歌的 AlphaGo 击败。深蓝显示出的智力威力大半依托于蛮力,而 AlphaGo 的胜利之所以让人感到惊讶,是因为它依靠神经网络和强化学习赢得了那场比赛。换句话说,AlphaGo 已经成功地朝着真正的智慧迈出了下一步。如果没有开源对人工智能的推动,这一切都不可能发生。新的语言正朝着麦卡锡的梦想而逐渐发展。我们的语言正越来越适合于最大限度地提高机器的智能。好消息是,在开源世界中,我们可以共同实现这份梦想,共同应对它所带来的挑战。

00:26:39 - Saron Yitbarek

《代码英雄》是红帽的原创播客节目。如果你希望更深入的了解 LISP 或者人工智能,你可以访问节目的网站 redhat.com/commandlineheroes。在这里,你也能看到每一集的额外内容。下一期将是本季的最终集。在下一期中,我们将对一门重量级语言进行探究,并揭露与之有关的许多惊人事实;这门语言对本季中迄今为止讨论过的几乎所有语言都产生过影响。这是我们对 C 的深入研究。我是 Saron Yitbarek,下期之前,编程不止。

什么是 LCTT SIG 和 LCTT LCRH SIG

LCTT SIG 是 LCTT 特别兴趣小组 Special Interest Group ,LCTT SIG 是针对特定领域、特定内容的翻译小组,翻译组成员将遵循 LCTT 流程和规范,参与翻译,并获得相应的奖励。LCRH SIG 是 LCTT 联合红帽(Red Hat)发起的 SIG,当前专注任务是《代码英雄》系列播客的脚本汉化,已有数十位贡献者加入。敬请每周三、周五期待经过我们精心翻译、校对和发布的译文。

欢迎加入 LCRH SIG 一同参与贡献,并领取红帽(Red Hat)和我们联合颁发的专属贡献者证书。


via: https://www.redhat.com/en/command-line-heroes/season-3/talking-to-machines

作者:Red Hat 选题:bestony 译者:bestony 校对:acyanbird, Northurland, wxy

本文由 LCRH 原创编译,Linux中国 荣誉推出

当程序员们谈论各类编程语言的相对优势时,他们通常会采用相当平淡的措词,就好像这些语言是一条工具带上的各种工具似的 —— 有适合写操作系统的,也有适合把其它程序黏在一起来完成特殊工作的。这种讨论方式非常合理;不同语言的能力不同。不声明特定用途就声称某门语言比其他语言更优秀只能导致侮辱性的无用争论。

但有一门语言似乎受到和用途无关的特殊尊敬:那就是 Lisp。即使是恨不得给每个说出形如“某某语言比其他所有语言都好”这类话的人都来一拳的键盘远征军们,也会承认 Lisp 处于另一个层次。 Lisp 超越了用于评判其他语言的实用主义标准,因为普通程序员并不使用 Lisp 编写实用的程序 —— 而且,多半他们永远也不会这么做。然而,人们对 Lisp 的敬意是如此深厚,甚至于到了这门语言会时而被加上神话属性的程度。

大家都喜欢的网络漫画合集 xkcd 就至少在两组漫画中如此描绘过 Lisp:其中一组漫画中,某人得到了某种 Lisp 启示,而这好像使他理解了宇宙的基本构架。

另一组漫画中,一个穿着长袍的老程序员给他的徒弟递了一沓圆括号,说这是“文明时代的优雅武器”,暗示着 Lisp 就像原力那样拥有各式各样的神秘力量。

另一个绝佳例子是 Bob Kanefsky 的滑稽剧插曲,《上帝就在人间》。这部剧叫做《永恒之火》,撰写于 1990 年代中期;剧中描述了上帝必然是使用 Lisp 创造世界的种种原因。完整的歌词可以在 GNU 幽默合集中找到,如下是一段摘抄:

因为上帝用祂的 Lisp 代码

让树叶充满绿意。

分形的花儿和递归的根:

我见过的奇技淫巧之中没什么比这更可爱。

当我对着雪花深思时,

从未见过两片相同的,

我知道,上帝偏爱那一门

名字是四个字母的语言。

(LCTT 译注:“四个字母”,参见:四字神名,致谢 no1xsyzy

以下这句话我实在不好在人前说;不过,我还是觉得,这样一种 “Lisp 是奥术魔法”的文化模因实在是有史以来最奇异、最迷人的东西。Lisp 是象牙塔的产物,是人工智能研究的工具;因此,它对于编程界的俗人而言总是陌生的,甚至是带有神秘色彩的。然而,当今的程序员们开始怂恿彼此,“在你死掉之前至少试一试 Lisp”,就像这是一种令人恍惚入迷的致幻剂似的。尽管 Lisp 是广泛使用的编程语言中第二古老的(只比 Fortran 年轻一岁) 1 ,程序员们也仍旧在互相怂恿。想象一下,如果你的工作是为某种组织或者团队推广一门新的编程语言的话,忽悠大家让他们相信你的新语言拥有神力难道不是绝佳的策略吗?—— 但你如何能够做到这一点呢?或者,换句话说,一门编程语言究竟是如何变成人们口中“隐晦知识的载体”的呢?

Lisp 究竟是怎么成为这样的?

Byte 杂志封面,1979年八月。

Byte 杂志封面,1979年八月。

理论 A :公理般的语言

Lisp 的创造者 约翰·麦卡锡 John McCarthy 最初并没有想过把 Lisp 做成优雅、精炼的计算法则结晶。然而,在一两次运气使然的深谋远虑和一系列优化之后,Lisp 的确变成了那样的东西。 保罗·格雷厄姆 Paul Graham (我们一会儿之后才会聊到他)曾经这么写道, 麦卡锡通过 Lisp “为编程作出的贡献就像是欧几里得对几何学所做的贡献一般” 2 。人们可能会在 Lisp 中看出更加隐晦的含义 —— 因为麦卡锡创造 Lisp 时使用的要素实在是过于基础,基础到连弄明白他到底是创造了这门语言、还是发现了这门语言,都是一件难事。

最初, 麦卡锡产生要造一门语言的想法,是在 1956 年的 达特茅斯人工智能夏季研究项目 Darthmouth Summer Research Project on Artificial Intelligence 上。夏季研究项目是个持续数周的学术会议,直到现在也仍旧在举行;它是此类会议之中最早开始举办的会议之一。 麦卡锡当初还是个达特茅斯的数学助教,而“ 人工智能 artificial intelligence (AI)”这个词事实上就是他建议举办该会议时发明的 3 。在整个会议期间大概有十人参加 4 。他们之中包括了 艾伦·纽厄尔 Allen Newell 赫伯特·西蒙 Herbert Simon ,两名隶属于 兰德公司 RAND Corporation 卡内基梅隆大学 Carnegie Mellon 的学者。这两人不久之前设计了一门语言,叫做 IPL。

当时,纽厄尔和西蒙正试图制作一套能够在命题演算中生成证明的系统。两人意识到,用电脑的原生指令集编写这套系统会非常困难;于是他们决定创造一门语言——他们的原话是“ 伪代码 pseudo-code ”,这样,他们就能更加轻松自然地表达这台“ 逻辑理论机器 Logic Theory Machine ”的底层逻辑了 5 。这门语言叫做 IPL,即“ 信息处理语言 Information Processing Language ”;比起我们现在认知中的编程语言,它更像是一种高层次的汇编语言方言。 纽厄尔和西蒙提到,当时人们开发的其它“伪代码”都抓着标准数学符号不放 —— 也许他们指的是 Fortran 6 ;与此不同的是,他们的语言使用成组的符号方程来表示命题演算中的语句。通常,用 IPL 写出来的程序会调用一系列的汇编语言宏,以此在这些符号方程列表中对表达式进行变换和求值。

麦卡锡认为,一门实用的编程语言应该像 Fortran 那样使用代数表达式;因此,他并不怎么喜欢 IPL 7 。然而,他也认为,在给人工智能领域的一些问题建模时,符号列表会是非常好用的工具 —— 而且在那些涉及演绎的问题上尤其有用。麦卡锡的渴望最终被诉诸行动;他要创造一门代数的列表处理语言 —— 这门语言会像 Fortran 一样使用代数表达式,但拥有和 IPL 一样的符号列表处理能力。

当然,今日的 Lisp 可不像 Fortran。在会议之后的几年中,麦卡锡关于“理想的列表处理语言”的见解似乎在逐渐演化。到 1957 年,他的想法发生了改变。他那时候正在用 Fortran 编写一个能下国际象棋的程序;越是长时间地使用 Fortran ,麦卡锡就越确信其设计中存在不当之处,而最大的问题就是尴尬的 IF 声明 8 。为此,他发明了一个替代品,即条件表达式 true;这个表达式会在给定的测试通过时返回子表达式 A ,而在测试未通过时返回子表达式 B而且,它只会对返回的子表达式进行求值。在 1958 年夏天,当麦卡锡设计一个能够求导的程序时,他意识到,他发明的 true 条件表达式让编写递归函数这件事变得更加简单自然了 9 。也是这个求导问题让麦卡锡创造了 maplist 函数;这个函数会将其它函数作为参数并将之作用于指定列表的所有元素 10 。在给项数多得叫人抓狂的多项式求导时,它尤其有用。

然而,以上的所有这些,在 Fortran 中都是没有的;因此,在 1958 年的秋天,麦卡锡请来了一群学生来实现 Lisp。因为他那时已经成了一名麻省理工助教,所以,这些学生可都是麻省理工的学生。当麦卡锡和学生们最终将他的主意变为能运行的代码时,这门语言得到了进一步的简化。这之中最大的改变涉及了 Lisp 的语法本身。最初,麦卡锡在设计语言时,曾经试图加入所谓的 “M 表达式”;这是一层语法糖,能让 Lisp 的语法变得类似于 Fortran。虽然 M 表达式可以被翻译为 S 表达式 —— 基础的、“用圆括号括起来的列表”,也就是 Lisp 最著名的特征 —— 但 S 表达式事实上是一种给机器看的低阶表达方法。唯一的问题是,麦卡锡用方括号标记 M 表达式,但他的团队在麻省理工使用的 IBM 026 键盘打孔机的键盘上根本没有方括号 11 。于是 Lisp 团队坚定不移地使用着 S 表达式,不仅用它们表示数据列表,也拿它们来表达函数的应用。麦卡锡和他的学生们还作了另外几样改进,包括将数学符号前置;他们也修改了内存模型,这样 Lisp 实质上就只有一种数据类型了 12

到 1960 年,麦卡锡发表了他关于 Lisp 的著名论文,《用符号方程表示的递归函数及它们的机器计算》。那时候,Lisp 已经被极大地精简,而这让麦卡锡意识到,他的作品其实是“一套优雅的数学系统”,而非普通的编程语言 13 。他后来这么写道,对 Lisp 的许多简化使其“成了一种描述可计算函数的方式,而且它比图灵机或者一般情况下用于递归函数理论的递归定义更加简洁” 14 。在他的论文中,他不仅使用 Lisp 作为编程语言,也将它当作一套用于研究递归函数行为方式的表达方法。

通过“从一小撮规则中逐步实现出 Lisp”的方式,麦卡锡将这门语言介绍给了他的读者。后来,保罗·格雷厄姆在短文《 Lisp 之根 The Roots of Lisp 》中用更易读的语言回顾了麦卡锡的步骤。格雷厄姆只用了七种原始运算符、两种函数写法,以及使用原始运算符定义的六个稍微高级一点的函数来解释 Lisp。毫无疑问,Lisp 的这种只需使用极少量的基本规则就能完整说明的特点加深了其神秘色彩。格雷厄姆称麦卡锡的论文为“使计算公理化”的一种尝试 15 。我认为,在思考 Lisp 的魅力从何而来时,这是一个极好的切入点。其它编程语言都有明显的人工构造痕迹,表现为 Whiletypedefpublic static void 这样的关键词;而 Lisp 的设计却简直像是纯粹计算逻辑的鬼斧神工。Lisp 的这一性质,以及它和晦涩难懂的“递归函数理论”的密切关系,使它具备了获得如今声望的充分理由。

理论 B:属于未来的机器

Lisp 诞生二十年后,它成了著名的《 黑客词典 Hacker’s Dictionary 》中所说的,人工智能研究的“母语”。Lisp 在此之前传播迅速,多半是托了语法规律的福 —— 不管在怎么样的电脑上,实现 Lisp 都是一件相对简单直白的事。而学者们之后坚持使用它乃是因为 Lisp 在处理符号表达式这方面有巨大的优势;在那个时代,人工智能很大程度上就意味着符号,于是这一点就显得十分重要。在许多重要的人工智能项目中都能见到 Lisp 的身影。这些项目包括了 SHRDLU 自然语言程序Macsyma 代数系统ACL2 逻辑系统

然而,在 1970 年代中期,人工智能研究者们的电脑算力开始不够用了。PDP-10 就是一个典型。这个型号在人工智能学界曾经极受欢迎;但面对这些用 Lisp 写的 AI 程序,它的 18 位地址空间一天比一天显得吃紧 16 。许多的 AI 程序在设计上可以与人互动。要让这些既极度要求硬件性能、又有互动功能的程序在分时系统上优秀发挥,是很有挑战性的。麻省理工的 彼得·杜奇 Peter Deutsch 给出了解决方案:那就是针对 Lisp 程序来特别设计电脑。就像是我那关于 Chaosnet 的上一篇文章所说的那样,这些 Lisp 计算机 Lisp machines 会给每个用户都专门分配一个为 Lisp 特别优化的处理器。到后来,考虑到硬核 Lisp 程序员的需求,这些计算机甚至还配备上了完全由 Lisp 编写的开发环境。在当时那样一个小型机时代已至尾声而微型机的繁盛尚未完全到来的尴尬时期,Lisp 计算机就是编程精英们的“高性能个人电脑”。

有那么一会儿,Lisp 计算机被当成是未来趋势。好几家公司雨后春笋般出现,追着赶着要把这项技术商业化。其中最成功的一家叫做 Symbolics,由麻省理工 AI 实验室的前成员创立。上世纪八十年代,这家公司生产了所谓的 3600 系列计算机,它们当时在 AI 领域和需要高性能计算的产业中应用极广。3600 系列配备了大屏幕、位图显示、鼠标接口,以及强大的图形与动画软件。它们都是惊人的机器,能让惊人的程序运行起来。例如,之前在推特上跟我聊过的机器人研究者 Bob Culley,就能用一台 1985 年生产的 Symbolics 3650 写出带有图形演示的寻路算法。他向我解释说,在 1980 年代,位图显示和面向对象编程(能够通过 Flavors 扩展)在 Lisp 计算机上使用)都刚刚出现。Symbolics 站在时代的最前沿。

Bob Culley 的寻路程序。

Bob Culley 的寻路程序。

而以上这一切导致 Symbolics 的计算机奇贵无比。在 1983 年,一台 Symbolics 3600 能卖 111,000 美金 16 。所以,绝大部分人只可能远远地赞叹 Lisp 计算机的威力和操作员们用 Lisp 编写程序的奇妙技术。不止他们赞叹,从 1979 年到 1980 年代末,Byte 杂志曾经多次提到过 Lisp 和 Lisp 计算机。在 1979 年八月发行的、关于 Lisp 的一期特别杂志中,杂志编辑激情洋溢地写道,麻省理工正在开发的计算机配备了“大坨大坨的内存”和“先进的操作系统” 17 ;他觉得,这些 Lisp 计算机的前途是如此光明,以至于它们的面世会让 1978 和 1977 年 —— 诞生了 Apple II、Commodore PET 和 TRS-80 的两年 —— 显得黯淡无光。五年之后,在 1985 年,一名 Byte 杂志撰稿人描述了为“复杂精巧、性能强悍的 Symbolics 3670”编写 Lisp 程序的体验,并力劝读者学习 Lisp,称其为“绝大数人工智能工作者的语言选择”,和将来的通用编程语言 18

我问过 保罗·麦克琼斯 Paul McJones (他在 山景城 Mountain View 计算机历史博物馆 Computer History Museum 做了许多 Lisp 的保护工作),人们是什么时候开始将 Lisp 当作高维生物的赠礼一样谈论的呢?他说,这门语言自有的性质毋庸置疑地促进了这种现象的产生;然而,他也说,Lisp 上世纪六七十年代在人工智能领域得到的广泛应用,很有可能也起到了作用。当 1980 年代到来、Lisp 计算机进入市场时,象牙塔外的某些人由此接触到了 Lisp 的能力,于是传说开始滋生。时至今日,很少有人还记得 Lisp 计算机和 Symbolics 公司;但 Lisp 得以在八十年代一直保持神秘,很大程度上要归功于它们。

理论 C:学习编程

1985 年,两位麻省理工的教授, 哈尔·阿伯尔森 Harold Hal Abelson 杰拉尔德·瑟斯曼 Gerald Sussman ,外加瑟斯曼的妻子 朱莉·瑟斯曼 Julie Sussman ,出版了一本叫做《 计算机程序的构造和解释 Structure and Interpretation of Computer Programs 》的教科书。这本书用 Scheme(一种 Lisp 方言)向读者们示范了如何编程。它被用于教授麻省理工入门编程课程长达二十年之久。出于直觉,我认为 SICP(这本书的名字通常缩写为 SICP)倍增了 Lisp 的“神秘要素”。SICP 使用 Lisp 描绘了深邃得几乎可以称之为哲学的编程理念。这些理念非常普适,可以用任意一种编程语言展现;但 SICP 的作者们选择了 Lisp。结果,这本阴阳怪气、卓越不凡、吸引了好几代程序员(还成了一种奇特的模因)的著作臭名远扬之后,Lisp 的声望也顺带被提升了。Lisp 已不仅仅是一如既往的“麦卡锡的优雅表达方式”;它现在还成了“向你传授编程的不传之秘的语言”。

SICP 究竟有多奇怪这一点值得好好说;因为我认为,时至今日,这本书的古怪之处和 Lisp 的古怪之处是相辅相成的。书的封面就透着一股古怪。那上面画着一位朝着桌子走去,准备要施法的巫师或者炼金术士。他的一只手里抓着一副测径仪 —— 或者圆规,另一只手上拿着个球,上书“eval”和“apply”。他对面的女人指着桌子;在背景中,希腊字母 λ (lambda)漂浮在半空,释放出光芒。

SICP 封面上的画作

SICP 封面上的画作。

说真的,这上面画的究竟是怎么一回事?为什么桌子会长着动物的腿?为什么这个女人指着桌子?墨水瓶又是干什么用的?我们是不是该说,这位巫师已经破译了宇宙的隐藏奥秘,而所有这些奥秘就蕴含在 eval/apply 循环和 Lambda 演算之中?看似就是如此。单单是这张图片,就一定对人们如今谈论 Lisp 的方式产生了难以计量的影响。

然而,这本书的内容通常并不比封面正常多少。SICP 跟你读过的所有计算机科学教科书都不同。在引言中,作者们表示,这本书不只教你怎么用 Lisp 编程 —— 它是关于“现象的三个焦点:人的心智、复数的计算机程序,和计算机”的作品 19 。在之后,他们对此进行了解释,描述了他们对如下观点的坚信:编程不该被当作是一种计算机科学的训练,而应该是“ 程序性认识论 procedural epistemology ”的一种新表达方式 20 。程序是将那些偶然被送入计算机的思想组织起来的全新方法。这本书的第一章简明地介绍了 Lisp,但是之后的绝大部分都在讲述更加抽象的概念。其中包括了对不同编程范式的讨论,对于面向对象系统中“时间”和“一致性”的讨论;在书中的某一处,还有关于通信的基本限制可能会如何带来同步问题的讨论 —— 而这些基本限制在通信中就像是光速不变在相对论中一样关键 21 。都是些高深难懂的东西。

以上这些并不是说这是本糟糕的书;这本书其实棒极了。在我读过的所有作品中,这本书对于重要的编程理念的讨论是最为深刻的;那些理念我琢磨了很久,却一直无力用文字去表达。一本入门编程教科书能如此迅速地开始描述面向对象编程的根本缺陷,和函数式语言“将可变状态降到最少”的优点,实在是一件让人印象深刻的事。而这种描述之后变为了另一种震撼人心的讨论:某种(可能类似于今日的 RxJS 的)流范式能如何同时具备两者的优秀特性。SICP 用和当初麦卡锡的 Lisp 论文相似的方式提纯出了高级程序设计的精华。你读完这本书之后,会立即想要将它推荐给你的程序员朋友们;如果他们找到这本书,看到了封面,但最终没有阅读的话,他们就只会记住长着动物腿的桌子上方那神秘的、根本的、给予魔法师特殊能力的、写着 eval/apply 的东西。话说回来,书上这两人的鞋子也让我印象颇深。

然而,SICP 最重要的影响恐怕是,它将 Lisp 由一门怪语言提升成了必要的教学工具。在 SICP 面世之前,人们互相推荐 Lisp,以学习这门语言为提升编程技巧的途径。1979 年的 Byte 杂志 Lisp 特刊印证了这一事实。之前提到的那位编辑不仅就麻省理工的新 Lisp 计算机大书特书,还说,Lisp 这门语言值得一学,因为它“代表了分析问题的另一种视角” 22 。但 SICP 并未只把 Lisp 作为其它语言的陪衬来使用;SICP 将其作为入门语言。这就暗含了一种论点,那就是,Lisp 是最能把握计算机编程基础的语言。可以认为,如今的程序员们彼此怂恿“在死掉之前至少试试 Lisp”的时候,他们很大程度上是因为 SICP 才这么说的。毕竟,编程语言 Brainfuck 想必同样也提供了“分析问题的另一种视角”;但人们学习 Lisp 而非学习 Brainfuck,那是因为他们知道,前者的那种 Lisp 视角在二十年中都被看作是极其有用的,有用到麻省理工在给他们的本科生教其它语言之前,必然会先教 Lisp。

Lisp 的回归

在 SICP 出版的同一年, 本贾尼·斯特劳斯特卢普 Bjarne Stroustrup 发布了 C++ 语言的首个版本,它将面向对象编程带到了大众面前。几年之后,Lisp 计算机的市场崩盘,AI 寒冬开始了。在下一个十年的变革中, C++ 和后来的 Java 成了前途无量的语言,而 Lisp 被冷落,无人问津。

理所当然地,确定人们对 Lisp 重新燃起热情的具体时间并不可能;但这多半是保罗·格雷厄姆发表他那几篇声称 Lisp 是首选入门语言的短文之后的事了。保罗·格雷厄姆是 Y-Combinator 的联合创始人和《Hacker News》的创始者,他这几篇短文有很大的影响力。例如,在短文《 胜于平庸 Beating the Averages 》中,他声称 Lisp 宏使 Lisp 比其它语言更强。他说,因为他在自己创办的公司 Viaweb 中使用 Lisp,他得以比竞争对手更快地推出新功能。至少,一部分程序员被说服了。然而,庞大的主流程序员群体并未换用 Lisp。

实际上出现的情况是,Lisp 并未流行,但越来越多 Lisp 式的特性被加入到广受欢迎的语言中。Python 有了列表推导式。C# 有了 Linq。Ruby……嗯,Ruby 是 Lisp 的一种。就如格雷厄姆之前在 2001 年提到的那样,“在一系列常用语言中所体现出的‘默认语言’正越发朝着 Lisp 的方向演化” 23 。尽管其它语言变得越来越像 Lisp,Lisp 本身仍然保留了其作为“很少人了解但是大家都该学的神秘语言”的特殊声望。在 1980 年,Lisp 的诞生二十周年纪念日上,麦卡锡写道,Lisp 之所以能够存活这么久,是因为它具备“编程语言领域中的某种近似局部最优” 24 。这句话并未充分地表明 Lisp 的真正影响力。Lisp 能够存活超过半个世纪之久,并非因为程序员们一年年地勉强承认它就是最好的编程工具;事实上,即使绝大多数程序员根本不用它,它还是存活了下来。多亏了它的起源和它的人工智能研究用途,说不定还要多亏 SICP 的遗产,Lisp 一直都那么让人着迷。在我们能够想象上帝用其它新的编程语言创造世界之前,Lisp 都不会走下神坛。


via: https://twobithistory.org/2018/10/14/lisp.html

作者:Two-Bit History 选题:lujun9972 译者:Northurland 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出


  1. John McCarthy, “History of Lisp”, 14, Stanford University, February 12, 1979, accessed October 14, 2018, http://jmc.stanford.edu/articles/lisp/lisp.pdf
  2. Paul Graham, “The Roots of Lisp”, 1, January 18, 2002, accessed October 14, 2018, http://languagelog.ldc.upenn.edu/myl/llog/jmc.pdf.
  3. Martin Childs, “John McCarthy: Computer scientist known as the father of AI”, The Independent, November 1, 2011, accessed on October 14, 2018, https://www.independent.co.uk/news/obituaries/john-mccarthy-computer-scientist-known-as-the-father-of-ai-6255307.html.
  4. Lisp Bulletin History. http://www.artinfo-musinfo.org/scans/lb/lb3f.pdf
  5. Allen Newell and Herbert Simon, “Current Developments in Complex Information Processing,” 19, May 1, 1956, accessed on October 14, 2018, http://bitsavers.org/pdf/rand/ipl/P-850_Current_Developments_In_Complex_Information_Processing_May56.pdf.
  6. ibid.
  7. Herbert Stoyan, “Lisp History”, 43, Lisp Bulletin #3, December 1979, accessed on October 14, 2018, http://www.artinfo-musinfo.org/scans/lb/lb3f.pdf
  8. McCarthy, “History of Lisp”, 5.
  9. ibid.
  10. McCarthy “History of Lisp”, 6.
  11. Stoyan, “Lisp History”, 45
  12. McCarthy, “History of Lisp”, 8.
  13. McCarthy, “History of Lisp”, 2.
  14. McCarthy, “History of Lisp”, 8.
  15. Graham, “The Roots of Lisp”, 11.
  16. Guy Steele and Richard Gabriel, “The Evolution of Lisp”, 22, History of Programming Languages 2, 1993, accessed on October 14, 2018, http://www.dreamsongs.com/Files/HOPL2-Uncut.pdf.[↩](#fnref16)[↩sup1/sup](#fnref16:1)
  17. Carl Helmers, “Editorial”, Byte Magazine, 154, August 1979, accessed on October 14, 2018, https://archive.org/details/byte-magazine-1979-08/page/n153.
  18. Patrick Winston, “The Lisp Revolution”, 209, April 1985, accessed on October 14, 2018, https://archive.org/details/byte-magazine-1985-04/page/n207.
  19. Harold Abelson, Gerald Jay. Sussman, and Julie Sussman, Structure and Interpretation of Computer Programs (Cambridge, Mass: MIT Press, 2010), xiii.
  20. Abelson, xxiii.
  21. Abelson, 428.
  22. Helmers, 7.
  23. Paul Graham, “What Made Lisp Different”, December 2001, accessed on October 14, 2018, http://www.paulgraham.com/diff.html.
  24. John McCarthy, “Lisp—Notes on its past and future”, 3, Stanford University, 1980, accessed on October 14, 2018, http://jmc.stanford.edu/articles/lisp20th/lisp20th.pdf.