Lisp
定义
Lisp 指一个编程语言家族,而不是某一个单一语言;过去的写法为 LISP,取自英文「列表处理」的缩写[1]。它与其他语言家族最直观的不同在于,几乎所有代码都写成以圆括号包围、元素之间以空白分隔的前缀列表,这类结构被称为 S-表达式[4]。在这种写法中,列表的第一个元素是函数名、宏名、lambda 表达式或特殊算符,其余元素是实际参数,例如取 3 个参数的函数 f 写作 (f arg1 arg2 arg3)[2]。
Lisp 家族内部按变量作用域分成两大支系:一类采用动态作用域,一类采用静态作用域(也称词法作用域);Scheme 与 Common Lisp 默认使用静态作用域,AutoLISP、PicoLisp 等则采用动态作用域[4]。
原理
Lisp 的计算模型建立在少数几个基本操作之上。列表由称为 cons 的单元链接而成,每个 cons 含 car 与 cdr 两个指针,分别指向当前元素与后续链表;树和其他复杂结构也可由 cons 组合表示[4]。求值采取从左到右、由内而外的顺序:遇到形如 (f a1 a2) 的表达式时,先依次求值各参数,再把值传给 f 调用[5]。
代码与数据的同构是 Lisp 能力的来源。源码本身就是列表,因此程序可以在运行时读取、修改和生成另一段程序,这种性质被称为同像性;基于它建立的宏系统允许程序员定义新语法,甚至嵌入面向特定领域的子语言[6]。特殊算符提供控制结构,例如 if 在第一个参数非 nil 时求值第二个参数,否则求值第三个参数;lambda 则用于构造匿名函数[4]。
存储管理由系统自动完成:程序运行中创建的函数、数据与列表由 Lisp 自动分配空间,不再需要的数据所占区域也被自动回收,程序员无需手工处理内存[7]。早期 Lisp 中只有原子与列表两种基本数据类型,原子指数或符号,列表则是元素(原子或列表)的有限有序序列[4]。
发展历程
麦卡锡于 1958 年在麻省理工学院开始设计 Lisp。1958 年 10 月,他发表的技术备忘录首次公开使用 LISP 这一名称,该备忘录面向的目标是构造一种特别适合实现人工智能的语言[3]。据麦卡锡本人 1978 年的回顾,1956 年夏至 1958 年夏是核心思想形成的阶段,1958 年秋至 1962 年则完成了语言实现并将其应用于人工智能问题[8]。
1960 年 4 月,《ACM 通讯》刊出麦卡锡的论文《符号表达式的递归函数及其机器计算,第一部分》,给出了 Lisp 首个版本的完整设计[2]。此后其学生史蒂芬·罗素在 IBM 704 上实现了可运行的 Lisp 解释器;1960 年发布的 LISP I 中,研究生丹尼尔·爱德华兹开发的垃圾回收程序使 Lisp 能在通用计算机上实际运行;1962 年,蒂莫西·哈特与迈克尔·莱文用 Lisp 本身写出了第一个完整的 Lisp 编译器[1]。
1960 年代末至 1980 年代初,多种方言并行出现,包括麻省理工学院人工智能实验室的 Maclisp、BBN 科技公司与 Xerox 的 Interlisp、犹他大学的 Portable Standard Lisp,以及运行于 Lisp 机器上的 ZetaLisp 等[7]。1975 年,杰拉德·萨斯曼与盖伊·史提尔二世开发出使用词法作用域与尾调用优化的 Scheme[1]。1984 年,汇集 Maclisp 等方言成果的 Common Lisp 诞生,并于 1994 年由美国国家标准学会标准化,标准编号为 ANSI INCITS 226-1994[9]。2007 年出现的 Clojure 是较新的方言[10]。
应用
Lisp 在诞生后很快成为人工智能研究中最受欢迎的编程语言[2]。在其上还发展出逻辑程序设计、actor 模型、计算反射等研究方向,Smalltalk 的设计也被认为受到 Lisp 影响[3]。在符号代数、定理证明、机器人规划与 CAD 等领域,Lisp 同样有较多使用[7]。
许多应用程序把 Lisp 方言用作脚本与扩展语言,较知名的有 Emacs 编辑器中的 Emacs Lisp、AutoCAD 中的 AutoLISP 及其后的 Visual Lisp、Audacity 中的 Nyquist 以及 LilyPond 中的 Scheme[6]。GNU 项目在需要可扩展性的新软件中则使用自己的 Scheme 实现 Guile[11]。Common Lisp 的典型用途还包括视觉处理、自然语言处理、规划与符号计算等[12]。
局限
大量而单一的圆括号是 Lisp 与其它语言家族最直接的差别,这种写法常被批评为难以阅读,学生中间流传着「迷失在愚蠢的括号中」一类的戏称[4]。有观点指出,多年来曾多次尝试给 Lisp 加入中缀语法,但多数情况下宏的能力随之损失[13]。
在通用计算机上,Lisp 的运行效率相对较低,数值计算能力也较弱,加之非可视化的编程方式与函数式风格不易为习惯传统语言的开发者接受,这些因素影响了它的推广[7]。Common Lisp 标准自 1994 年确定后核心长期未变,各实现自行提供互不相同的扩展,线程、系统调用等能力往往需要借助可移植性封装库才能跨实现使用[14]。此外,Common Lisp 的并发与不可变性交由程序员自行把握,这一点与后来以不可变数据结构为默认设计的语言形成对照[10]。
参见
参考资料
- Lisp(过去拼写为LISP)是具有悠久历史的计算机编程语言家族,有独特的完全用圆括号的前缀符号表示法[3] [引用日期2026-10-29]
- Lisp (programming language) [引用日期2026-10-29]
- JavaScript disabled [引用日期2026-10-29]
- 大量而单一的使用圆括号,是Lisp与其他编程语言家族最直接明显的差别 [引用日期2026-10-29]
- Common Lisp [引用日期2026-10-29]
- [科普中国]-嵌式Lisp语言解译器 [引用日期2026-10-29]
- 图文详情 - [科普中国]-lisp语言 [引用日期2026-10-29]
- History of LISP [引用日期2026-10-29]
- ANSI INCITS 226-1994 (R1999) [引用日期2026-10-29]
- lisp-vs-clojure-which-is-better-for-functional-development [引用日期2026-10-29]
- gnu.org [引用日期2026-10-29]
- LISP Workshop for Musicians #0 - Bibliography: LISP texts [引用日期2026-10-29]
- Page 2: The Problem with Macros - Advertisement [引用日期2026-10-29]
- stackoverflow.com 上的网页 [引用日期2026-10-29]