Declarative vs Imperative(声明式 vs 命令式)
Declarative programming 可以认为是一种 global approach,而 imperative programming 可以认为是一种 local approach。
一个简单的例子
如上。可以看到这个定义,就是函数的 global 定义。
这就是非常 imperative style 的定义。一步一步要给你算出来。
牛顿力学(微分方程)和拉格朗日力学
使用牛顿力学考虑受力时,要用到牛顿第三定律。也就是:\(\frac {\mathrm dv} {\mathrm dt} = \frac F m\)。我们考虑的是在某一处、某一时刻的局部情况。通过积分,局部变化累加成了整体变化。
但是,考虑费马原理:光走极值路线。这就是一个整体的描述。通过一个整体的描述,你只要找出来符合这个描述的路径,那就是光路。
Lagrange 力学考虑的是最小作用原理。令 \(\mathrm {Action} = \int (K - P) \mathrm dt\),则极值的路径就是我们世纪要走的路径。
- 直观上,炮弹为什么不直接走直线,而是抛物线?因为可以在高空,i.e. where \(K\) is small and \(P\) is large,多呆一会儿。
但是,为什么满足最小呢?实际上,在量子力学中,真正物体(在两点之间)的路径是所有路径的加权。相加之后,可以证明:通过经典方法计算出来的路径,就是所有路径加权之后的最大概率路径。
而这个所有路径,就是 global,就是 declarative。
神经网络
局部上来看,神经网络里的一个神经元,就是加权接受信息、再把信息给到下一个神经元。
整体上来看,神经网络可以认为是:我们把所有神经网络中的路径加权相加。这些路径中,有些认为 no,有些认为 yes,它们互相抵消,略多的一方获胜。
- just like adding up all path from \(a\) to \(b\). The route derived by classical physics, is the most probable route by quantum physics.
Functional Reactive Programming (FRP)
与其在局部上处理每一个响应,不如整体上进行操作。也就是:
- 把一段时间内的所有响应视作一个 list。
- 我们假设我们已经掌握的整个 list,从而,我们直接 work on the whole list
- 当然,实际上,when on the fly,这个 list 并不完整。但是,no problem! Haskell is a lazy language, which means it can react when the data actually comes. (if it's not yet come, just block the other, and wait till the data comes)
从而,我们通过操作整体的方式,配合 pure function 的 laziness,达到了局部的效果。