圣战简史:编程语言篇


Author: Kimmy

跟编辑器一样,编程语言也是个生产力工具。这俩另外的一个共同点就是,都在圣战的核心。

编程语言是站队分派别的主要方式,并且因为这一点的存在,也就成了各种编程语言背后的势力来控制程序员的主要途径。你真别不相信,大部分时候借用编程语言来宣扬某些东西是最能让对应的开发者群体买账的方法,后面我们会看到一些例子。

另外一方面,编程语言是某种编程思维的具体实现。一门编程语言必然满足一种或者多种编程范式,编程范式直观地限定了设计代码时所考虑的重点和解决方案,但不同的范式之间只有适用场景的不同,没有显然的优劣之分。反倒是一些人因为了解顺序问题,总会把后来者当成是更高级的。但殊不知对应的思想远在60年代就已经出现、成熟,恰是有些人借助这种编程语言的宗教煽动性,形成一系列的高低贵贱的观点。

同样的编程语言也是如此,只有适用于某些场景的编程语言,没有“最好”的编程语言(PHP除外)。我在2014年提出过一个“编程语言定律”:一切编程语言都是Domain Specific的。这一点至今没变。没有一个通用的编程语言可以实现一切。

这一点我们在最初的编程语言里面就能看出端倪。最早的编程语言都是解决各种领域问题的,从他们的名字上就能看出来:

所以我们看到Fortran拿来做科学计算、LISP拿来做符号计算、Algol用来描述算法、Perl用来处理文本和数据,他们都有着光明的前途。

这个光明的前途,也是一步步走出来的。

在开始聊编程语言之前,先说明一下,我们的scope是计算机科学领域。毕竟在“programming”表示“编程”之前,另有别的意思,比如 Linear Programming。

而且远在编程语言出现在之前,也需要用于描述步骤和执行步骤的方式,比如古希腊数学家欧几里得用来记录著名的欧几里得算法(用于计算两个数字的最大公约数),也是用定义完善的规则来描述的执行步骤,而后人只需要通过在《几何原本》里面描述的步骤自然也就能利用该算法求最大公约数。

这个过程常被人忽视而直接进入到了下一步:机器出现,需要指令来控制机器的执行,于是才出现了编程语言。但在没有机器之前,理解和执行指令的是人。比如下面一个老梗:

妻子让做程序员的丈夫去超市买两个面包,并说:“如果有鸡蛋的话,就买六个”。

结果不一会,丈夫带着六个面包回来了。妻子奇怪地问:“你怎么买了六个面包?”,丈夫回答说:“你不是让我有鸡蛋的话就买六个吗?我看超市里有鸡蛋,所以就买了六个”

熟悉编程的人很容易看懂这个笑话的梗,而也正是这个笑话明显能看出作为“指令”和“执行”这两部分之间沟通的重要性:与人沟通尚且如此,与机器沟通自然也就需要更明确的指令。中国人发明了算盘,可以拿来做计算,但去操作的依然是操纵算盘的人。直到19世纪Charles Babbage在提花机的基础之上进一步设计了分析机(Analytical Engine),才有了可以通过指令自动解决问题的“机器”,与之一起出现的,是第一位程序员Ada Lovelace和最早的“计算机程序”。

当然了,在Babbage的时代,完全没有指令集的概念,所以他给出的是一些操作性的示例。而根据John Walker提供的模拟器的还原,提供了一系列标准的符号化指令用于简化程序的设计,这些指令是跟Babbage的打孔卡相对应的。如下是一段求阶乘的程序:

N0 6
N1 1
N2 1
×
L1
L0
S1
–
L0
L2
S0
L2
L0
CB?11

CB在这里指的是Conditional Branching,是巴比奇的一大创新。有了这个操作整个分析机就可以进行重复和分支执行代码。

遗憾的分析机和更早的差分机都没能在巴比奇的有生之年被建造出来。而且因为一些原因,早期的电子计算机如Havard Mark I和ENIAC(埃尼阿克)并没有直接继承巴比奇的设计,而是重复踩了很多坑。

不过在威廉·吉布森的小说《差分机》的设定下,差分机和分析机得到了重生,Ada也成发表了对应设定背景的“哥德尔不完备性定理”。尽管现实世界没有直接受太多的影响,但因为《差分机》带来的蒸汽朋克浪潮还是进入了主流文化圈。

而至于Ada,70年代以后我们还会遇到她的。

时间进入20世纪。

