程序语言编年史

程序语言编年史

概述

这次咱们聊下程序语言的发展史,除了程序语言,还会着重讲下程序语言密切相关的计算机的发展史,顺带讲下同时期与程序语言和计算机相关领域的发展,为什么要把程序语言和计算机相关领域放到一块讲, 因为这些领域和计算机的关系太密切了, 程序语言是程序员和计算机沟通交流唯一方式, 计算机的计算模型的发展, 还有计算机的应用领域的发展都对程序语言有着深刻的影响. 通过计算机相关领域的发展, 我们能从中可以找到一些影响程序语言关键因素, 看看这些因素是如何推动程序语言一步步发展成今天这个样子的.

计算机发展史

计算机的发展可以分为两条线进行追溯, 一条是计算理论的发展, 一条是计算机实体的发展, 下面我们看看计算理论和计算机的发展轨迹.

理论模型的演变

计算理论是近现代才出现的一个数学分支,主要研究可计算性,计算的复杂度,计算模型(计算理论中两大计算模型:图灵机,lambda演算),形式语言(编程语言也是一种形式语言).我们可以看到计算理论主要研究的对象的名字中有三个带了; 这个词很常见,好像和这些词汇所表达的意思挺相近:四则运算,数值计算,逻辑运算.本节就以为主线介绍下计算是什么,以及其演变历史,还有它和计算理论的关系.

公元前2500年,在美索不达米亚的一块泥板上记录着谷仓里面有1152000,每个人分7分,可以分给多少人,结果是164571,有余数.这是最早有记录的数学活动,可以猜想到史前的数学的用途:测量,记账,计数等等,都是一些简单的数值计算. 在这个时期, 数学中抽象出的数字及其相关运算操作都是直接对应现实世界中的实物某项具体性质(长度,数量,金额等)和对实物性质的操作(测量读数,计数,分配等).
可见当时的数学抽象程度很低,使用的领域也都是和日常实践活动密切相关,而且都是数字计算.

公元前五世纪,根据毕达哥斯拉学派的希帕索斯发现等腰直角三角形的直角边长与其斜边长不可通约(通约:两个量选取一个表示单位量的数后,两者不能同时被表示整数之比), 这个发现颠覆了之前毕达哥斯拉学派之前认为的”万物皆数(自然数)”的信条, 这就是数学史上有名的;就是这个不可通约数的发现还导致了一个悲剧, 毕达哥斯拉学派众人认为希帕索斯的发现是异端邪说,作为惩罚他们把希帕索斯淹死了, 因为真理被死亡的希帕索斯可能是科学史上的第一个, 但他却不是最后一个, 此后的哥白尼也没有因日心说被火烧死, 但是哥白尼同时期的其他科学家可能就没有那么幸运了.

思考一个问题:希帕索斯是如何发现等腰直角三角形的斜边和直角边不可通约的呢/p>

设等腰三角形的直角边长为x,斜边长为y,根据毕达哥斯拉定理有:,进一步可推测出, x和y的关系, 满足左边等式的有无限个组解, ,而且这:

1. 为奇数, 为偶数
2. 为奇数, 为奇数
3. 为偶数, 为偶数
4. 为偶数, 为奇数,

根据  和  进一步只分析  的情况, 只剩下了三种可能:

1. 为奇数, 为偶数; 代入原等式, 如果偶数 乘以 2 得到的结果还是偶数, 和是奇数矛盾, 所以此命题不成立
2. 为奇数, 为奇数; 代入原等式, 如果奇数 乘以 2 得到的结果是偶数, 和是奇数矛盾, 所以此命题不成立
3. 为偶数, 为偶数; 和前提:只分析  的情况冲突, 此种情况不存在
4. 为偶数, 为奇数;由原等式推出, 为偶数的话, 那么肯定也是偶数,因为只有偶数的平方仍为偶数, 而且偶数的平方乘以二分之一仍为偶数, 和原来的陈述矛盾,所以此命题不成立.

综上所述,直角等腰三角形的直角边和斜边不可通约.

我们现在回顾分析上述的数学活动过程, 从,的定义,然后通过,最后得出, 这个过程中计算只参与了各个可能情况中的等值判断, 中间结果和最终结果的流转全是由推动的.从这个时期开始, 数学理论研究工作中的主要方法为,以及后来出现.比如欧几里得的<几何原本>,书中对几何的研究方法都是以和以及为基础.还有比较有名:. 以及斯多葛的逻辑证明的推理规则和  可以导出 .就是这些基础的或者叫或者正式点叫, 为以后的数学大厦奠定了夯实的基础,后面我们会继续介绍逻辑在数学计算发展史中所发挥的重要作用.

