机器的语言
在19世纪英国,诗人拜伦的女儿阿达·洛夫莱斯,在1842至1843年间,投入了9个月的时间,翻译了意大利数学家路易吉·米那比亚关于查尔斯·巴贝奇最新计算机设计 — 分析机的备忘录。
她的工作不仅仅是翻译,还包括对米那比亚备忘录的注解,其中她增加了大量自己的见解和算法描述,包括指导机器如何计算伯努利数,这通常被认为是世界上第一个计算机程序算法的原型。因此,阿达也被认为是世界上第一位程式设计师。
然而随着时间的推移,阿达的算法逐渐被人遗忘。直到20世纪中叶,差不多是她死后一百年,电子计算机的诞生,阿达之前对查尔斯·巴贝奇的《分析机概论》所留下的笔记于1953年才被重新公布。
(拜见祖师母)
为纪念阿达,美国国防部还专门制作了一个新的高级计算机编程语言:Ada。
从阿达之后,历史翘首期盼了百年,编程的思想从未停歇。1946年,德国工程师Konrad Zuse在1930年代末到1940年代期间设计并建造了数台机械式的计算机,其中最著名的是Z3计算机,被认为是世界上第一台可编程的计算机之一。下图是Zuse和它的Z3机器。
Zuse和它的Z3机器
Zuse 几乎是凭借一己之力从零发明了现代计算机,在设计和制造世界上Z系列计算机的过程中,意识到需要一种高级语言来简化程序设计,于是他提出了 Plankalkül 的概念。由于第二次世界大战期间的资源限制和战后的经济困难,Plankalkül 并没有得到完全的实现。Zuse 在1945年完成了 Plankalkül 的初稿,但由于缺乏合适的计算机和编译器,这个语言没有得到广泛的应用。
时间到了1946年2月14日,“情人节”,世界上第一台计算机ENIAC诞生,使用的是最原始的打孔卡片,编程语言是一串串的0和1的二进制。在 20 世纪的大部分时间里处于打孔卡时代,程序员需要手动编写或打孔来输入指令,涉及到设置开关和连接电缆来确定计算序列。
上个世纪程序员使用的打孔卡片
直接插拔线路
可以看出,机器语言太 “反人类”了,对于人类来说,二进制程序是不可读的,很难记忆和理解。根本看不出来机器干了什么。为了解决可读性的问题,以及偶尔的编辑需求,就诞生了汇编语言。
面向人的汇编语言
而第一种真正应用于电子计算机上的机器语言则是1949年问世的Short Code语言,又称为short-order code,是1949年由John Mauchly提出并由William Schmitt实现的,它是为BINAC计算机在1949年实现。
但早期的Short Code并不是一个独立的、广泛认可的编程语言,而是一种编程方法或者说是过渡技术,通过一个解释器执行,而不是编译,这使得编程过程大大简化,尽管执行速度较慢。但它允许程序员使用较短的助记符来代表长的机器语言指令,从而提高了编码的效率和可读性。随后IBM在1950年代推出了它的短代码系统,就属于这类技术。
真正第一个汇编程序是符号优化汇编程序(SOAP)系统,是早期为IBM650计算机研制的汇编程序。代表了早期汇编语言程序设计的进步。随着时间的推移,计算机技术迅速发展。其中,Intel公司推出的80×86系列微处理器成为了个人电脑时代的一个标志性成就。这也对汇编语言的需求也发生了变化。程序员开始使用更为先进的汇编器,如MASM和TASM,来编写能够在80×86系列微处理器上运行的汇编程序。
例如,为Intel80x86设计的汇编语言的指令:
- ADD AX,BX :表示将寄存器AX和BX中的内容相加,结果保存在寄存器AX中。
- SUB AX,NUM :表示将寄存器AX中的内容减去NUM,结果保存在寄存器AX中。
- MOV AX ,NUM :表示把数NUM保存在寄存器AX中。
代码如下:
操作:寄存器BX的内容送到AX中
因此,汇编语言可以看作是对机器语言的直接扩展,是二进制指令的文本形式。比如上面的加法指令00000011写成汇编语言就是 ADD。只需要一个能将汇编语言转换成机器指令的工具,我们称其为编译器,将汇编语言还原成二进制,就可以被 CPU 直接执行,所以它是最底层的低级语言。
第一个编译器被认为是由美国计算机科学家格蕾丝·霍珀(Grace Murray Hopper)发明的。她为A-0系统编写了编译器,这是在20世纪50年代初期的工作。
高级编程语言
第一个被广泛认可的高级编程语言是Fortran(Formula Translation),它在20世纪50年代初期由IBM的约翰·巴科斯(John Backus)和他的团队开发。Fortran语言的首个版本发布于1957年,它被设计用于科学和技术计算,特别是为了满足数值分析和工程计算的需求。它包含了一个具备完整功能的编译器,也是编译器历史上的一个重要里程碑。
这之后,编程语言发展迅猛无比。
仅一年,在苏黎世会议上发布了Algol 58,这标志着高级编程语言的诞生。Algol 58的出现不仅引领了编程语言的新潮流,而且对后续语言的设计产生了深远的影响。
紧接着,在1960年,Algol 60的发表进一步巩固了这一趋势,它几乎成为了所有后续计算机语言语法设计的鼻祖,但与同一年,格蕾丝·霍珀发明的COBOL(Common Business Oriented Language)没有太大关系。格蕾丝·霍珀也被誉为COBOL之母。宏(DEFINE)和数据结构(记录)这些概念就是她弄出来的。
接着咱们就不得不重点说说 Lisp 语言了,也是在1960年,由约翰·麦卡锡在麻省理工学院(MIT)的人工智能研究小组中发明,这一语言建立在列表和 lambda 演算的基础上,成为了函数式编程的鼻祖,更是如今 AI 开发顶级编程语言之一,被谓之人工智能研究的“母语”。
著名的人工智能专家彼得·诺维奇(Peter Norvig)在其权威著作《Artificial Intelligence: A Modern Approach》中,深入阐述了Lisp成为AI开发顶级编程语言之一的多个原因。
另外,在《永恒之火》剧中的插曲中,认为上帝必然也是使用 Lisp 创造世界的,可见Lisp语言有多么的受尊敬。歌词是这样描述的:
因为上帝用祂的 Lisp 代码
让树叶充满绿意。
分形的花儿和递归的根:
我见过的奇技淫巧之中没什么比这更可爱。
当我对着雪花深思时,
从未见过两片相同的,
我知道,上帝偏爱那一门
名字是四个字母的语言。
1979年8月的 Byte 杂志封面
随后的1963年,剑桥大学的研究人员发明了CPL(Combined Programming Language),这是一种集多种编程范式于一体的强大语言。
而在1964年,我们见证了两个重要事件的发生:首先是约翰·凯梅尼和托马斯·库尔茨共同开发了BASIC(Beginner’s all-purpose symbolic instruction code),这门语言以其对初学者友好和对硬件要求低而迅速流行;
其次是PL/I的诞生,它作为Algol 60、Fortran IV和COBOL的集大成者,适用于科学计算和商务应用等多个领域。
Matin Richards在1967年对CPL进行了创新性的简化,推出了BCPL(Base Combined Programming Language),这一举措为编程语言的进一步发展铺平了道路。紧接着,在1969年,贝尔实验室的Ken Thompson对BCPL进行了关键性的改进,设计出了B语言,这是一种更为简洁且更接近硬件的编程语言,为C语言的诞生奠定了基础。
到了1970年,以Algol-W为基础,尼克劳斯·维尔特发明了Pascal语言,这距离他离开Algol小组差不多两年的时间。Pascal 这门语言语法严谨,层次分明,程序易写,可读性强,继承了Algol的代码结构、逻辑完整性以及对递归的支持,同时将复杂的东西简化,添加了对复杂和用户自定义数据类型的支持。
维尔特的文章《Program Development by Stepwise Refinement》成为了软件工程领域的经典之作,其中提出的“算法+数据结构=程序”(Algorithms+Data Structures=Programs)的理念。
凭借这些贡献,尼克劳斯·维尔特授获得了1984年的图灵奖,至今仍被奉为计算机科学的圭臬。
随着技术的不断进步,新的编程语言和范式不断涌现,而一些旧的语言则逐渐衰落。这是一个自然的过程,反映了技术发展和市场需求的变化。然而,每一种语言都有其独特的价值和贡献。它们在特定的历史时期,解决了特定的问题,推动了技术的进步。即使一些语言逐渐衰落,它们的思想和设计仍然影响着后来的语言。
本篇最后,插入一个编程语言射自己脚的搞笑段子,来源于外网(部分编程语言还没有介绍到):
C:射你自己的脚。
C++:你不留神生成了一堆你自己的实例,所以只好挨个射他们的脚。因为你不知道哪个是你的真正实例,哪个只是实例的引用。
Fortran:你逐个射你的脚趾,一直循环到射没了所有的脚趾,然后你读入下一只脚并重复之。如果你没了子弹,你也得接着射,因为你没有异常处理机制。
Pascal:编译器不允许你这么干。
Ada:在你仔细地包装好了你的脚后,你试图以并行的方式上子弹,扣扳机,尖叫,并射你自己的脚。然而,当你试了一下后,发现你的脚类型不对。
Lisp:你用拿着枪的四肢拿着的枪射你的拿着枪的四肢。Forth:脚的己自你射
Prolog:你告诉程序你想射你自己的脚。程序会自动找到具体的计划,不过语法上是不允许把这些计划告诉你的。
BASIC:你用水枪射你自己的脚。如果是在大系统中,重复直至你的下半身被水浸没。
Visual Basic:你其实只是装出好象是射了你的脚的样子。不过你觉得这么干更有趣所以也不在乎到底射没射。 Paradox:不但你可以射你自己的脚,你的用户也可以。
汇编语言:你试图射你自己的脚,结果发现你还得先自己来制造出枪支,子弹,瞄准具,和你的脚。