SICP笔记(三)

As programmers,we should be alert to opportunities to identify the underlying abstractions in our programs and to build upon them and generalize them to create more powerful abstractions.

接受一个或多个函数作为输入,或者以一个函数作为返回值的函数称为高阶函数(higher-order function)。高阶函数可以让我们在更高层面上思考问题,避免直接面对底层的基本语义过程。

first-class

带有最少限制的元素称为具有第一级的状态(first-class status)。

  • They may be named by variables
  • They may be passed as arguments to procedures
  • They may be returned as the result of procedures
  • They may be included in data structures

作为参数

对整数和,立方和,莱布尼兹序列求和的过程中,都存在一个求和的过程,我们可以将其抽象。

1
2
3
4
5
(define (sum term a next b)
(if (> a b)
0
(+ (term a)
(sum term (next a) next b))))

抽象出的sum是这几个过程的公共模式,如此处理,可以减少公共函数的复用。

1
2
3
4
5
6
7
8
9
10
11
12
13
;;; [a,b]的整数求和
(sum (lambda (x) x)
a
(lambda (x) (+ x 1))
b)


;;; [a,b]的整数的立方求和
(sum (lambda (x) (* x x x))
a
(lambda (x) (+ x 1))
b)

lambda · let

lambda表达式可以创建匿名函数,免去为函数取名字。创建的函数和使用define创建的函数除了没有绑定环境中的变量名之外,都是一样的。
let表达式可以创建局部变量。let表达式是lambda表达式的语法糖,对let表达式的求值过程中,解释器并不需要新的机制。let表达式中变量的作用域就是let表达式中的函数体。

  • let allows one to bind variables as locally as possible to where they are to be used
  • the variables’ values are computed outside the let

作为一般性的方法

区间折半法寻找方程的根,时间复杂度O(log (L/T)),其中L是区间长度,T为可容忍的误差。
寻找函数不动点,使用平均阻尼(average damping)可以加速计算的收敛速度。

作为返回值

一般情况,将一计算过程写成程序可以有很多方式,有经验的程序员知道如何选择过程的形式,使其特别地清晰且易理解,并且使该计算过程中有用的元素能表现为一些分离的个体,能重新用于其他的应用中。
牛顿法求平方根,收敛速度比区间折半法快得多。


至此,第一章阅读完毕,从4.21开始,刚好历时一个月,比想象中慢些,come on!!!

习题解答:传送门