前面的讲述提到的其实只参与推理活动需要数值判断的部分;和数学理论研究相反的是实践活动中的数学,计算承担了其中的大部分工作.计算参与数学实践活动有一个比较有名的例子就是欧几里得的求两个数最大公约数,这个计算模型包含了得出最大公约数的能力同时也隐含了最大公约数的推理证明.辗转相除法的计算模型简化了求最大公约数的过程和证明其为最大公约数的过程, 从这里我们似乎看到了计算和证明的一点点模糊关系.

另外值得注意的是这次的数学求解活动将现实中具体问题与数学中抽象的问题完全分割开来,因为此次求解涉及的概念完全是从对现实问题的抽象(数学中的计算,测量,分割)的抽象(对从现实抽象而来的数学概念再次抽象)而来,这次求解开辟了对纯粹的数学抽象概念的研究, 断开了与现实问题的直接连接, 比如这次数学活动中的这个概念, 这个概念不涉及任何具体的三角行, 活动要研究的是所有的特征,而不是某个具体的的特征. 以后的数学所研究的领域也大都是此类从现实问题抽象而来再次抽象的数学问题, 虽然这样的数学问题普适性更广, 也越接近本质, 但是这也是数学为什么这么让人费解犯难的原因之一吧.

我们接着来说逻辑证明的发展情况,从中世纪开始一直到20世纪,逻辑证明在历经各位哲学大师的雕琢下,愈发的闪亮, 当然也愈发的让人为难了.我们前面提到的也进一步的演化为,最终演变成今天的的样子.

命题逻辑以后很长一段时间,逻辑证明在数学史的发展都没有出现新的成果,直到17世纪德国的莱布尼茨首次尝试将进行符 化,公理化.但是很遗憾的是他没成功,不过这次尝试给逻辑证明带来了新的方向:将逻辑证明数学化; 再后来布尔发明的布尔代数通过将命题进行布尔运算组合后判断真假,同时布尔也发明了一些运算符 来抽象运算规则。

后来到了19世纪末期,弗雷格在前人的基础上对进行了更加细致完备的完善工作, 他提出将命题逻辑的命题中所作用到的进行和, 然后再用量化词或者对后的实例进行范围的限定修饰, 这样不仅消除了命题逻辑中的模糊性, 而且可以根据演绎规则对后的谓词逻辑模板所生成的新进行真值推断.

弗雷格另一个突出的逻辑证明的实践贡献,就是弗雷格希望能为自然数提供一种纯粹逻辑的理论,从而将算术、微积分的所涉及的问题乃至一切数学问题都进行逻辑化. 比如2+2=4, 他认为即使是浅显基础的数学公式,也应该用严格的演绎推理来进行证明,而不是用归纳总结来确证.
弗雷格的<算术基础>中根据和给出了2+2=4的证明:

上表中我们可以清楚的看到计算工具的逻辑载体从机械过渡到电子继电器进而最终发展成电子设备,其中的计算规则的执行也逐渐由机器的自动化执行取代了人工操作;计算工具的计算能力的适用性也由专用的领域拓展到了通用计算.
在计算机的发展历史节点有一个关键点那就是图灵机和lambda演算的出现, 而且这两个模型在同一年被提出, 这两个计算模型都是图灵完备的, 我们在上一节中也讲到过这两个计算模型和计算的能力是等价的. 有意思的是图灵机给现代的程序存储计算机提供了最早的计算理论模型. 而lambda演算作为一种原生形式语言给程序设计语言提供了函数编程范式.
此处重点介绍下图灵机和lambda演算,因为图灵机影响了现代计算机的架构,而lambda演算影响了现代程序语言。

图灵机

图灵机是一种状态机,所有能做的事情, 图灵机也能模拟完成.现代计算机的计算能力和图灵机的计算能力是等价的, 现代的计算机就是受图灵机的原理一步步发展成现在这个样子的.

