# LISP

编程范型 多范型：函数式，过程式，同像性，反射式，元编程 约翰·麦卡锡 史帝芬·羅素, Timothy P. Hart和Mike Levin 1958年，​64年前 动态类型，强类型 Arc, AutoLISP, Clojure, Common Lisp, Emacs Lisp, ISLISP, newLISP, PicoLisp, Racket, Scheme, SKILL, IPL CLU, Dylan, Falcon, Forth, Haskell, Io, Ioke, JavaScript, Julia[1], Logo, Lua, LPC, , ML, , OPS5（英语：OPS5）, Perl, POP-2/11（英语：POP-11）, Python, REBOL, Ruby, Smalltalk, Wolfram语言[2]

Lisp（歷史上拼寫為LISP），是具有悠久歷史的計算機編程語言家族，有獨特和完全用括號的前綴符號表示法[3]。起源於1958年[4]，是現今第二悠久而仍廣泛使用的高階編程語言。只有FORTRAN編程語言比它更早一年[5][6]。Lisp編程語族已經演變出許多種方言。現代最著名的通用編程語種是SchemeCommon LispRacketClojure

Lisp最初創建時受到阿隆佐·邱奇lambda演算的影響[7]，用來作為計算機程序實用的數學表達[8]。因為是早期的高階編程語言之一，它很快成為人工智能研究中最受歡迎的編程語言[9]。在計算機科學領域，Lisp開創了許多先驅概念，包括：树结构自動記憶體管理动态类型条件表达式高階函數遞迴[10]、自主（self-hosting）編譯器[11]讀取﹣求值﹣輸出循環（REPL）[12]

"LISP"名稱源自「列表處理器」（英語：LISt Processor）的縮寫[13]列表是Lisp的主要數據結構之一，Lisp編程代碼也同樣由列表組成。因此，Lisp程序可以把源代碼當作數據結構進行操作，而使用其中的宏系統，開發人員可將自己定義的新語法或領域專用的語言，嵌入在Lisp編程中。

## 歷史

1958年，約翰·麥卡錫麻省理工學院發明了Lisp程式語言。1960年，他在《ACM通讯》發表論文，名為《遞迴函數的符號表達式以及由機器運算的方式，第一部》[14]。在這篇論文中闡述了只要透過一些簡單的運算子，以及借鑒自阿隆佐·邱奇的用於匿名函數的表示法，就可以建立一個具圖靈完備性語言，可用於演算法中。

1955年至1956年間，資訊處理語言被創造出來用於人工智能。它首先使用的列表處理與遞歸概念被用於了Lisp。

### 联系于人工智能

Lisp机器，现存于MIT博物馆英语MIT Museum

### 谱系和方言

#### 历史上的重要方言

• LISP 1[16]，是第一个实现。
• LISP 1.5[26]，是第一个广泛发行的版本，由McCarthy和其他人在MIT开发。如此命名是因为它包含了对最初的LISP 1解释器的改进，但不是LISP 2英语LISP 2规划的那种重大重构。
• Stanford LISP 1.6[27]，是开发的LISP 1.5后继者，广泛的发行于运行TOPS-10操作系统的PDP-10系统。罗宾·米尔纳ML运行在Stanford LISP 1.6下[28]。它被Maclisp和InterLisp所淘汰。
• MACLISP[29]，由MIT的MAC计划开发，MACLISP是LISP 1.5的直接后代。它运行在PDP-10和Multics系统上。MACLISP后来被叫做Maclisp，并通常被提及为MacLisp。在MACLISP中的“MAC”，既无关于Apple的Macintosh，又无关于McCarthy
• Interlisp英语Interlisp[30]，由BBN科技开发，用于运行操作系统的PDP-10系统之上，后来InterLisp-D被Xerox Lisp机器接纳并昵称为西海岸Lisp。还为基于6502的计算机发行了叫做“InterLISP 65”的小型版本。在很长一段时间内，Maclisp和InterLisp相互之间是强有力的竞争者。
• Franz Lisp，起源于加利福尼亚大学伯克利分校的计划，后来由Franz Inc开发。这个名字是Franz Liszt的幽默变形，它不牵涉到Franz Inc后来销售的。
• XLISP，由David Betz开发[31]AutoLISP基于了它。
• Standard Lisp和，是曾被广泛使用和移植的犹他大学开发的版本，特别是用它写成了计算机代数系统。
• ，Symbolics称其变体版本为ZetaLisp，它用在Lisp机器之上，是Maclisp的直接后代。Lisp Machine Lisp对Common Lisp有巨大影响。
• Le Lisp，是一个法国Lisp方言。最早的之一（叫做SOS界面[32]）是用Le Lisp写成的。
• Scheme（1975年版）[33]
• Common Lisp（1984年版）[34]，是通过合并对Maclisp的不同尝试（ZetaLisp、Spice Lisp英语Spice Lisp、和S-1 Lisp英语S-1 Lisp）而创建的方言[35]，也具有来自Scheme方言的实质影响。这个版本的Common Lisp在广泛的平台上都能获得到，从而被众人接受为业界标准[36]，直至ANSI Common Lisp（ANSI X3.226-1994）出版。最广泛传播的Common Lisp子方言是Steel Bank Common Lisp（SBCL）、CMU Common Lisp（CMU-CL）、Clozure OpenMCL（不要混淆于Clojure）、GNU CLISP和；所有这些实现都坚持了后来的ANSI CL标准。
• Dylan，在它的第一个版本中是Scheme和Common Lisp对象系统的混合。
• EuLisp英语EuLisp，尝试开发一个新的高效和整洁的Lisp。
• ISLISP，尝试开发一个新的高效和整洁的Lisp。标准化为ISO/IEC 13816:1997[37]，后来修订为ISO/IEC 13816:2007[38]：《信息技术 – 编程语言，它们的环境和系统软件接口 – 编程语言 ISLISP》。
• IEEE Scheme，IEEE标准1178–1990（停用日期：2019-11-07）[39]
• ANSI Common Lisp（1994年版），是美国国家标准协会（ANSI）的Common Lisp标准 ，由X3J13英语X3J13委员会创建，其章程是[40]：开始于以《》作为基础文档[34]，致力于通过公开的达成共识过程，找到Common Lisp实现的程序可移植性兼容性这个共通问题的解决方案。尽管形式上是ANSI标准，ANSI Common Lisp的实现、销售、使用和影响一直都是世界范围的。
• ACL2，是Common LISP的一个应用式（免于副作用）变体。ACL2既是可以建模计算机系统的编程语言，也是帮助证明这些模型性质的工具。
• ，是一个视频游戏编程语言，由Andy Gavin英语Andy Gavin和团队在顽皮狗开发。它是使用Allegro Common Lisp写成并被用于整个系列游戏的开发。