大卫希尔伯特在世纪初提出了23个世纪问题,而与计算机科学息息相关的就是希尔伯特第十问题,“可判定性”。30年代,Alonzo Church和他卓越的学生Alan Turing分别给出了自己的计算模型:λ演算和图灵机。

当然距离主流计算机产业意识到这之间的联系还有一段时间,我们就不拓展这个话题了。

电子计算机出现后的很长一段时间内,依然都是在延续巴比奇的模型:通过指令控制机器。之所以没有成形的编程语言出现,一方面早期计算机的执行效率低,转换和执行编程语言的速度远低于直接解释执行指令。

John Mauchly在1949年设计了Short Code,用于把数学形式的表达式转译成机器指令,这样既方便理解,也方便编写。但其问题在于,每一次执行的时候都有一个前置的转换到机器指令的过程,导致Short Code要比机器指令慢50倍之多。

Alick Glenie在50年代早期实现的Autocode是最早的编译型编程语言之一。与Shortcode运行时在翻译的过程不同,Autocode程序会被预先编译成机器指令,运行时直接执行机器指令就好。而根据Alick的编译器说明书,生成的程序比原始的机器代码只慢“不到10%”。


1952年,IBM发布了其第一台商用机,IBM 701。

之后的1953年,29岁的费城小伙John Backus设计了Speedcoding。跟Autocode和Short Code类似,是一个用高级代码编写IBM 701程序的高级编程语言。

Backus在他的论文中提到,有了Speedcoding以后,花费需要几周才能完成的701程序,只要几个小时就能编写完成。由此虽然带来了比较长的运行时间,但却能节省掉更高的人力成本。

这不仅仅是工作安排上的一个平衡问题,也是后来诞生的软件工程学领域的一个核心问题——总是有人追求靠不断投入人力、拉长时间来解决问题,而不是追求更高效的工作方式。

Backus的这次成功经验直接促成了下一个重要的编程语言的诞生。

1953年末,John Backus向IBM提交了一个建议,为构建IBM 704开发一个更实用的编程语言。基本的想法就是简化数学表达式的输入方式。1954年11月份,IBM Mathematical Formula Translaing System规范草案编写完成。随后的1956年10月,Fortran的说明文档出现,1957年4月,第一个Fortran编译器正式交付。这是第一个正式商用的编程语言,也是第一个优化型编译器:毕竟对于当时的使用者来说,还是希望所使用的高级语言生成的程序,要能够达到跟手写汇编一样的效率。

Fortran团队的一些程序员是国际象棋棋手,因为觉得他们的思维逻辑性更强,于是就被选中作为IBM的雇员。后来的John Backus在接受采访时说,大部分的工作源自于其偷懒的想法:因为不喜欢写程序,所以在给IBM 701写导弹轨迹计算程序的时候,就尝试搞一个可以更方便写程序的程序。而这个思路,也就演变成了随后的Fortran。

Fortran自发布以后就被部分科学家用来编写数值密集型的程序,这也促使编译器作者不断优化编译器,可以生成更快更高效的代码。于是Fortran编译器演进的同时,编译技术也在一起发展:一些早期的优化技术也随之加入进Fortran编译器。

Fortran结构上的创新在于引入了代码块的概念,一个块只有一个入口和一个出口,这样就便于更好的控制程序的逻辑。在此基础上加入了基本的3路IF语句和LOOP语句,以支持分支跳转和循环。注意这里的IF还是比较原始的通过判断数值表达式的结果来进行三路跳转,所以看起来仍然是仍然会感觉很奇怪。直到1962年的FORTRAN IV才加入LOGICAL数据类型(也即bool类型)和基于逻辑结果的IF分支语句。而真正的基于块的IF-ELSE-END IF,则要等到1977年finalize的FORTRAN 77中才有支持。这个时候Fortran才算是填上了结构化编程的最后一块砖。

而这样的一个过程,可以看出Fortran自身也在适应潮流不断发展。这也正是最初就定下来的基调。Fortran几乎是在模块化地添加和丰富自身的特性。FORTRAN II加入了过程式的支持,可以自定义子程序和函数,随后更是一步步地加入了结构化编程(FORTRAN 77)、模块化和泛型编程(Fortran 90)、面向对象编程(Fortran 2003)以及并发和并行编程(Fortran 2008/2018)的支持。这也成了后续标准化的编程语言的一个趋势:后来的Ada和C++都在有这么一个模块化添加和丰富自身特性的过程。

