Skip to content

LISP - 基本语法

欢迎来到 Lisp 的世界!本教程将重点介绍 Common Lisp,这是一种功能强大、标准化且支持多范式的编程语言。我们将从基础语法开始,并指导您设置一个现代的开发环境。

为了获得高效的 Lisp 体验,交互式设置至关重要。以下是一个推荐的现代工具链(toolchain):

  • 实现(Implementation):SBCL (Steel Bank Common Lisp) 是一款高性能、开源的编译器。它是初学者和专业开发的绝佳选择。
  • 包管理器(Package Manager):Quicklisp 是 Common Lisp 事实上的包管理器。它允许您通过简单的命令下载和管理数百个开源库。
  • 构建系统(Build System):ASDF (Another System Definition Facility) 是定义 Lisp 源文件如何编译和加载为内聚系统(项目)的标准工具。
  • 编辑器(Editor):具有强大 Lisp 集成的编辑器至关重要。带有 SLIME 或 Sly 的 Emacs 提供了深度交互式的 REPL 驱动体验。此外,带有 Alive 或 SLIMA 等扩展的 VS Code 提供了一种现代替代方案。

Lisp 程序由**S-表达式(S-expressions,Symbolic Expressions,符号表达式)**构建而成,S-表达式有两种形式:

  • 原子(Atoms):原子是除列表之外的任何事物。这包括数字、符号(变量和函数的名称)和字符串。
  • 列表(Lists):列表是原子和/或其它列表的序列,用括号 () 括起来。
123 ; 一个数字
3.14159 ; 一个浮点数
'my-symbol ; 一个符号(常用于变量或函数)
:my-keyword ; 一个关键字(自求值符号)
"Hello, Lisp!" ; 一个字符串
(+ 1 2) ; 表示函数调用的列表
'(a b c) ; 符号列表
(list 1 "two" '(three)) ; 嵌套列表
() ; 空列表,也称为 NIL

Lisp 在**读取-求值-打印循环(Read-Eval-Print Loop,REPL)**上运行。它读取一个 S-表达式,求值(evaluates)它,并打印结果。求值的关键规则是:

  • 符号被视为变量并求值为它们的值。
  • 列表被视为函数调用,其中第一个元素是函数名,其余是其参数。

如果您想将列表视为纯数据,该怎么办?您需要**引用(quote)**它。

单引号 ' 是 quote 特殊操作符的简写。它告诉 Lisp 抑制求值,并将后续表达式视为字面数据。

; 定义变量 'a'
(defvar a 10)
; 这是一个由两个符号 'a' 和 'b' 组成的列表。
; Lisp 尝试查找名为 'a' 的函数,这会失败。
;;; (a b) -> ERROR: The function A is undefined.
; 这是一个数据列表,不是函数调用。
; 表达式返回列表本身。
(print '(a b))
; 函数 `*` 被调用,参数为 2 和 3。
(print (* 2 3))
; 列表 `(* 2 3)` 被视为数据,不进行求值。
(print '(* 2 3))
(A B)
6
(* 2 3)

分号 (;) 用于注释。单个分号通常用于代码同行的注释。多个分号则按照惯例用于块级注释。

;; 此函数向用户打招呼。
(defun greet (name)
(format t "Hello, ~a!~%" name)) ; 打印格式化字符串到控制台
  • 函数调用:Lisp 使用前缀表示法:(function-name arg1 arg2)。例如,(+ 1 2 3) 对数字求和。
  • 大小写敏感性:默认情况下,Lisp 读取器会将未转义的符号名转换为大写。因此,my-function 和 MY-FUNCTION 指向相同的符号。现代惯例是输入小写,让读取器进行大小写折叠(case-fold)。
  • 真与假:在 Common Lisp 中,符号 T 代表布尔真值。符号 NIL 代表布尔假值。NIL 也是空列表 () 的唯一表示形式。
  • 特殊形式(Special Forms):有些看起来像函数调用的表达式实际上是特殊形式或宏(macros)。它们有自己的求值规则,对于控制流(if、when)、变量绑定(let)和定义事物(defun、defvar)至关重要。

Common Lisp 中的惯用风格是使用 kebab-case(烤肉串命名法)来命名符号,用连字符 (-) 分隔单词。例如:my-cool-function,*global-variable*(对于特殊/全局变量使用耳罩约定)。