LISP - 基本语法
Lisp - 现代基本语法与设置
Section titled “Lisp - 现代基本语法与设置”欢迎来到 Lisp 的世界!本教程将重点介绍 Common Lisp,这是一种功能强大、标准化且支持多范式的编程语言。我们将从基础语法开始,并指导您设置一个现代的开发环境。
设置您的开发环境
Section titled “设置您的开发环境”为了获得高效的 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 提供了一种现代替代方案。
基本构建块:S-表达式
Section titled “基本构建块:S-表达式”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)) ; 嵌套列表() ; 空列表,也称为 NILLisp 在**读取-求值-打印循环(Read-Eval-Print Loop,REPL)**上运行。它读取一个 S-表达式,求值(evaluates)它,并打印结果。求值的关键规则是:
- 符号被视为变量并求值为它们的值。
- 列表被视为函数调用,其中第一个元素是函数名,其余是其参数。
如果您想将列表视为纯数据,该怎么办?您需要**引用(quote)**它。
单引号 ' 是 quote 特殊操作符的简写。它告诉 Lisp 抑制求值,并将后续表达式视为字面数据。
示例:求值 vs. 引用
Section titled “示例:求值 vs. 引用”; 定义变量 '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)) ; 打印格式化字符串到控制台核心语言概念
Section titled “核心语言概念”- 函数调用: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*(对于特殊/全局变量使用耳罩约定)。