Dopcn's Blog

life and work

数据过程二元对立之过程作为数据

Posted at — Nov 9, 2015

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

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

过程作为参数

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

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 作为参数可以换成其他形式

过程作为返回值

函数求导

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 过程的调整就可以做到完全不影响其他过程。