Fortran自身的语法直接影响了很多编程语言的设计,一个典型的例子就是BASIC,基本上就是清理了一部分语法噪音之后的Fortran。其比较直接的定位也相对来说给自己保留了很大的一部分发展空间:科学计算和高性能计算领域,并不需要非常fancy的特性,要的是稳定、高效和能直观表达思路的方法,于是可能我们在很长好一段时间根本看不到Fortran的身影,但依然能在60多年后还能保持更新。

更重要的是作为一个商业化的编程语言,他证明了高级语言是有其市场空间的,所以,接下来就是第一波编程语言潮。

四 IPL 和 FLOW-MATIC

1956 年,来自卡内基理工学院(卡内基梅隆大学的前身)的 Allen Newell、Cliff Shaw 和 Herbert Simon 设计了 IPL。一个用于做信息处理的编程语言。IPL 的语法仍然是类似汇编的指令形式,但其功能上做了很多增强。其包含一个可以用于列表处理等大概进 150 种操作的库,用于进行符号计算和一些高阶的函数式操作,这也使得其成为第一个支持列表处理符号计算高阶函数的编程语言。并且作为一个设计用于多平台的编程语言实现,也是第一个涉及了“虚拟机”概念的编程语言,因此可以在诸如 IBM 704 等机器上运行 IPL 形式的汇编语法。

作为一个擅长符号运算的语言,IPL 最初被用来验证《数学原理》(罗素和怀特海著)中的定理可以通过计算来证明。后来则用于实现一些早期的人工智能程序,如逻辑理论家(Logic Theorist)、通用解题器(General Problem Solver)等。

后来的事情大家就都知道了,人工智能的第一轮捧红的并不是 IPL,而是其继任,LISP


1955 年,在海军少将 Grace Hopper 的带领下,一群人开始设计一种更接近英语的数据处理语言 FLOW-MATIC。

FLOW-MATIC 的名字源自于其前身 ARITH-MATIC,一个由 Grace Hopper 设计的编译器周边工具。最早的版本名字叫 A-0,Arithmetic Language version 0。后面一直扩展到 A-3,并在营销部门的牵头下,改成了 ARITH-MATIC。

由于 Grace Hopper 发现很多专注于业务数据处理的商人们对于数学符号并不感冒,甚至可能不太理解这些东西,她便提议可以设计一套通过英语作为关键字的编程语言,这个编程语言最初的名字叫 B-0(Business Language version 0),随后即改为 FLOW-MATIC。

FLOW-MATIC 是第一个使用类似自然语言的方式表达操作的编程语言,也是第一个把数据和操作专门分开的数据处理系统:除了专门用于描述处理操作的部分之外,还有一个标准的数据定义语言来规范制定输入数据的格式。

这样一套操作后来随机影响了后来那个一直被使用至今的用于“处理业务”的编程语言,COBOL。

在那个时候 Grace Hopper 的这个动机更多的是为了更好的向商业公司推广计算机,但是现如今仍然还是会有人尝试使用自然语言或者是类似自然语言的语法来写程序,就有些南辕北辙了。特别是在作为有更简洁的词法和关键字的情况下还要坚持使用中文字符替换,怕不是在开历史的倒车。

1956年夏,达特茅斯学院(Dartmouth College)举行了一场近八周的工作坊。参与的人有后来被尊为人工智能之父的Allen Newell、Herbert Simon、Marvin Minsky和John McCarthy,还有已经因为信息论成名的Claude Shannon以及因博弈论成名的John Nash。

这次会议定下来了“人工智能”这个名词,并自此开始了一个计算机科学的分支领域。

随后John McCarthy和Marvin Minsky加入了麻省理工学院,创建了Project MAC,随后发展成了MIT AI Lab。1958年,在MIT任教期间的John McCarthy设计了LISP,并被Steve Russell在IBM 704上实现了出来。

单独提一下Steve Russell,他最知名的成就并不是实现了第一个LISP,而是1962年在MIT新安装的DEC PDP-1上开发了已知的最早的电子游戏Spacewar!。1968年秋,Steve Russell在西雅图的湖边学校(Lakeside School)一个变成兴趣组里带了两个平平无奇的学生,教他们使用PDP-10。这两个学生就是后来Microsoft的创始人,Bill Gates和Paul Allen。

说回LISP。诞生于1958年的这门编程语言是现在被过度宣传和被蹭热度最多的,同时,它也拥有最多的方言。并且我感觉编程语言也有“方言”这个概念就是主要来自LISP——毕竟是个用了S表达式(S-expression)的语言都想靠上去亲热一下。