图灵机实现计算的方式是根据自身定义好的,一步步根据上的字符输入,来切换自身当前的状态,改写纸带上的字符移动,图灵机的输入输出都是在一条可以进行读写字符的格子纸带, 最终的计算结果也是靠纸带上字符呈现的. 实际上图灵机的主要结构就是一个无限长的用来记录输入和输出的格子纸带(计算机的内存) 和 一个具有状态转换集合并且可以左右移动的读写头(和cpu很相似, 状态转换集合可以看成cpu的指令集, 左右移动的读写头可以看成cpu对内存进行随机读写)

的定义和的定义是等价的, 而且它们的执行过程也很相似, 都是对状态进行一步步的转换. 在用图灵机进行计算时, 其中有一个关键的要素, 就是如何将实际问题抽象转化为图灵机可解的计算模型, 这有和我们通过程序语言模拟建模现实问题的解决方案是一样的. 我们知道在使用程序语言进行解决问题时有两个比较关键因素决定了程序的实现难度:一个就是数据结构, 一个就是算法.在图灵机中, 原生的数据结构就是一条可读写字符的格子纸带, 原生算法就是状态转换以及对纸带的读写.
使用图灵机进行计算的步骤:
1.从现实问题中抽象出参与计算的实体,比如数字加法运算中的数字, 你可以将数字定义为纸带上写有1的连续格式的数量, 比如3就是111, 2就是11,6就是111111,依次等等; 当然还要定义算法操作符, 操作符可以选取字符中加 :
2.定义算法,定义算法时需要根据前面一步中定义的实体的自身特点来进行实际算法实现;比如加法,根据上面对数字的定义, 那么加法的可以定义为读写头擦除第一个数字1,然后读写头向右一直移动到加 处将 改为1,最后读写头向右移动到空白处停机; 此时纸带上1的个数就是此次运算的结果.

lambda演算

lambda演算是一个用来实现计算的数理逻辑形式系统. 其核心就是基于符 替换和转换规则来实现计算.

lambda表达式和以及针对lambda表达式的转换规则(也叫规约)
下面是三个基础lambda表达式项

按照顺序排列在打孔纸带上的指令, 这就是最初的程序设计语言, 虽然太难读; 那会有一个叫葛丽丝·霍普的女程序员(在马克一 上写代码)就感觉直接在纸带书写指令太麻烦, 就想着能不能直接用人类的语言(前面说过自然语言是一个形式系统,本身具备计算能力)来写程序呢, 于是她就开始了这方面的尝试, 我们常说好事都会发生在别人身上, 果不其然, 她在1951年-1952年做出了第一不完整编译器 A-0 System, 这个编译器内部预置了功能函数, 程序员只能使用这些功能函数, 最终A-0会将代码转换成内置的功能函数的二进制指令, 有点像编译器中链接功能.虽然这个编译器的功能很弱,但是用人类的语言来书写程序的这个想法, 使得程序设计语言和编译器从此开发生根萌芽,一直到现在的百花齐放. 另外有一个让人拍手称快的消息, 这个女程序员发现了史上第一个bug(一个飞蛾), 很嘲讽有么有.

这里面有很多概念不是由语言直接支持的,而是由语言之上的api库来支持, 例如设计模式,aop,ioc等等. 不过像面向对象,接口,异常这些概念在刚提出的时候当时的编程语言也是不支持的, 是后来程序员发现这些概念在解决问题时特别常用,然后就把这些概念加入到了语言当中. aop,ioc,设计模式等等这些概念会不会得到语言自身的支持, 这还得看语言和语言的使用方式的发展了.值得一提的是观察者模式在C#中直接通过语言的概念提供了支持, C#提供了 event和delegate 关键字来提供了支持.

在程序设计语言这个形式语言中, 各种概念的加入丰富了编程的乐趣,不过带来的更多的是以不同的视角对现实问题的抽象建模的可能,这些概念提出的背景可能涉及很多:.最终这些概念解决了提出它时所要解决的问题,但是也引入了其他问题,当然也没有一个万能的概念能解决所有问题,更多是写代码的人要思考如何使用这些概念的排列组合来解决一个个现实问题.不过这些概念有一个共同的特征,那就是这些抽象出来的概念越来越接近以人类看待现实问题的特点.

不过另外一些问题倒是挺有趣的, 那就是如果以计算来看待这个世界,人具备计算能力,而且创造具备计算能力的机器. 计算机的计算能力来自于人为设计,那人的计算能力来自于何方, 是计算本身吗计算机的计算能力是为了帮助人类解决现实问题,那人类的计算能力的目的是为了什么, 是为了人类自身吗/p>

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年11月9日
下一篇 2019年11月9日

相关推荐