### 2000年迄今

Scheme社群積極維護了二十多個實作。在2000年代開發了數個有意義的新實作，即ChickenGambit等，Scheme社群廣泛接納了R5RS語言標準[44]。Scheme實作用戶社群增長，需求建立了很多準標準函式庫和Scheme擴展功能。於2003年開始語言標準化過程，在2007年產生了R6RS標準[45]。使用Scheme介紹計算機科學課程的學校似乎有所減少，麻省理工學院的計算機科學入門課程，已經不再使用Scheme[46][47]

## 主要方言

Common LispScheme是Lisp发展的两大主流的代表。这些语言体现了显著不同的设计选择。

Common LispMaclisp的后继者。对它有重要影响的是、Maclisp、S-1 Lisp英语S-1 LispSpice Lisp英语Spice Lisp和Scheme[50]。它拥有用于编程Lisp机器的大型Lisp方言Lisp Machine Lisp的很多特征，但设计上能高效的实现在任何个人计算机或工作站上。Common Lisp是通用编程语言，因而拥有一个大型语言标准，包括很多内建数据类型、函数、宏和其他语言元素，以及一个对象系统，即Common Lisp对象系统。Common Lisp还从Scheme借鉴了特定特征，比如词法作用域词法闭包。Common Lisp实现目标定为不同的平台，比如：LLVM[51]Java虚拟机[52]、x86-64、PowerPC、Alpha、ARM、Motorola 68000和MIPS[53]，和不同的操作系统，比如：Windows、macOS、Linux、Solaris、FreeBSD、NetBSD、OpenBSD、Dragonfly BSD和Heroku[54]

Scheme是一个静态作用域和正当尾递归的Lisp编程语言方言[55]，由Guy L. Steele, Jr.Gerald Jay Sussman发明。它的设计有着异常清晰和简单的语义，和很少的形成表达式的不同方式。它的设计大约比Common Lisp早上一个年代，Scheme是一个相当极简主义的设计。它拥有非常小的标准特征集合，但具有在Common Lisp中未规定的特定实现特征，比如尾递归优化和完全续体。在Scheme中能方便的表达广阔的编程范型，包括指令式、函数式和消息传递风格。Scheme通过一系列的标准，即第n次修订的算法语言Scheme报告，和一系列而持续的演化。

### 标准化的方言

Lisp有官方标准化和业界标准的方言：IEEE Scheme[39]ANSI Common Lisp、ISO ISLISPR5RS SchemeR7RS Scheme

## 语法和语义

### 符号表达式（S-表达式）

Lisp是一个。不同于多数其他语言，在表达式和语句之间不做区分。所有代码和数据都写为表达式。当求值一个表达式的时候，它产生一个值（在Common Lisp中可能有多个值），它可以接着被嵌入到其他表达式中。每个值都可以是任何数据类型的。

McCarthy的1958年论文介入两种类型的语法：符号表达式即S-表达式或sexps，它镜像了代码和数据的内部表示；和元表达式即M-表达式英语M-expression，它表达S-表达式的函数。M-表达式从未得到青睐，几乎所有今天的Lisp都使用S-表达式来操纵代码和数据二者。

### 列表

* (list 1 2 (quote foo))
(1 2 FOO)

* (list 1 2 (list 3 4))
(1 2 (3 4))

### 算符

* (+ 1 2 3 4)
10

Lisp没有在Algol派生语言中实现的那样的算符概念。在Lisp中算术算符是可变参数函数（或多元函数），能够接受任何数目的实际参数。C-风格的++增加算符，有时在名字incf之下实现，给出的语法是：

* (setq x 0)
0

* (incf x)
1

* (if nil
(list 1 2 "foo")
(list 3 4 "bar"))
(3 4 "bar")

Lisp还提供逻辑算符andornotandor算符进行短路求值，并分别返回它们的第一个nil或非nil实际参数：

* (or (and "zero" nil "never") "James" 'task 'time)
"James"

### Lambda表达式和函数定义

* (lambda (arg) (+ arg 1))
#<FUNCTION (LAMBDA (ARG)) {5344B3FB}>

* ((lambda (arg) (+ arg 1)) 5)
6

* (defun foo (a b c d) (+ a b c d))
FOO

(defun f (a) b...)在全局环境中定义一个名为f的新函数。它在概念上类似于表达式：