实际上最早的LISP使用的是M表达式(M-expression),即形如car[cons[A,B]]的形式,可以等价地转换成S表达式(car (cons A B))。在Steve Russell实现了LISP以后,大部分程序员都选择S表达式形式,所以M表达式只在后期方言如MLisp中短暂出现过一段时间。不过在80年代末期由Stephen Wolfram拿过去实现了Wolfram Language(Mathematica的核心),也算有了一个好归宿。

LISP如其名,基础即是用来做列表处理的。其主要的两个结构列表的操作对应就是IBM 704的宏操作:car(Contents of the Address part of Register)和cdr(Contents of the Decrement part of Register)。大部分LISP方言依旧沿用这两个符号来获取列表的首元素和首元素以外的列表。

同样因为S表达式的存在,LISP也是第一个其语法本身就是能够被直接作为标准数据结构解析的语言。因此LISP自身有着很强的元编程特性,也促使后面进一步地出现了宏系统和元循环求值器。早在1962年就出现了使用LISP实现的LISP编译器,同时支持混合了编译结果和解释执行的增量编译。

LISP还引入了基于块的分支结构(即后来Algol 60中的if-then-else)和基于引用计数的自动垃圾回收。

然而在人工智能领域之外,LISP并没有得到特别的关注。在MIT发展了一段时间,经历了几个方言和Lisp Machine的失败以后,LISP开始了标准化的道路:多个方言合并成Common Lisp。1994年才完成标准化的Common Lisp,是一个拥有复杂的运行时环境、复杂的求值规则、运行效率底下且生态极度匮乏的编程语言,完全没有赶上新时代的末班车。

少数应用会选择使用LISP的方言做为扩展语言,其中比较知名的由Emacs Lisp(用于Emacs编辑器的扩展)和AutoLISP(即后来的Visual Lisp,用于AutoCAD的扩展)。

而作为LISP另外一个方言系列,Scheme其极简主义设计形成的语言内核比较小巧,非常适合做扩展。不过在90年代出现的一个为了入门方便去掉了S表达式的Scheme实现(指JavaScript)和一个来自巴西的专门用于嵌入设计的极简编程语言(指Lua)直接替代了这些非主流语言的地位。

说起Scheme,我们没有特别提到它的原因,就是因为从时代背景、应用领域和设计哲学方面,与LISP和Common Lisp相关的方言已经有了很大的不同,换句话说也就长得像LISP了。所以与他相关的内容,还是要等到时机合适了再说。

至于2010年前后所谓的LISP Resurgence,也是我前面提到的蹭LISP热度罢了。

1958年五月末,欧美两地的科学家聚集在苏黎世召开了一个关于编程语言的会议,参与者包括John Backus、Alan J. Perlis等人,这次会议的目的也正是为了设计一门能够在欧美两地都能广泛接受的通用语言,最开始这门语言叫做International Algebraic Language,后来被命名为了ALGOL 58。如同FORTRAN一样,ALGOL也是个诡异的缩写,ALGOrithmic Language。

因为Backus的加入,ALGOL 58有了专用的工具来形式化地表现其语法结构,即我们至今仍然在用的BNF,Backus normal form。

看到年份命名就一定要开始习惯了,意味着这个语言后续还会有更多的改进版本。比之于稚嫩的ALGOL 58,两年后在巴黎推出的ALGOL 60要更成熟一些,也加入了更多的对后世影响的元素。

另外,作为ALGOL 60 report的编辑,Peter Naur扩展了Backus的形式规则,在Donald Knuth建议之下,把BNF改成了Backus-Naur Form。

ALGOL引入了代码块的概念,以及begin...end的块状语法结构和词法作用域。这也是为什么实际上(de facto)大部分编程语言都是ALGOL方言的原因。

ALGOL对后来的编程语言影响到底有多大呢?

另外,ALGOL也是早期在中文编程语言领域拓荒过的。不要忘了其初衷是设计一门国际通用语言,所以也便有人探索Chinese ALGOL。1974年来自马里兰大学的Yaohan Chu先生发表了Structure of a direct-execution high-level Chinese programming language processor一文,给出了他设计的整个执行程序。单从其设计看,某些爱国主义程序员落后了可远不止四十多年。

ALGOL所代表的小核心编程语言成了那个时代的特色,ALGOL 60的改进版报告包含完整的标准库也才只有十几页的文档。这一特色由Scheme接棒继承了一段时间。后来的ALGOL 68也正是因为语言设计过于复杂,受到了不少的批评,其中就有来自其委员会的C. A. R. Hoare和E. W. Dijkstra。所以通常提起ALGOL指的都是ALGOL 60,而ALGOL 68才是专门指代ALGOL 68。

