模型
它描述了我们使用怎样的方式,根据一组输入计算得到输出。
计算模型有很多种,图灵机,递归函数,λ演算,谓词逻辑,形式文法,
这些计算模型都是数学化的,为我们提供了刻画计算的不同方式。
常见的计算机都是冯·诺伊曼结构的,
是通用图灵机的具体实现,
它可以接受一段程序作为输入,输出这段程序的执行结果。
直接用机器可识别的指令进行编程,是非常麻烦的,因为指令与自然语言相距甚远,
于是人们想到引入一个间接层,
通过编译器或者解释器,将更贴近自然语言的源代码,转换成计算机指令,
使人们可以脱离具体的计算机体系结构考虑问题。
集成
从计算模型的角度理解面向对象设计,是有帮助的。
面向对象是把一个大型系统,拆分为互通消息的多个子系统,
子系统的内部状态,对外是不可见的。
然而,子系统的最终状态,是不可判定的,
获得最终状态的唯一办法,就是将它们集成到一起,开始运行,
这其实构成了一种新的计算模型——Object Calculus。
从模型角度来看,状态的演变是一个计算过程,
拆分和集成是完成同一个任务的两个重要步骤。
表述
不同的编程语言会影响一个人的表述习惯,
因为,能用省力的办法达到目的,多数人都不会绕行。
理论上在任何一种通用编程语言中实现另一种语言,都是没问题的,
但很少有人会为了解决问题便利,当场发明一种新语言。
例如,在用C语言编程的时候,
我们一般不会先实现一套面向对象系统,再用面向对象的方式去编程,
即使在某些场景下,面向对象更能贴近问题的本质。
所以,编程其实更像是一种翻译工作,
把要做的事情翻译成已有的编程语言,而不是转而去创造一门新语言。
而现有的语言,会影响译文的繁杂程度。
损失
在进行编码的时候,有一些信息是无法写入代码的,
毕竟程序只要能运行就好了,开发者在阅读代码时才需要可读性。
那些未写入代码中的信息,就造成了理解障碍。
那么用不同的编程语言进行编程,会导致不同的信息损失吗?
我想会的。
在用命令式语言进行编程的时候,我们能清晰的看到程序的执行过程,
而面向对象语言的执行过程,就被隐式的表现为对象方法之间的调用了,
至于对象为什么这样设计,我们就不得而知了。
在用函数式语言进行编程的时候,程序的执行被打散为了函数的调用,
我们通过测试能明确知道结果是正确的,
但是这些小函数之间为什么那样组合,理解起来就很困难了。
所以不同的编程语言,采用不同的编程范式,会导致不同的信息损失,
信息损失过大,就会对阅读者造成负担,
高昂的维护成本,加剧了代码的腐烂。
结语
代码建立了开发者与计算机之间的桥梁,
遇到一个具体的问题,开发者首先会在大脑中从模型的角度分析它,
然后,再用具体的编程语言实现它,这是一个翻译过程。
本文强调的是,翻译过程会受制于具体编程语言的表述习惯,
也会造成不同程度的信息损失。
所以,编程语言并不是越灵活越好,
编写者能进行的选择越多,我们越不明白当初 Ta 为什么这样做。