第 2 部分 · Basics
基础:用 Racket 写点什么
回答"用 Racket 写点什么,最少要知道什么"。从括号的含义到数据、列表、结构体、函数,建立 Racket 代码的基本形状。
01
括号不是负担——Racket 的结构之美
Racket 满屏的括号不是语法噪音,而是一种把程序形态削减到极致的设计——同一套括号既是代码,也是数据,这就是同像性(homoiconicity)。
02
Racket 的数据——原子与复合
Racket 的数据看似五花八门,其实只分两半:原子(数、字符串、布尔、符号、字符)不可再拆,复合(pair 与 list)把原子粘起来。可它们为什么都能塞进同一套括号?
03
列表——Racket 的主力数据结构
在 Racket 里,列表不是数组,而是一个个 cons 单元串成的链——理解了这根链,`first`、`rest`、`map`、`filter` 才算有了根。
04
结构体——给数据一个明确的形状
列表能装一切,代价是你得记住每个位置代表什么。`struct` 给每个字段一个名字,顺手生成谓词、访问器和不可变性。为什么树、节点、配置这类复合数据,一到 `struct` 手里就突然清楚?
05
函数与闭包——Racket 里动作如何成为值
在 Racket 里,函数和数字、字符串一样是一个值——能存进变量、塞进列表、传来传去。而让这一切成立的,是闭包:函数随身带着它出生时的环境。
06
符号表达式——Lisp 元编程的根基
Lisp 用一套括号写两样东西——程序,和程序操作的数据;这种“代码即数据”的语法叫符号表达式,是 Lisp 元编程的根基。
07
从嵌套到管道——Racket 函数组合的两种方向
Racket 里把几个函数拼成一个新函数,用 `compose`;想让数据从左流到右、一眼读懂,用管道。两者方向相反,各管一摊。
08
告别循环——map、filter 与 fold 的列表处理
处理列表不用写循环:map 做转换、filter 筛选、fold 压成一个值、apply 把列表摊开成参数。你描述“结果是什么”,而不是指挥“每一步怎么做”。