引言
SCIP(Structure and Interpretation of Computer Programs)[1]是MIT自1984年起的编程入门教程,尽管最近他们用Python的课程取代了Lisp语言,但是随着工业界越来越多的应用函数编程语言,如Clojure、Scala、Racket,以及软件开发使用并发的趋势(见文章[2]),重读SCIP是很有意义的。
SCIP分五章:构造过程抽象,构造数据抽象,模块化、对象和状态(涉及并发),源语言抽象,寄存器机器里的计算(编译器如何工作)
环境
OS X下使用IDE DrRacket及其语法插件#PLaneT neil sicp.plt
在文件头使用 #lang planet neil/sicp 声明语言类型
Lisp基本语法
Lisp的原始定义在John McCarthy1960发表的论文[3]。
Lisp[4]是一个语言族,包括Common Lisp和Scheme,二者区别见[5]。
过程定义
1 | (define (<name> <formal parameters>) <body>) |
以上是Scheme的主要语法,可以容易而优雅地生成语法树,没有语法糖。那么递归和迭代怎么用?使用上面的语法规则即可。
1 | ; 递归法求阶乘 |
高阶函数
过程作为参数
1 | # define ∑f(n), n∈[a,b] |
Lambda构造过程
匿名函数,用法同Python
1 | (lambda <formal-parameters> <body>) |
let表达式,注意var不是变量是常量,无副作用。
1 | (let ( (<var1> <exp1>) |
工具函数
打印
1 | (define (print x) |
以上是Lisp的主要语法规则,非常简练。
至此,SCIP第一章结束,其中有许多练习,余不一一。
构造数据抽象
闭包
(这里指的不是匿名函数)
是在处理符合数据中的一个关键思想:用于组合数据对象的粘合剂,不但能用于组合基本的数据对象,同样也可以用复合数据的对象。
其中,粘合剂指:程序设计语言应该提供的,把一些数据对象组合起来,形成更复杂的数据对象的操作。
Wiki: 闭包是引用了自由变量的函数
序对
用来粘合两个对象,用法:
1 | (define x (cons 1 2)) |
序对的一种定义:
1 | (define (cons_ x y) |
另一种定义:
1 | (define (cons__ x y) |
序列(列表)
可看做嵌套的序对:
1 | (list <a1> <a1> ... <an> nil) |
表操作:
1 | ; list[0] |