第 3 部分 · Functional
函数式:不动状态的计算
回答"不动用状态,怎么完成计算"。从高阶函数、递归到 λ 演算、Y-Combinator、迷你解释器——Racket 的核心范式。
01
递归——Racket 处理列表与树的方式
递归不是 Racket 对循环的妥协,而是处理列表和树的自然方式——数据是递归的形状,处理就跟着是递归的形状。
02
柯里化——把多参数函数拆成一串小函数
柯里化把一个多参数函数拆成一串单参数函数:喂一个参数,拿回一个还在等剩下参数的新函数。
03
三种局部绑定——let 的并行、顺序与递归
Racket 里给中间结果起个名字、限定它的可见范围,靠 `let` 家族。绑定相互独立用 `let`,有先后依赖用 `let*`,要引用自己用 `letrec`——区别全在求值时机。
04
let-values——一次接收函数的多个返回值
Racket 的函数能一次返回多个值,`let-values` 就是把它们一次性接住、绑到本地变量上的专门工具。
05
case-lambda——按参数个数分派一个函数
一个函数名,好几种调用形态——Racket 的 `case-lambda` 让你按参数个数分派不同的函数体,把“重载”这件事写进语法里。
06
模式匹配——用形状拆解数据
`match` 让你按数据的“形状”做判断:一次匹配同时完成“是不是这种结构”和“把里面的部件取出来”两件事。它是 `cond` 的进化版——`cond` 只比值的相等,`match` 能比形状。
07
Lambda 演算——用函数表达一切计算
λ 演算只有三种表达式——变量、函数抽象、函数应用——没有数字、没有 if、没有循环,却足以表达一切可计算的东西。
08
Y-Combinator——递归从哪里来
一个连名字都没有的函数,怎么调用自己?Y-Combinator 不给它取名,而是给它一个不动点。
09
写一个迷你解释器——递归遍历语法树
一个算术解释器,本质就是一段递归遍历语法树的代码——复合节点递归进去,原子节点直接返回。写出来不到三十行,“求值”这件事就不再神秘。