* (setf (fdefinition 'f) #'(lambda (a) (block f b...)))
#<FUNCTION (LAMBDA (A)) {5344BA1B}>

### 作用域和闭包

Lisp家族按变量作用域分裂为两大支系，分别使用动态作用域[62]，或使用静态（也叫做词法）作用域[63]SchemeCommon LispClojure缺省使用静态作用域，而AutoLISPPicoLisp[64]newLISP[65]使用动态作用域。Emacs Lisp自从Emacs版本24.1起使用动态和词法作用域二者[66]

### cons和列表

Lisp列表被实现为单向链表[67]。这个链表的每个单元都叫做cons（在Scheme中叫做pair），它构成自两个指针，分别叫做car英语CAR and CDRcdr英语CAR and CDR

#### 列表处理过程

Lisp提供很多内建的过程，用来访问和控制列表。列表可以直接用list过程创建，它接受任何数目的实际参数，并返回这些实际参数的列表：

* (list 1 2 'a 3)
(1 2 A 3)

* (list 1 '(2 3) 4)
(1 (2 3) 4)

* (cons 1 '(2 3))
(1 2 3)

* (cons '(1 2) '(3 4))
((1 2) 3 4)

append过程将两个（或更多）列表相互附加。由于Lisp列表是链表，附加两个列表有渐进时间复杂度 ${\displaystyle O(n)}$

* (append '(1 2) '(3 4))
(1 2 3 4)

* (append '(1 2 3) '() '(a) '(5 6))
(1 2 3 A 5 6)

#### 共享结构

Lisp列表，作为单向链表，可以相互共享结构。就是说，两个列表可以有相同的尾部，或者最终的cons序列。例如，在执行下列Common Lisp代码之后：

* (setf foo (list 'a 'b 'c))
(A B C)

* (setf bar (cons 'x (cdr foo)))
(X B C)

* (setf (third foo) 'goose)
GOOSE

* bar
(X B GOOSE)

### 自求值形式和引述

Lisp求值用户录入的表达式。符号和列表求值为某个其他（通常更简单的）表达式，例如：一个符号求值为它指名的变量的值；(+ 2 3)求值为5。但是，多数其他形式求值为其自身：如果录入5到Lisp中，它返回5

Common Lisp和Scheme二者还支持“反引述”（backquote）算符（在Scheme中叫做准引述英语quasiquote），这时录入`字符（重音符）。它几乎同于普通引述，除了它允许表达式被求值，并将它们的值插入到引述列表之中，这些表达式标记了逗号,表示去引述，或逗号-at,@表示拼接算符。如果变量snue有值(bar baz)，则`(foo ,snue)求值为(foo (bar baz))，而`(foo ,@snue)求值为(foo bar baz)。反引述经常用于定义宏展开[69][70]

* (defun should-be-constant ()
'(one two three))
SHOULD-BE-CONSTANT

* (let ((stuff (should-be-constant)))
(setf (third stuff) 'bizarre))
BIZARRE

* (should-be-constant)
(ONE TWO BIZARRE)

### 控制结构

Lisp最初有很少的控制结构，但是在语言演化期间却增加了很多。Lisp的最初条件算符cond，是后来的if-then-else结构的先驱。

Scheme方言的编程者经常使用尾递归表达循环。Scheme在学术计算机科学中的通行性，导致了一些学生相信尾递归是在Lisp中书写迭代的唯一的或最常用的方式，但是这是不正确的。所有常见的Lisp方言都有指令式风格的迭代构造，从Scheme的do循环到Common Lisp的复杂的loop表达式。此外，使得这成为客观上而非主观上的一件事的关键要点，是Scheme对尾递归的处理提出了特殊要求，Scheme通常鼓励使用尾递归的原因，是语言定义明确的支持了这种实践。与之相反，ANSI Common Lisp不要求常称为尾递归消除的这种优化[71]。因此，不鼓励将尾递归风格作为使用更传统的迭代构造（比如dodolistloop）的替代品[72]。在Common Lisp中不只是风格偏好的问题，而是潜在的效率问题，因为在Common Lisp中明显的尾递归可能未被编译为简单的jump；和程序正确性问题，因为在Common Lisp中尾递归可能增加栈的使用而有堆栈溢出风险。

Common Lisp和Scheme二者都有非局部控制流程算符。在这些算符中的不同是在这两种方言之间最深的差异。Scheme使用call/cc过程支持可重入的续体，它允许一个程序保存（并在将来恢复）执行中的特定位置。Common Lisp不支持可重入的续体，但是支持处理逃脱续体的一些方式。

* (mapcar #'+ '(1 2 3 4 5) '(10 20 30 40 50))
(11 22 33 44 55)

### 程序代码的列表结构

Lisp利用这一点来实现了一个非常强力的系统。就像其他宏语言比如C，一个宏返回可以接着被编译的代码。但是不同于C的宏，Lisp的宏是函数因而可以利用Lisp的全部能力。

### 求值和读取–求值–打印循环

Lisp语言经常被以交互式命令行来使用，它还可以结合入集成开发环境（IDE）。用户在命令行录入表达式，或指示IDE将它们传送给Lisp系统。Lisp读取录入的表达式，求值它们，并打印结果。为此，Lisp命令行被叫做读取﹣求值﹣输出循环（REPL）。

REPL的基本操作描述如下。这是一个简化的描述，省略了很多真实Lisp的元素，比如引述和宏。

eval函数求值数据，返回零或多个其他Lisp数据作为结果。求值不必然意味着解释；一些Lisp系统编译所有的表达式为机器代码。但将求值描述为解释是很简单的：要求值其car指名一个函数的一个列表，eval首先求值在它的cdr中的每个实际参数，接着应用这个函数于这些实际参数。在这个案例中，这个函数是加法，而应用它于实际参数列表(1 2)产生答案3。这是这个求值的结果。

print函数的工作是将输入表示给用户。对于简单结果比如3这是平凡的。求值为一段列表结构的一个表达式会要求print遍历这个列表并将结果输出为一个S-表达式。

Lisp REPL典型的也提供输入编辑、输入历史、错误处理和到调试器的接口。

Lisp通常使用及早求值。在Common Lisp中，实际参数以应用式次序（最左最内为先）求值，而在Scheme中实际参数的次序是未定义的，为编译器优化留下了余地[74]

## 原始运算

Paul GrahamJohn McCarthy的最初论文中提炼出如下7个原始运算[75]

### quote

(quote x)返回x，我们简记为'x

* (quote a)
A

* 'a
A

* (quote (a b c))
(A B C)

quote寫成'只是一種語法糖

### atom

(atom x)x是一个atom或者空的list时返回原子t，否则返回NIL。在Common Lisp中我们习惯用原子t列表示真，而用空列表()NIL列表示假。例如：

* (atom 'a)
T

* (atom '(a b c))
NIL

* (atom '())
T

* (atom (atom 'a))
T

* (atom '(atom 'a))
NIL

### eq

(eq x y)xy指向相同的对象的时候返回t，否则返回NIL，例如：

* (eq 'a 'a)
T

* (eq 'a 'b)
NIL

* (eq '() '())
T

* (eq '(a b c) '(a b c))
NIL

### car

(car x)要求x是一个列表，它返回x中的第一个元素，例如：

* (car '(a b))
A

### cdr

(cdr x)同样要求x是一个列表，它返回x中除第一个元素之外的所有元素组成的列表，例如：

* (cdr '(a b c))
(B C)

### cons

cons x y预期y的值是一个列表，并且返回包含x的值和随后y的值的那些元素的一个列表，例如：

* (cons 'a 'b)
(A . B)

* (cons 'a (cons 'b 'c))
(A B . C)

* (cons 'a  (cons 'b ()))
(A B)

* (cons 'a (cons 'b (cons 'c ())))
(A B C)

### cond

(cond (p1 e1) ...(pn en))的求值规则如下：对“条件列表达式p”依次求值，直到有一个返回t。如果能找到这样的p列表达式，相应的“结果列表达式e”的值，作为整个cond列表达式的返回值。例如：

* (cond ((eq 'a 'b) 'first)  ((atom 'a)  'second))
SECOND

## 範例

### Hello World!

Scheme Common Lisp Clojure
;; 显示过程在屏幕中打印字符串
;; 并返回未规定值
(display "Hello, world!")

;; 定义过程hello-world
(define (hello-world)
(display "Hello, world!"))

;; 调用过程hello-world
(hello-world)
;; 格式化函数在第一个参数是t时,
;; 在屏幕中打印字符串，并返回NIL
(format t "hello, world!")

;; 定义函数hello-world
(defun hello-world ()
(format t "hello, world!"))

;; 调用函数hello-world
(hello-world)
;; 打印函数在屏幕中打印字符串
;; 并返回nil
(print "hello, world!")

;; 定义函数hello-world
(defn hello-world []
(print "hello, world!"))

;; 调用函数hello-world
(hello-world)

### 阶乘

Lisp语法自然的适合于递归。数学问题比如递归定义集合的枚举，在这种表示法中表达是很容易的。例如，要求值一个数的阶乘

(defun factorial (n)
(if (zerop n) 1
(* n (factorial (1- n)))))

(defun factorial (n &optional (acc 1))
(if (zerop n) acc
(factorial (1- n) (* acc n))))

(defun factorial (n)
(loop for i from 1 to n
for fac = 1 then (* fac i)
finally (return fac)))

### 反转列表

(defun -reverse (list)
(let ((return-value))
(dolist (e list) (push e return-value))
return-value))

## 对象系统

• Common Lisp对象系统（CLOS），是ANSI Common Lisp内在的一部份。CLOS衍生自New Flavors和CommonLOOPS。ANSI Common Lisp是第一个标准化的面向对象编程语言（1994, ANSI X3J13）。
• ObjectLisp[76]或，用于和早期版本的Macintosh Common Lisp。
• LOOPS（Lisp面向对象编程系统）和后来的。
• ，建造于MIT，它的后代是New Flavors（由Symbolics英语Symbolics开发）。
• KR（知识表达），它是用来辅助书写Common Lisp的GUI库Garnet的基于的对象系统。
• （KEE）使用叫做UNITS的对象系统并集成入了推理机[77]和（ATMS）。

## 参考文献

1. ^ Introduction. The Julia Manual. Read the Docs. [2016-12-10]. （原始内容存档于2016-04-08）.
2. ^ Wolfram Language Q&A. Wolfram Research. [2016-12-10]. （原始内容存档于2019-05-20）.
3. ^ Edwin D. Reilly. Milestones in computer science and information technology. Greenwood Publishing Group. 2003: 156–157 [2021-10-24]. ISBN 978-1-57356-521-9. （原始内容存档于2020-08-05）.
4. ^ McCarthy, John. History of Lisp (PDF). Artificial Intelligence Laboratory, Stanford University. 12 February 1979 [2021-10-25]. （原始内容 (PDF)存档于2020-11-07）. There were two motivations for developing a language for the IBM 704. First, IBM was generously establishing a New England Computation Center at M.I.T. …… Second, IBM was undertaking to develop a program for proving theorems in plane geometry (based on an idea of Marvin Minsky’s), ……. ……
In connection with IBM’s plane geometry project, Nathaniel Rochester and (on the advice of McCarthy) decided to implement a list processing language within FORTRAN, ……. This work was undertaken by Herbert Gelernter and Carl Gerberich at IBM and led to FLPL, standing for FORTRAN List Processing Language. ……
I spent the summer of 1958 at the IBM Information Research Department at the invitation of Nathaniel Rochester and chose differentiating algebraic expressions as a sample problem. It led to the following innovations beyond FLPL:
a. Writing recursive function definitions using conditional expressions. ……
b. The maplist function that forms a list of applications of a functional argument to the elements of a list. ……
c. To use functions as arguments, one needs a notation for functions, and it seemed natural to use the λ-notation of Church (1941). I didn’t understand the rest of his book, so I wasn’t tempted to try to implement his more general mechanism for defining functions. Church used higher order functionals instead of using conditional expressions. Conditional expressions are much more readily implemented on computers.
d. The recursive definition of differentiation made no provision for erasure of abandoned list structure. ……
The implementation of LISP began in Fall 1958. …… The programs to be hand-compiled were written in an informal notation called intended to resemble FORTRAN as much as possible.
5. ^ SICP: Foreword. （原始内容存档于2001-07-27）. Lisp is a survivor, having been in use for about a quarter of a century. Among the active programming languages only Fortran has had a longer life.
6. ^ Conclusions. [2014-06-04]. （原始内容存档于2014-04-03）.
7. ^ . Some History of Functional Programming Languages (PDF). [2021-10-25]. （原始内容 (PDF)存档于2020-04-15）. LISP was not based on the lambda calculus, despite using the word “LAMBDA” to denote functions. At the time he invented LISP, McCarthy was aware of (Church 1941) but had not studied it. The theoretical model behind LISP was Kleene’s theory of first order recursive functions. (McCarthy made these statements, or very similar ones, in a contribution from the floor at the 1982 ACM symposium on LISP and functional programming in Pittsburgh. No written version of this exists, as far as know.)
. Lambda-Calculus Schemata (PDF). LISP AND SYMBOLIC COMPUTATION: An International Journal, 6, 259–288. 1993 [2021-10-25]. （原始内容 (PDF)存档于2022-03-02）. Pure LISP allows the definition and evaluation of functions over S-expressions. The lambda notation for functional abstraction is borrowed from Church’s lambda calculus, but otherwise there is little similarity between the two systems. Pure LISP has no higher-order functions, and call-by-value evaluation order is implicitly assumed. Two special constructs, conditional expressions and the label operator, allow recursive functions to be defined. Limited as it is, pure LISP is nevertheless powerful enough to express all partial recursive functions and hence provides an adequate basis for a theory of computation.
8. ^ The Art of the Interpreter, or the Modularity Complex (Parts Zero, One, and Two), Part Zero, P. 4. MIT Libraries. [2020-08-01]. hdl:1721.1/6094. （原始内容存档于2021-01-24）.
9. ^ The Top Programming Languages in Artificial Intelligence. Artificial Intelligence. APRO. [2021-02-15]. （原始内容存档于2020-10-30）.
10. ^ John McCarthy, Paul W. Abrahams, Daniel J. Edwards, Timothy P. Hart, Michael I. Levin. LISP 1.5 Programmer's Manual (PDF) 2nd. MIT Press. 1985 [1962] [2021-10-25]. ISBN 0-262-13011-4. （原始内容 (PDF)存档于2021-03-02）. A function can be simply a name. In this case its meaning must be previously understood. A function may be defined by using the lambda notation and establishing a correspondence between the arguments and the variables used in a form. If the function is recursive, it must be given a name by using a label. ……
When a symbol stands for a function, the situation is similar to that in which a symbol stands for an argument. When a function is recursive, it must be given a name. This is done by means of the form LABEL, which pairs the name with the function definition on the a-list. The name is then bound to the function definition, just as a variable is bound to its value.
In actual practice, LABEL is seldom used. It is usually more convenient to attach the name to the definition in a uniform manner. This is done by putting on the property list of the name, the symbol EXPR followed by the function definition. The pseudo-function define used at the beginning of this section accomplishes this. When apply interprets a function represented by an atomic symbol, it searches the p-list of the atomic symbol before searching the current a-list. Thus a define will override a LABEL.
11. ^ Paul Graham. Revenge of the Nerds. [2013-03-14]. （原始内容存档于2019-06-07）.
12. ^ Chisnall, David. Influential Programming Languages, Part 4: Lisp. 2011-01-12 [2021-10-24]. （原始内容存档于2021-03-01）.
13. ^ Jones, Robin; Maynard, Clive; Stewart, Ian. The Art of Lisp Programming. Springer Science & Business Media. December 6, 2012: 2. ISBN 9781447117193.
14. ^ John McCarthy. Recursive functions of symbolic expressions and their computation by machine, Part I. (PDF). Communications of the ACM (ACM New York, NY, USA). 1960, 3 (4): 184–195 [2021-09-23]. doi:10.1145/367177.367199. （原始内容 (PDF)存档于2021-02-19）.
15. ^ David Canfield Smith. MLISP Users Manual (PDF). [2006-10-13]. （原始内容 (PDF)存档于2021-02-26）.
16. John McCarthy; Robert Brayton; Daniel Edwards; ; ; ; Klim Maling; ; Steve Russell. LISP I Programmers Manual (PDF). Boston, Massachusetts: Artificial Intelligence Group, and Research Laboratory. March 1960 [2021-09-23]. （原始内容 (PDF)存档于2022-04-02）.
17. ^ Tim Hart and Mike Levin. AI Memo 39-The new compiler (PDF). [2019-03-18]. （原始内容 (PDF)存档于2020-12-13）.
18. ^ Hart, Timothy P. AIM-057, MACRO Definitions for LISP, Timothy P. Hart. October 1963. hdl:1721.1/6111.
19. ^ Gerald J. Sussman, Guy L. Steele Jr. The Revised Report on SCHEME: A Dialect of LISP. 1978 [2021-10-26]. （原始内容存档于2022-04-06）. SCHEME is a dialect of LISP. It is an expression-oriented, applicative order, interpreter-based language which allows one to manipulate programs as data.
It differs from most current dialects of LISP in that it closes all lambda-expressions in the environment of their definition or declaration, rather than in the execution environment. This has the consequence that variables are normally lexically scoped, as in ALGOL. However, in contrast with ALGOL, SCHEME treats procedures as a first-class data type. They can be the values of variables, the returned values of procedures, and components of data structures.
Another difference from LISP is that SCHEME is implemented in such a way that tail-recursions execute without net growth of the interpreter stack. The effect of this is that a procedure call behaves like a GOTO and thus procedure calls can be used to implement iterations, as in PLASMA.
20. ^ The 36-bit word size of the PDP-6/PDP-10 was influenced by the usefulness of having two Lisp 18-bit pointers in a single word. Peter J. Hurley. The History of TOPS or Life in the Fast ACs. Newsgroupalt.folklore.computers. 18 October 1990 [2021-10-24]. Usenet: 84950@tut.cis.ohio-state.edu. （原始内容存档于2013-05-28）. The PDP-6 project started in early 1963, as a 24-bit machine. It grew to 36 bits for LISP, a design goal.
21. ^ Gerald Jay Sussman, Terry Winograd. Micro-planner Reference Manual. AI Memo No, 203, MIT Project MAC. 1970 [2021-11-13]. （原始内容存档于2008-08-20）.
22. ^ John McCarthy, Paul W. Abrahams, Daniel J. Edwards, Timothy P. Hart, Michael I. Levin. LISP 1.5 Programmer's Manual (PDF) 2nd. MIT Press. 1985 [1962] [2021-10-25]. ISBN 0-262-13011-4. （原始内容 (PDF)存档于2021-03-02）. To define these functions, we use the pseudo-function define. …… A pseudo-function is a function that is executed for its effect on the system in core memory, as well as for its value. define causes these functions to be defined and available within the system. Its value is a list of the functions defined …….
23. . The Revised Maclisp Manual. 1983, 2007 [2021-10-26]. （原始内容存档于2022-03-28）. DEFUN Special Form (DEFUN namespec . definitionspec)
DEFUN offers a way of associating a functional definition with a symbol. …… DEFUN can be used to define both normal functions and special forms (fexprs and macros). ……
;; Normal expr or lexpr function definitions
(DEFUN name bvl . body)

……
If name is a symbol and bvl is a list of symbols which is free of &keywords (to be described below), the definition is an expr or lexpr definition. In Maclisp, this would be essentially equivalent to writing
(DEFPROP name (LAMBDA bvl . body) EXPR).
…… Note also that the keyword EXPR is used for both expr and lexpr definitions. The only distinction between expr and lexpr definitions is whether the bvl is a symbol or a list, but they are specified in the same way and looked up from the same property. ……
A fexpr英语fexpr is a function for which the formal parameters are not evaluated. The form of a fexpr definition is:
(DEFUN name FEXPR (sym) . body).
The lambda expression which describes a fexpr should expect to receive exactly one argument which will be the list of (unevaluated) arguments given in the call to the fexpr, so usually there is only one bound variable (sym) in the bound variable list. ……
DEFUN can also be used to instantiate a MACRO definition. …… The syntax for a macro definition is
(DEFUN name MACRO (sym) . body),
where sym will become bound to the whole macro form to be expanded (including the name). Note that this argument convention is different than fexprs, which only receive the cdr of the call form. ……
DEFUN was introduced into Maclisp in March, 1969. Although now it is recognized as the standard function defining form because it shields the user from the implementational details of how the function is defined ……. ……
DEFPROP Function (DEFPROP sym val indicator)
Gives sym a property called indicator with value val. The arguments are not evaluated. DEFPROP should not be used imbedded in other expressions. It is intended to occur at toplevel to assign properties that are set up once and never changed. In other places, use PUTPROP with three quoted arguments.
24. ^ Gerald J. Sussman, Guy L. Steele Jr..  Scheme: An Interpreter for Extended Lambda Calculus. 维基文库. 1975 （英文）. DEFINE － This is analogous to the MacLISP DEFUN primitive (but note that the LAMBDA must appear explicitly!). It is used for defining a function in the "global environment" permanently, as opposed to LABELS (see below), which is used for temporary definitions in a local environment. DEFINE takes a name and a lambda expression; it closes the lambda expression in the global environment and stores the closure in the LISP value cell of the name (which is a LISP atom).
Gerald J. Sussman, Guy L. Steele Jr. The Revised Report on SCHEME: A Dialect of LISP. 1978 [2021-10-26]. （原始内容存档于2022-04-06）. Atoms which are not atomic symbols (identifiers) evaluate to themselves. Typical examples of such atoms are numbers, arrays, and strings (character arrays). Symbols are treated as identifiers or variables. They may be lexically bound by lambda-expressions. There is a global environment containing values initially have as their values primitive operations such as, for example, CAR, CONS, and PLUS. SCHEME differs from most LISP systems in that the atom CAR is not itself an operation (in the sense of being an invocable object, e.g. a valid first argument to APPLY), but only has one as a value when considered as an identifier.
25. ^ ; . Technical Issues of Separation in Function Cells and Value Cells. Lisp and Symbolic Computation. June 1988, 1 (1): 81–101 [2021-11-01]. S2CID 26716515. doi:10.1007/bf01806178. （原始内容存档于2006-11-13）. In this paper, we shall refer to two abstract dialects of Lisp called Lisp1 and Lisp2.
Lisp1 has a single namespace that serves a dual role as the function namespace and value namespace; that is, its function namespace and value namespace are not distinct. In Lisp1, the functional position of a form and the argument positions of forms are evaluated according to the same rules. Scheme [Rees 1986] and the language being designed by the EuLisp group [Padget 1986] are Lisp1 dialects.
Lisp2 has distinct function and value namespaces. In Lisp2, the rules for evaluation in the functional position of a form are distinct from those for evaluation in the argument positions of the form. Common Lisp is a Lisp2 dialect. ……
Most Lisp dialects adopted a two-namespace approach to the naming problem. To some extent this is because most dialects followed Lisp 1.5 [McCarthy 1965] or dialects derived from Lisp 1.5.
Lisp 1.5 broke symbols into values and functions; values were stored on an , and function on the property lists of symbols. Compiled and interpreted code worked in different ways. ……
MacLisp [Pitman 1983] is a direct descendant of the PDP-6 Lisp and is a Lisp2 dialect. MacLisp uses a sophisticated form of link table, which is made possible by the separation of namespaces. In particular, function-defining functions have controlled access into the places where functions are stored so that the link tables can be correctly maintained. ……
Common Lisp was the result of a compromise between a number of dialects of Lisp, most of them descendants of MacLisp, all of them Lisp2s.
26. ^ John McCarthy, Paul W. Abrahams, Daniel J. Edwards, Timothy P. Hart, Michael I. Levin. LISP 1.5 Programmer's Manual (PDF) 2nd. MIT Press. 1985 [1962] [2021-10-25]. ISBN 0-262-13011-4. （原始内容 (PDF)存档于2021-03-02）.
27. ^ Lynn H. Quam. Stanford LISP 1.6 Manual (PDF). 1969 [2021-12-29]. （原始内容 (PDF)存档于2022-03-03）.
28. ^ The original Edinburgh LCF. 1977 [2021-10-10]. （原始内容存档于2021-10-10）.
29. ^ Maclisp Reference Manual. March 3, 1979 [2021-10-29]. （原始内容存档于2022-03-28）.
30. ^ Teitelman, Warren. InterLisp Reference Manual (PDF). 1974 [2021-10-29]. （原始内容 (PDF)存档于2022-03-03）.
31. ^ Package: lang/lisp/impl/xlisp/. cs.cmu.edu. [2021-10-26]. （原始内容存档于2022-03-31）.
32. ^ Outils de generation d’interfaces : etat de l’art et classification by H. El Mrabet (PDF). [2021-10-24]. （原始内容 (PDF)存档于2017-10-01）.
33. ^ Gerald J. Sussman, Guy L. Steele Jr. SCHEME: An Interpreter for Extended Lambda Calculus. 1975 [2021-10-27]. （原始内容存档于2022-04-17）. Inspired by ACTORS [Greif and Hewitt][Smith and Hewitt], we have implemented an interpreter for a LISP-like language, SCHEME, based on the lambda calculus [Church], but extended for side effects, multiprocessing, and process synchronization. The purpose of this implementation is tutorial. We wish to:
⑴ alleviate the confusion caused by , CONNIVER, etc. by clarifying the embedding of non-recursive control structures in a recursive host language like LISP.
⑵ explain how to use these control structures, independent of such issues as pattern matching and data base manipulation.
⑶ have a simple concrete experimental domain for certain issues of programming semantics and style.
34. Guy L. Steele, Jr., , , , . Common Lisp the Language 1st edition. 1984. ISBN 0-932376-41-X.
35. ^ Steele, Guy L., Jr. Purpose. Common Lisp the Language 2nd edition. 1990 [2021-10-24]. ISBN 0-13-152414-3. （原始内容存档于2021-03-08）.
36. ^ Kantrowitz, Mark; Margolin, Barry. History: Where did Lisp come from?. FAQ: Lisp Frequently Asked Questions 2/7. 20 February 1996 [2021-10-24]. （原始内容存档于2021-03-08）.
37. ^ ISO/IEC 13816:1997. Iso.org. 2007-10-01 [2013-11-15]. （原始内容存档于2016-07-30）.
38. ^ ISO/IEC 13816:2007. Iso.org. 2013-10-30 [2013-11-15]. （原始内容存档于2016-07-30）.
39. IEEE Scheme. IEEE 1178-1990 - IEEE Standard for the Scheme Programming Language. [27 August 2019]. （原始内容存档于2021-03-04）.
40. ^ X3J13 Charter. [2021-10-24]. （原始内容存档于2021-03-05）.
41. ^ The Road To Lisp Survey. [2006-10-13]. （原始内容存档于2006-10-04）.
42. ^ Trends for the Future. Faqs.org. [2013-11-15]. （原始内容存档于2013-06-03）.
43. ^ Weinreb, Daniel. Common Lisp Implementations: A Survey. [4 April 2012]. （原始内容存档于2012-04-21）.
44. ^ The Revised5 Report on the Algorithmic Language Scheme. schemers.org. 1998 [2021-10-24]. （原始内容存档于2007-01-05）.
45. ^ The Revised6 Report on the Algorithmic Language Scheme. 2007 [2021-11-04]. （原始内容存档于2013-06-25）.
46. ^ Why MIT now uses python instead of scheme for its undergraduate CS program. cemerick.com. March 24, 2009 [November 10, 2013]. （原始内容存档于September 17, 2010）.
47. ^ Broder, Evan. The End of an Era. mitadmissions.org. January 8, 2008 [November 10, 2013]. （原始内容存档于2018-08-21）.
48. ^ Clemens Fruhwirth. Liskell － Haskell Semantics with Lisp Syntax (PDF). 2007 [2021-10-25]. （原始内容 (PDF)存档于2022-04-06）.
49. ^ a specification for Bel页面存档备份，存于互联网档案馆）, "a new dialect of Lisp."
50. ^ Chapter 1.1.2, History, ANSI CL Standard
51. ^ [1]页面存档备份，存于互联网档案馆） Clasp is a Common Lisp implementation that interoperates with C++ and uses LLVM for just-in-time compilation (JIT) to native code.
52. ^ [2]页面存档备份，存于互联网档案馆） "Armed Bear Common Lisp (ABCL) is a full implementation of the Common Lisp language featuring both an interpreter and a compiler, running in the JVM"
53. ^ [3] 互联网档案馆存檔，存档日期2018-06-22. Common Lisp Implementations: A Survey
54. ^ [4]页面存档备份，存于互联网档案馆） Comparison of actively developed Common Lisp implementations
55. ^ Gerald J. Sussman, Guy L. Steele Jr. The First Report on Scheme Revisited. 1998 [2021-10-28]. （原始内容存档于2022-04-06）. Sussman had just been studying Algol. He suggested starting with a lexically scoped dialect of Lisp, because that seemed necessary to model the way names could refer to acquaintances in PLASMA. Lexical scoping would allow actors and functions to be created by almost identical mechanisms. Evaluating a form beginning with the word lambda would capture the current variable-lookup environment and create a closure; evaluating a form beginning with the word alpha would also capture the current environment but create an actor. Message passing could be expressed syntactically in the same way as function invocation. The difference between an actor and a function would be detected in the part of the interpreter traditionally known as apply. A function would return a value, but an actor would never return; instead, it would typically invoke a continuation, another actor that it knew about. Our interpreter also provided the necessary primitives for implementing the internal behavior of primitive actors, such as an addition operator that could accept two numbers and a continuation actor. ……
…… This led us to three important ideas:
• First, we realized that all the patterns of control structure that Hewitt had described in terms of actors could equally well be described by the λ-calculus. ……
• Second, we realized that the λ-calculus — a small, simple formalism — could serve as the core of a powerful and expressive programming language. (Lisp had adopted the λ-notation for functions but had failed to support the appropriate behavior for free variables. The original theoretical core of Lisp was recursion equations, not the λ-calculus.) ……
• Third, we realized that in our quest for the “ultimate AI language” we had come full circle. As the MIT school had struggled to find more and more powerful ways to express and manipulate control structure to support heuristic search, we had progressed from Lisp to CONVERT to Planner to Conniver to PLASMA to a simple variation of Lisp!
56. ^ An In-Depth Look at Clojure Collections页面存档备份，存于互联网档案馆）, Retrieved 2012-06-24
57. ^ Clojure rational. [27 August 2019]. （原始内容存档于2016-01-04）. Clojure is a Lisp not constrained by backwards compatibility
58. ^ Script-fu In GIMP 2.4页面存档备份，存于互联网档案馆）, Retrieved 2009-10-29
59. ^ librep页面存档备份，存于互联网档案馆） at Sawfish Wikia, retrieved 2009-10-29
60. ^ The Jargon File - Lisp. [2006-10-13]. （原始内容存档于2021-04-18）.
61. ^ John McCarthy, Paul W. Abrahams, Daniel J. Edwards, Timothy P. Hart, Michael I. Levin. LISP 1.5 Programmer's Manual (PDF) 2nd. MIT Press. 1985 [1962] [2021-10-25]. ISBN 0-262-13011-4. （原始内容 (PDF)存档于2021-03-02）. Special Forms － Normally, eval evaluates the arguments of a function before applying the function itself. Thus if eval is given (CONS X Y), it will evaluate X and Y, and then cons them. But if eval is given (QUOTE X), X should not be evaluated. QUOTE is a special form that prevents its argument from being evaluated.
A special form differs from a function in two ways. Its arguments are not evaluated before the special form sees them. COND, for example, has a very special way of evaluating its arguments by using evcon. The second way which special forms differ from functions is that they may have an indefinite number of arguments. Special forms have indicators on their property lists called FEXPR and FSUBR for LISP-defined forms and machine language coded forms, respectively.
62. ^ John McCarthy, Paul W. Abrahams, Daniel J. Edwards, Timothy P. Hart, Michael I. Levin. LISP 1.5 Programmer's Manual (PDF) 2nd. MIT Press. 1985 [1962] [2021-10-25]. ISBN 0-262-13011-4. （原始内容 (PDF)存档于2021-03-02）. The variables in a lambda expression are dummy or bound variables because systematically changing them does not alter the meaning of the expression. Thus λ[[u;v];v2+u] means the same thing as λ[[x;y];y2+x].
We shall sometimes use expressions in which a variable is not bound by a lambda. For example, in the function of two variables λ[[x;y];xn+yn] the variable n is not bound. This is called a free variable. It may be regarded as a parameter. Unless n has been given a value before trying to compute with this function, the value of the function must be undefined. ……
Free Variables － A variable is bound in a particular function when it occurs in a list of bound variables following the word LAMBDA or PROG. Any variable that is not bound is free. ……
When a variable is used free, it must have been bound by a higher level function. If a program is being run interpretively, and a free variable is used without having bee bound on a higher level, error diagnostic *A 8* will occur.
If the program is being run complied, the diagnostic may not occur, and the variable may have value NIL.
63. ^ Gerald J. Sussman, Guy L. Steele Jr..  Scheme: An Interpreter for Extended Lambda Calculus. 维基文库. 1975 （英文）. There are several important consequences of closing every lambda expression in the environment from which it is passed (i.e., in its "lexical" or "static" environment).
First, the axioms of lambda calculus are automatically preserved. Thus, referential transparency is enforced. This in turn implies that there are no "fluid" variable bindings (as there are in standard stack implementations of LISP such as MacLISP).
Second, the upward [Moses] requires that the environment structure be potentially tree-like.
Finally, the environment at any point in a computation can never be deeper than the lexical depth of the expression being evaluated at that time; i.e., the environment contains bindings only for variables bound in lambdas lexically surrounding the expression being evaluated. This is true even if recursive functions are involved. ……Furthermore, it is not even necessary to scan the environment for the variable, since its value must be in a known position relative to the top of the environment structure; this position can be computed by a compiler at compile time on the basis of lexical scope.

64. ^ Alexander Burger. PicoLisp Frequently Asked Questions. [2021-10-29]. （原始内容存档于2017-08-06）. Why do you use dynamic variable binding? Dynamic binding is very powerful, because there is only one single, dynamically changing environment active all the time. This makes it possible (e.g. for program snippets, interspersed with application data and/or passed over the network) to access the whole application context, freely, yet in a dynamically controlled manner. And (shallow) dynamic binding is the fastest method for a Lisp interpreter.
Lexical binding is more limited by definition, because each environment is deliberately restricted to the visible (textual) static scope within its establishing form. Therefore, most Lisps with lexical binding introduce "special variables" to support dynamic binding as well, and constructs like labels to extend the scope of variables beyond a single function.
In PicoLisp, function definitions are normal symbol values. They can be dynamically rebound like other variables. ……
Are there no problems caused by dynamic binding? You mean the funarg problem, or problems that arise when a variable might be bound to itself? For that reason we have a convention in PicoLisp to use transient symbols (instead of internal symbols) or private internal symbols ……
But with dynamic binding I cannot implement closures! This is not true. Closures are a matter of scope, not of binding.
For a closure it is necessary to build and maintain a separate environment. In a system with lexical bindings, this has to be done at each function call, and for compiled code it is the most efficient strategy anyway, because it is done once by the compiler, and can then be accessed as stack frames at runtime.
For an interpreter, however, this is quite an overhead. So it should not be done automatically at each and every function invocation, but only if needed.
65. ^ Lutz Mueller. Comparison to Common Lisp and Scheme. [2021-10-29]. （原始内容存档于2022-04-06）. Dynamic scoping inside isolated namespaces － newLISP is sometimes criticized for using dynamic scoping and fexprs. …… In newLISP, all variables are dynamically scoped by default. However, by defining a function in its own context, static/lexical scoping can be achieved. In newLISP, several functions and data can share a namespace. By enclosing functions in their own namespace, a lexical closure- like mechanism is achieved. Common Lisp and Scheme are lexically scoped by default and use lambda expressions as the closure mechanism. Common Lisp also offers special variables for dynamic scoping.
The problems of free variables in dynamic scoping can be avoided. In the rare cases when free variables must be used, you can partition code into namespace modules for easier control over free variables. You can then exploit the advantages of dynamic scoping. With dynamic scoping inside lexically-closed namespaces, newLISP combines the best of both scoping worlds.
newLISP has no funarg problem because it follows a simple rule: variables always show the binding of their current environment. When expressions with local variables are entered, newLISP saves the current variable state on a stack and restores it on exit of that expression. In newLISP, not only are function parameters and variables declared with let expressions local, loop variables in all looping expressions are local too.
66. ^ Dynamic Binding Vs Lexical Binding. EmacsWiki. [2021-10-28]. （原始内容存档于2022-05-09）. dynamic － All variable names and their values live in one global table. lexical － Each binding scope (function, let syntax, …) creates a new table of variable names and values, organised in a hierarchy called “the environment”. ……
EmacsLisp as of 24.1 has both dynamic binding and lexical binding. Lexical binding must be enabled explicitly for a file or buffer. Individual variables can be 'defvar'ed to make them “special”, like in CommonLisp.
67. ^ Sebesta, Robert W. "2.4 Functional Programming: LISP";"6.9 List Types";"15.4 The First Functional Programming Language: LISP". Concepts of Programming Languages 10th. Boston, MA, USA: Addison-Wesley. 2012: 47–52;281–284;677–680 [2021-10-23]. ISBN 978-0-13-139531-2. （原始内容 (print)存档于2021-03-08） （英语）.
68. ^ NB: a so-called "dotted list" is only one kind of "improper list". The other kind is the "circular list" where the cons cells form a loop. Typically this is represented using #n=(...) to represent the target cons cell that will have multiple references, and #n# is used to refer to this cons. For instance, (#1=(a b) . #1#) would normally be printed as ((a b) a b) (without circular structure printing enabled), but makes the reuse of the cons cell clear. #1=(a . #1#) cannot normally be printed as it is circular, although (a...) is sometimes displayed, the CDR of the cons cell defined by #1= is itself.
69. ^ CSE 341: Scheme: Quote, Quasiquote, and Metaprogramming. Cs.washington.edu. 1999-02-22 [2013-11-15]. （原始内容存档于2013-08-23）.
70. ^ Alan Bawden. Quasiquotation in Lisp. 1999 [2021-10-29]. （原始内容存档于2021-10-29）.
71. ^
72. ^ 4.3. Control Abstraction (Recursion vs. Iteration) in Tutorial on Good Lisp Programming Style页面存档备份，存于互联网档案馆） by and Peter Norvig, August, 1993.
73. ^ Time of Evaluation - Common Lisp Extensions页面存档备份，存于互联网档案馆）. Gnu.org. Retrieved on 2013-07-17.
74. ^ Gerald J. Sussman, Guy L. Steele Jr. The Revised Report on SCHEME: A Dialect of LISP. 1978. Magic forms are recognized by then presence of a "magic (reserved) word" in the car position of the form. All non-atomic forms which are not magic forms are considered to be combinations. The system has a small initial set of magic words; there is also a mechanism for creating new ones {Note FUNCALL is a Pain}.
A combination is considered to be a list of subforms. These subforms are all evaluated. The first value mub be a procedure; it is applied to the other values to get the value of the combination. There are four important points here:
(1) the procedure Position is always evaluated just like any other position. (This is why the primitive operators are the values of global identifiers.)
(2) the procedure is never "re-evaluated"; if the first subform fails to evaluate to a applicable procedure, it is an error. Thus, unlike most LISP systems, SCHEME always evaluates the first subform of a combination exactly once.
(3) the arguments are all completely evaluated before the procedure is applied; that is, SCHEME, like most LISP systems, is an applicative-order language. Many SCHEME programs exploit this fact.
(4) the argument forms (and procedure form) may in principle be evaluated in any order. This is unlike the usual LISP left-to-right order. (All SCHEME interpreters implemented so far have in fact performed left-to-right evaluation, but we do not wish programs to depend on this fact. Indeed, there are some reasons why a clever interpreter might want to evaluate them right-to-left, e.g. to get things on a stack in the correct order.)
75. ^ Paul Graham. The Roots of Lisp (PDF). 2002 [2021-10-28]. （原始内容 (PDF)存档于2021-10-28）.
76. ^ Daniel G. Bobrow, Kenneth Kahn, Gregor Kiczales, Larry Masinter, Mark Stefik, Frank Zdybel. CommonLoops: Merging Lisp and Object-Oriented Programming. 1986 [2021-10-29]. （原始内容存档于2022-04-06）.
77. ^ "A History and Description of CLOS", by Jim Veitch. Pages 107–158 of Handbook of Programming Languages, Volume IV: Functional and Logic Programming Languages, ed. . 1998 (1st edition), Macmillan Technical Publishing; ISBN 1-57870-011-6