3)将有关认识与那些在实际中和他同在的所有其他认识隔离开,这就是抽象
SICP 第一章
现存的许多威力强大的程序设计技术,都依赖于填平在「被动的」数据和「主动的」过程之间的传统划分
SICP 第一章

计算机程序是由需要被操作的「数据」和操作数据的「过程」构成。解释起来可以说是一静一动,数据所代表的静态的具体某个值,而过程则是动态的代表从一个值到另一个值的转化。和数学研究很像不光研究函数对值的作用,还研究函数本身,计算机编程过程中也不光用过程作用于数据,也可以处理过程本身就像作用于数据之上那样。

过程作为参数

通过区间折半寻找方程的一个根

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
enum searchError: ErrorType {
case sameSign
}
func isCloseEnough(x x: Double, y: Double) -> Bool {
return abs(x-y) < 0.001
}
func search(function f: (Double)->Double, negPoint: Double, posPoint: Double) -> Double {
let midPoint = (negPoint+posPoint)/2
if isCloseEnough(x: negPoint, y: posPoint) {
return midPoint
} else {
if f(midPoint) < 0 {
return search(function: f, negPoint: midPoint, posPoint: posPoint)
} else {
return search(function: f, negPoint: negPoint, posPoint: midPoint)
}
}
}
func halfIntervalSearch(function f:(Double)->Double, x: Double, y: Double) throws -> Double {
let a = f(x), b = f(y)
if a > 0 && b < 0 {
return search(function: f, negPoint: y, posPoint: x)
} else if a < 0 && b > 0 {
return search(function: f, negPoint: x, posPoint: y)
} else {
throw searchError.sameSign
}
}
func f(x: Double) -> Double {
return x*x*x - 2*x - 3
}
do {
let result = try halfIntervalSearch(function: f, x: 1, y: 2)
print(result)
} catch {
print("error")
}

其中函数 f 作为参数可以换成其他形式

过程作为返回值

函数求导

1
2
3
4
5
6
7
8
9
10
func deriv(function f:(Double)->Double) -> (Double)->Double {
let dx = 0.00001
return {(x:Double)->Double in (f(x+dx)-f(x))/dx}
}
func cube(x:Double) -> Double {
return x*x*x
}
deriv(function: cube)(2)

过程的单一责任原则

过程是可以复合定义的,良好的定义应当保持各部分的解耦,例如第一个例子中对 isCloseEnough 过程的调整就可以做到完全不影响其他过程。