至于为什么要从IAL换成ALGOL,据说是因为IAL这个词不太好发音,所以就换成了一个能够读出声来的缩写。

COBOL也是一门年逾花甲的老语言。要不是因为疫情原因某些老旧的系统爆出故障成为大新闻,这门语言也不会再一次出现在人们的视野中。

上个世纪50年代,除了军用领域以外,各大计算机厂商也在探索商用业务。Grace Hopper在FLOW-MATIC等前期实验性的产品成型以后,也准备设计一个更完备的通用编程语言。经过首席设计师 Jean Sammet 一顿操作下来以后,得到的结果就是COBOL(COmmon Business-Oriented Language,通用业务语言)。这个语言也是美国国防部的通用语言计划的一部分,最初推出以后并没有得到多少响应。但在美国国防部的强行推动下,要求每个计算机厂商都要提供支持,于是就被广泛应用在了各种应用系统领域。

因为一定程度上继承了Grace Hopper的FLOW-MATIC,COBOL也采用了类似英语的语法形式。比如现在似乎看起来更自然的赋值语法y = x;,在COBOL中的表示则是MOVE x TO y。其本来设计的用意是为了可以自文档化、可以方便阅读;但因为语法过度复杂而且早期对于结构化编程没有足够的支持,实际并不是那么容易理解。

正如FORTRAN和ALGOL一样,COBOL设计之初也有一个简单的目的,就是作为通用的业务编程语言来处理批量或者事务性的数据。所以在COBOL设计中的基本数据类型只有两种:数值类型和文本类型。因此使用它来解决更加通用的问题可能不太现实,所以更多的是存在于企业业务系统中。

强行推行虽然让COBOL成功火到了70年代,但在那以后就慢慢消退了。一方面来自Edsger Dijkstra等人对结构化编程的推广以及对COBOL的批评对其影响很大,另外一方面,作为ALGOL方言的众多优秀语言不断推出和发展,现实所面临的问题已经远超COBOL所能及的地步。COBOL并没有成为一门通用的编程语言,而是作为一个特性非常鲜明的DSL,活到了现在。

COBOL自身的毛病也很多,因为其缺乏一些良定义的结构和数据类型,所以是千年虫问题的重灾区;作为一个满是单词的编程语言很难清晰地理清楚其固有的结构导致早期模块化和复用困难,GO TO满屏都是(EWD的论文一部分就是在针对这个现象);而且因为语言关键字过多、标准库非常复杂导致了一些兼容性问题。每一个都不是那么致命,但累积起来就成了一身的累赘。

COBOL在目前的使用越来越少,基本上完全变成了只进行维护的状态。而这种“失败”的境地一定程度上也是说明了更贴近自然语言语法的编程语言的不可行性。一个丧失了结构的编程语言也许可以比较自然的吸引一部分人上手,但长期来看维护和发展都将成为问题。

甚至也正是因为COBOL所谓的“面向业务”和其“更像英语”的一些特点,这门编程语言没有吸引到任何学术界的人参与设计。设计委员会的人基本上是政商界人士。这也进一步地限制了其在学术圈(包括大学课堂)上的出场和宣传,更难得到来自这边的反馈和改进。所以直到COBOL 2002,才出现了自定义函数、递归和面向对象等在计算机科学界已经非常常见的特性。

COBOL早期有一些神奇的特性,对后来的影响也比较大。比如ALTER语句,允许你在运行过程中修改代码,能够在混用GO TO 的上下文中改变跳转的目标。这种操作异常危险,因为出现ALTER了以后整个执行流是随着运行时状态改变的,所以理解其执行结果和内容会非常困难。然而仍然不能改变的一点是,这可以看成是早期非常不安全的一种元编程操作,在陆续发展了几十年后成为了各种动态语言的必备特性。

从今年一月份的第一篇文章开始,到现在的 12 个月以来,《圣战简史》——也就是现在的《计算机简史》——已经写(shui)了这是第 19 篇了。在第一篇里我就直接说起来了这个关键的点,所谓的圣战能够存在,就是由于程序员这个群体的宗教性。在各种宗教观点的支持之下没有什么是不会引起冲突的。而从近期的 Rust 社区的很多表现来看,依然如此。

这些人将 Alan Perlis 的忠告置若罔闻。王垠在他的文章《程序员的心理疾病》中也提到了这一问题。线下跟一位朋友聊天也提及了一些观点:国外社区的一些知名人物,特别如 RMSESRLarry Wall 等几个老炮,也都是擅长喊口号的传教士。

