文章目录
Programming
Programming是一种制式
看待Programming的角度
The science of programming
- 观点:写程序要用科学思维
- 例
一个Pascal程序
这个程序实现了对整数的求商、余数;r := x; q := 0; while r > y begin r = r - y; q := q + 1; end;
这个程序的不足之处有:
若y < 0,程序运行没有尽头;应该检查先决条件
存在问题的原因:没从科学的角度(程序应该满足充分的前置、后置条件)
修改程序
这样依然不够,因为前后置条件写的还不完善;改进{ y > 0 } r := x; q := 0; while r > y begin r = r - y; q := q + 1; end; { x = y * q + r }
{ y > 0 and x >= 0 } r := x; q := 0; while r >= y begin r = r - y; q := q + 1; end; { x = y * q + r and r < y }
- 编程要科学看待:写程序时正确确定前后置条件,不断推演,检查写的程序是否是所需要的
- 每个statement都有条件约束,整个程序的执行利用符号表示不断变化,满足计算需求;并不关心具体值,在符号上就可以进行推演
这就是Calculus{ 0 <= x and 0 < y } r := x; q := 0; { 0 <= r and 0 < y and x = y * q + r } while r >= y do begin { 0 <= r and 0 < y <= r and x = y * q + r } r := r - y; q := q + 1; { 0 <= r and 0 < y and x = y * q + r } end { 0 <= r < y and x = y * q + r }
- 在推理时,符号的计算仅看作符号的推演,不是动态语义
- 编程的科学观点认为,这样的程序可以被证明正确性以时时保持正确(但现在还没办法证明程序的正确性)
- 通常对程序的保障:
关键之处尽可能证明片段
大部分不证明,而用test(即用想到的不同情况数据来验证,提高可靠性而非提高正确性) - 对程序的另一种保障:
每个程序对应一种自动机,倒过来的方法:模型检测
注:没法推广,但是时时保持科学思维总是很好
The art of computer programming
观点
- 如果要写好程序,要像艺术品一样有创造性;也要了解要操纵的对象(如machine)
Programming Paradigm(编程范式)
Imperative Paradigm(命令式编程范式)
概述
- 命令式编程:要做的事都是将计算过程按照我们要求的形式编排好,让计算机执行
- 在执行过程中叫停,我们应当知道程序所有的状态
- 发展过程
Godel提出:不存在完备系统能描述所有的问题(类似量子物理开始时的观点)
接着,人们得到可计算的理论
Church:能用Lambda算子表示的都可以计算
Turing:能用Turing Machine表示的都可以计算
Godel:能递归函数表示的都可以计算
经证明,三个观点等价;可计算性的研究开始
冯诺伊曼在研究可计算性问题时,根据设计需求和Turing理论,提出冯诺伊曼架构;冯诺伊曼架构“指令编排来做任务”,是结构化与面向对象的基础
注:Godel和Church提出的计算模型与描述式编程范式的两种范式有关
Procedural Programming(结构化编程)
将程序执行的顺序安排好,按步执行
Object Oriented Programming(面向对象编程)
面向对象只是在描述层,便于理解而且屏蔽了不好的习惯;执行时还是命令式的
Declarative Paradigm(描述式编程范式)
概述
- 描述式编程:告诉机器“要做什么”而非“怎么做”
- 程序运行中叫停,内部状态不可知
- 后台有一个运行系统支持,描述函数、输入;如何调度函数、如何调度输入、调几次功能都与使用者无关,是根据计算资源调度决定的
Functional Programming(函数式编程)
- 程序设计语言中的函数(function)有特点是:副作用;即在函数的计算过程中会改变一些环境参数(在完成本身运算任务之外还对外部环境产生影响导致变化);即f(g)与g(f)结果不一定相同(结果与调用顺序有关)
- 函数式程序设计中的函数:无副作用
例如word排版系统:一个字先换字号后换字体还是先换字体后换字号结果相同;(类似这类的排版系统:将处理变成运算命令)
函数式编程参考 - 函数式编程其他好处
通过计算过程不必有序来实现数据的更高效
例如:统计一本书中“a”的个数
命令式编程的做法是对整本书遍历、见a加1
函数式编程的做法是:从第几页第几行开始没有区别,将所有的书拆散,拆成每页/每行,交给好多人去做,最后统计汇总即可(这就是Map Reduce的思想,认为计算没有前后的区别)
Logical Programming(逻辑式编程)
- 只告诉基本规则、已有事实(facts),输入给计算机,(具体怎么做还是交给后台系统来做),接下来只要问系统问题,系统回答
- 似Query系统:事实与规则写入系统,执行query,系统会运行计算出结果;但从哪条规则开始匹配、从哪条规则开始触发都没办法了解
- 逻辑式编程语言代表:Prolog
- 例
son(a, c). son(b, c). brother(X, Y) :- son(X, Z), son(Y, Z). ?-brother(a, b). yes. ?brother(a, X) b.