语义工程和PLT Redex

本书侧重于从抽象机器介绍编程语言, 愚以为某些内容尚待打磨, 并非易读. 本书分为三个部分, 第一部分介绍了操作语义和抽象机器, 第二部分引入了表达操作语义的工具PLT Redex, 第三部分呈现了PLT Redex的一些实际应用.

第1章 语义via句法

描述编程语言自句法始. 正如每个程序员所知, 语言的句法总以BNF (Backus-Naur Form) 语法的某种变体形式出现, 其枚举了符合语法的词汇和句子. 困难之处实际上在于刻画程序的意义, 即程序是如何进行计算的.

在这本书的第一部分, 我们建立了一个基于句法的语义描述方法. 我们从这样的观察开始, 即计算 (computation) 是对于算术 (calculation) 的一般化, 一个孩子所接受的算术训练从11等于2这样的材料开始. 诀窍在于看出这种形式的算术也可应用到程序上来.

程序的算术意味着观察一个表达式或者语句的句法, 然后将其与另一个表达式或者语句联系起来, 通常假定是更简单的. 对于表达式1+1而言, 前面的声明是容易理解的. 它等于2, 即1+12关联起来. 即便是函数应用于参数值也可以这种方式表达 [注记: 实际上, +本身即是一个二元函数]:如果定义f(x)=2x+55, 那么f(4)=24+55.

用数学语言来说, 我们是在以句法上的关系描述编程语言的语义. 对于学习函数式编程语言的人而言, 这种声明并不令人意外. 我们知道函数式编程并不超出将七年级代数转换为编程语言太多, 而代数定律不过就是将代数表达式相互联系起来的等式. 但或许令人惊讶的是, 以这种方法我们可以描述(几乎)所有编程语言的语义, 即便是那些含有命令式副作用的语言.

现在我们将引入我们的想法, 即必要的数学元知识, 从将句法定义为集合开始.

第1.1节 定义集合

BNF语法可有多种用途. 一种含义是字符串的集合. 另一种解释是的集合, 其常被称为抽象句法(树). 本书我们总是指后者.

对于本章和下一章而言, 我们使用下面的BNF语法作为一个实际例子:B=t|f|(BB)我们将其当作以下施加于抽象句法树集合B上的约束的缩写:tBfBaBbB(ab)B从技术上说, B是满足以上约束的最小集合. 为了构造这个集合, 我们先包括基本元素tf, 然后归纳性地将其组合为复合元素.

记号: 我们有时用B表示集合B, 但是有时B又表示B的任意一个元素. 从上下文来看, 意义总是明确的. 有时我们将下标或者撇号附到集合的名字上以表示该集合的任意元素, 例如B1或者B. 因此, 以上约束也可以写成tB[a]fB[b](B1B2)B[c]在有限的空间之中枚举出B的所有元素显然是不可能的:B={t,f,(tt),(tf),}然而, 给定某个树, 我们可以通过表明其满足约束而论证其的确属于B. 例如, (t(ft))就在B中:1.tB根据[a]2.fB根据[b]3.tB根据[a]4.(ft)B根据2, 3, 以及[c]5.(t(ft))B根据1, 4, 以及[c]通常这样的论证也可以安排成所谓的证明树的形式:

第1.2节 关系

第1.3节 作为等价关系的语义

第1.4节 语义via归约

第1.5节 上下文中的归约

第1.6节 求值函数

第1.7节 记号总结

第2章 分析句法性语义

第2.1节 从问题到数学声明

第2.2节 作为定理的回答

第3章 λ演算

第3.1节 函数和λ演算

第3.2节 λ演算: 句法和归约

λ演算的表达式的一般语法定义如下:M,N,L=X|(λX.M)|(MM)X,Y,Z=一个变量: x,y,以下是M的示例成员:x,(xy),(λx.x),((xy)(zw)),(λy.(λz.y)),((λy.(yy))(λy.(yy)))第一个例子, 即x, 没有特定的直觉性意义, 因为x还未被定义. 类似地, (xy)的意义是x应用于y, 但是我们没有更多可说的了. 与之形成对比的是, 例子(λx.x)与恒等函数相对应. 这个例子和前两个例子的不同之处在于x在前两个表达式里都是自由出现的, 而在后面的例子里是绑定出现的.

第3.3节 编码布尔

true(λx.(λy.x))false(λx.(λy.y))if(λv.(λt.(λf.((vt)f))))

第3.4节 编码序对

M,N(λs.((sM)N))mkpair(λx.(λy.(λs.((sx)y))))fst(λp.(ptrue))snd(λp.(pfalse))

第3.5节 编码数字

0(λf.(λx.x))1(λf.(λx.(fx)))2(λf.(λx.(f(fx))))n(λf.(λx.(f((fx)))))

第3.6节 编码和错误

第3.7节 递归

Y(λf.((λx.(f(xx)))(λx.(f(xx)))))

第3.8节 一致性和规范形式

第3.9节 规范形式和归约策略

第3.10节 历史

第4章 ISWIM

1950年代末期和1960年代早期, 人们发现了编程语言和λ演算的诸多方面之间的联系. 其动机从想要刻画Algol 60的语义演变为藉由已经充分理解了的数学系统来理解编程语言的面貌. 也就是说, 人们想要学会如何系统地设计编程语言.

第4.1节 ISWIM表达式

第4.2节 ISWIM的计算

第4.3节 α, η和商

第4.4节 YV组合子

第4.5节 求值

第4.6节 一致性

第4.7节 观察等价

第4.8节 历史

第5章 一个抽象句法机器

第5.1节 标准归约

第5.2节 标准归约定理

第5.3节 对于观察等价进行推理

第5.4节 一致求值

第5.5节 历史

第6章 抽象寄存器机器

第6.1节 CC机器

第6.2节 SCC机器

第6.3节 CK机器

第6.4节 CEK机器

第6.5节 历史

第7章 尾调用和更多的空间节省

第7.1节 SECD机器

第7.2节 求值上下文的空间

第7.3节 环境的空间

第7.4节 历史

第8章 控制: 错误, 异常和延续

第9章 状态: 命令式赋值

第10章 简单类型ISWIM