用口号吸引人上船,如果能拖得住,就勉强能修得一个正果;如果拖不住,可能就没了。2010 年编程语言文艺复兴以来已经出现过不少例子了:Red Hat 的 Ceylon(2011),CRAY 的 Chapel(2009),专注做 Web Application 的 Opa(2011)、Amber(2011)和 Elm(2012),还有在 ES6 没正式成为标准之前的各种 AltJS,Julia(2012)、Nim(2008)、以及后期的 Zig(2016)和 V(2019),甚至还出现了专门用于 Cloud Native 的 Ballerina(2017)。

形成这一现象的原因有两点,首先 Web/JS 作为一个主要的应用平台兴起,而 JS 作为 Web 时代的汇编语言(甚至后面直接出现了 WebAssembly)成为了一个非常简便并且热门的目标平台;其次各种编译工具和平台如 antlr、llvm 等逐渐拉低造轮子的门槛,让很多人能够相对容易地获得制造一门编程语言的机会:你甚至完全不必了解编译原理是什么——而且本来也不用。

提及这些编程语言不是为了让大家去非得了解他们或者如何,只是想说,这些前仆后继的程序员重新发明轮子方面是不遗余力的。因为一旦这个轮子形成了一个成规模的集体,就可以成为教宗,来主导这个群体。一旦稍微理性地分析一下某个编程语言的问题,就容易被贴上“争论”、“黑”的标签。

本身对编程语言理论和编译技术有所研究,因此我并没有主观上对于这些语言的偏爱。我在没工作之前,就对经常在痛斥 Java 的一些设计上的问题,但工作依然使用 Java 作为主要的技术栈。因为很简单,从团队协作的角度而言,Java 之外的那些编程语言问题更明显。

编程语言领域的绝大部分问题早就在这 60 年内给解决完了。按照业界的一些 PLT 大佬讲,现在工业界应用的无非是七八十年代的研究成果。而众所讨论的各种编程范式也早就在那个时期早已成型。现代的绝大多数编程语言都是多范式的,这一层就不是个值得探讨的问题了。不过依然能够看到很多人在吵 FP 比 OO 好,OO 比过程式(Procedural)好。有函数(子程序、过程)定义就是过程式编程、支持多态的消息传递(message passing)就是面向对象编程、有分支和循环就是结构化编程能够用高阶函数就是函数式编程:这些都在 1960 年以后的那段时间就成型并沉淀了下来,本来就是各取所需,没有优劣。

同时,我们看五十年代这段蛮荒的探索时代,也依然给我们留下了不少的教训。比如自然语言编程这种探索,遗留下的是 COBOL 这个已经没有多少专业人员支持的负担;比如中文编程,所看到的也是一个基于关键字翻译后的原型。现在所有的“自然语言”和“中文编程”,都没办法跳出这个圈儿

如果你能正确认知历史的话就会发现,现在的编程语言无非是组合了其核心开发者的个人口味之后形成的缝合怪:一段时间以后,初期所有不按照历史发展规律的设定所带来的后果,都要在花费巨大的代价来补偿这篇文章中最后提到的问题就是一个例子)。即便是一些社区有非常严格和正规的流程,具体操作下来得到的却也是一个口味极其挑剔的社区年初的 actix-web 事件中,可见一斑。

这倒让我开始思考为什么要写历史来。因为回头看历史通常有这么几个目的:一是从新时代的角度给过去的时间一个评价;二是总结历史经验教训;三则是因为当前发展不顺意,只能靠怀念历史来找自己的存在感

但首先,现在也没有什么突破性的进展,能够让我们进到编程语言和编译技术的新时代,我也没有资格来“评价”什么,所以第一个目的肯定不是了。总结历史经验教训,可能是有一些,但也许现在也没几个人会觉得这是什么重要的事情了:毕竟只要喊口号就有人跟,这个事情做起来太容易,也没人去考虑历史经验能够怎么指导现有的工作了。所以到最后可能也就剩怀古了

1950 年代的几门代表性的编程语言我们已经聊完了,也重点提及了对后面影响比较深的 LISPALGOL。六十年代和七十年代正式确立了编程语言的基础范式,这段时间也是计算机科学发展的黄金时代,无数风云人物在这段时间你方唱罢我登场,奠定了后续这门学科和相关行业坚实的基础。

第二季见。

创建时间:2020-09-14 最近更新时间:2024-07-26