滩头阵地 - 语言 — 有的已消亡,有的仍活跃

作者:Jon "maddog" Hall

“maddog”,我非常熟悉的声音响亮地传来。它属于我的一个年轻朋友,Eduardo。“你为什么把你的船命名为Agape?是因为这艘船很宽敞吗?”

我停下打磨我的小单桅帆船,面对我的年轻朋友。“不,这个词不是英语,而是拉丁语。它不是要与酿酒用的小水果押韵,而是要表达最高形式的爱。”

Eduardo看了我一会儿,说:“我不知道你还会说英语以外的语言。”

“大多数情况下,我不会”,我回答。“我在小学时学过拉丁语和法语,但在我意识到掌握多种语言有多么有价值时,大部分训练都已经流失了。然而,学习过拉丁语和法语有时确实会派上用场,因为我有时会利用那些被遗忘的训练来理解外语和我的母语英语中的新词。现在,我学习的语言主要是计算机语言。”

“那是另一件事”,Eduardo说。“当您真正需要的只是 Java 时,为什么会有这么多语言?”

我放下砂纸块,靠在Agape上,仔细思考了一会儿。

FORTRAN 是我学过的第一种计算机语言。那是在 1969 年,我通过阅读一本名为Programming the IBM 1130 in FORTRAN的书,并在配备 4,000 字主内存以及读卡器和穿孔机的 IBM 1130 计算机系统上练习来学习 FORTRAN 的。该系统还配备了链式打印机(您可能不想知道那是什么)和笔式绘图仪。请注意,该语言的名称是 FORTRAN,全部大写。那是我们当时的书写方式,因为它代表 FORmula TRANslator,就像 COBOL 代表 COmmon Business Oriented Language 一样。FORTRAN 适用于工程师和科学家,而 COBOL 适用于商务人士。这两种语言都相当出色地完成了它们的工作。

因为我是一名工程专业的学生,也是西方电气公司(贝尔系统成员)的合作学生,所以我学习了 FORTRAN。在某个时候,营销人员认为人们不喜欢名称中的所有大写字母,因此该语言被称为 Fortran。多年来,FORTRAN(始于 1950 年代初期)变成了 FORTRAN II、FORTRAN III、FORTRAN IV,然后开始使用与其更新年份相关的名称。今天,人们正在为 Fortran 2008 的定义而努力。Fortran 是一个很好的例子,说明一种语言(而不仅仅是一个名称)如何发生变化以满足时代的需求。

从我的合作实习期回到德雷克塞尔技术学院(现在的德雷克塞尔大学)后,我开始寻找更多被称为计算机的设备。我在电气工程系的计算机实验室中找到了几台 Digital PDP-8 小型计算机。尽管这些系统有一种类似于 FORTRAN 的小型语言,称为 Focal,但德雷克塞尔的 PDP-8 小型计算机主要使用汇编语言和/或机器语言(机器使用的 1 和 0)进行编程。

我得到了一些关于如何用机器语言为 PDP-8 编程的书籍,并且我自学了如何使用计算机最基本的语言进行编程。对我来说幸运的是,PDP-8 的机器语言非常简单,只有八条基本指令和一个充当“累加器”的主寄存器。每条指令的长度都相同,并且与 12 位的字长匹配,因此 PDP-8 虽然繁琐,但编程起来很简单。PDP-8 无法进行减法运算(更不用说乘法或除法了),因此您必须加上被减数的补码才能进行减法运算。

处理器在前面板上有开关和指示灯,通过拨动这些开关,您可以将程序直接输入到系统的内存中。更重要的是,您可以一次单步执行程序的一条机器语言指令,在机器的累加器和程序计数器(也由控制台上的指示灯指示)上看到每条指令的结果。

当然,大多数人不会通过开关输入他们的整个程序;他们使用 ASR-33 电传打字机将汇编语言的源代码输入到编辑器中,打孔输出源代码纸带,将该纸带输入到汇编器,并(最终)得到一个包含要馈送到计算机的 1 和 0 的目标级纸带。

您的程序的一次周转通常至少需要 45 分钟。读取编辑器(纸带)需要五分钟。接下来,您输入您的程序,进行一些编辑,并将您的程序打孔输出到新的纸带上。然后,您读入三遍汇编器(15 分钟的纸带读取),读入您的源代码程序(假设您的纸带没有撕裂),并将包含您的程序的二进制(纸)带打孔输出。

最后,您将您的二进制纸带读入计算机的内存中,观看程序可能覆盖自身和真实内存中的所有其他内容,然后您重新开始整个过程(在对着编程之神大声咒骂之后)。

但是,这很有趣,也很有挑战性。而且,这是“机器的意志”与纯粹的 1 和 0 逻辑的较量。我被迷住了。

在同一时期,我从电气工程师转变为工程和商业双专业,辅修后来成为计算机科学的专业。我学习了几种不同的语言:Algol、Lisp、PL/I、SNOBOL 和 APL,每种语言在计算机领域都有其特殊的地位。

我记得 SNOBOL 是一种用于字符串处理的语言,虽然我记不太清了,但我记得我当时认为几乎任何输入到 SNOBOL 编译器中的字符串都会生成某种语法正确的程序。我记得我当时认为可能生成的唯一语法错误是缺少 END 语句。

另一方面,APL 是一种非常强大的数组编程语言。它甚至培养了自己的特殊符号集,这意味着您必须将它们绘制在普通键盘的按键侧面,并且(对于 IBM Selectric 打字机)使用专门为 APL 制造的打印头。

在一门关于比较语言设计的课程中,我们的教授给我们布置了一项挑战,即尽可能用最少的 APL 代码行重新实现一个 40 行的 FORTRAN 程序。我们大多数人将 FORTRAN 程序减少到三行 APL 代码,有些人减少到两行 APL 代码。而且,班上最聪明的学生之一(David Erb)熬夜将程序减少到只有一行 APL 代码。这是一行真正令人惊叹的代码。

在向程序输入数据并看到正确的结果后,教授(眼中闪烁着光芒)要求 David 解释程序是如何工作的。David 在几个小时前才完成程序,他拼命想记住程序实际上是如何工作的,但他无法解释他是如何得出那条特定的一行代码,甚至无法解释它将如何产生预期的结果。

作为一个班级,我们经历了我们的第一个“只写”语言。这是在接下来的 38 年里一直被记住的教训——永远不要编写您无法轻易更改或重用的程序。

在计算机科学学位出现之前的日子里,那是一个有趣的时代。它更像是“计算机黑魔法”,计算机由数学系、电气工程系、商学院、物理系等部门拥有。我甚至有一位教授告诉我,我永远无法靠编写软件为生。他是否正确还有待验证。

随着时间的推移,计算机对世界变得越来越重要,大学开始授予计算机科学、计算机工程、网络工程和信息科学学位。我们经历过的理解这些程序的非常痛苦的步骤被形式化为我们现在(通常)称之为计算机科学的东西。

我最终从德雷克塞尔大学毕业,在寻找我的第一份工作时,我决心不使用“高级语言”进行编程,例如 FORTRAN 或 COBOL。我想用汇编语言编程。我拒绝了很多工作,只是为了寻找那个机会。

最终,这个机会降临到我身上:在 Aetna Life and Casualty 的系统编程组中,为 IBM 360 系列计算机(一种我从未见过的汇编语言和计算机系统)使用基本汇编语言 (BAL) 进行编程。他们问我是否可以用汇编语言编程。我说:“当然,只要给我看看书就行了。”

幸运的是,有一本书,Programming the IBM 360 in BAL,在阅读它并在 Aetna 练习了几天后,我开始了在那里为期四年的系统编程生涯——那是我一生中学习了很多东西的时期。

然而,如果我可以这么称呼它的话,多年来一直支持我的一种“语言”是机器代码的 1 和 0。

正是机器代码让我学会了编译器和解释器如何将不同的语言翻译成机器可以遵循的语言。正是机器代码向我展示了可重入和递归语言是如何工作的,以及程序代码中的微小变化如何缩短程序执行的数分钟、数小时甚至数天的时间。

正是对机器代码和机器体系结构的研究让我知道操作系统是如何真正工作的,并让我理解了网络协议。正是机器代码以及查看其源代码让我理解了大端序与小端序以及单精度与双精度的问题。

正是对机器语言的了解让我能够找到编译器在将源代码翻译成 1 和 0 时出错的地方。只懂高级语言的人可能会永远盯着那些高级语言的源代码,而找不到问题所在。

然而,除了短暂地涉足教授机器和汇编语言课程(最后一次是在 1985 年,当时我教授了一门 PDP-11 汇编语言课程,另一种我自己自学的汇编语言),自从 1977 年离开 Aetna 以来,我实际上就没有用汇编语言或机器语言编写过程序。

简单的原因是,用这些低级语言编写程序太耗时,而且容易出错。编译器优化技术已经变得更好,CPU 更快,内存更便宜,人们的时间更昂贵。不要误解我的意思;仍然有很多地方使用汇编语言和机器代码,尤其是在需要绝对最佳性能或最小尺寸的地方。但总的来说,编译器做得相当不错,普通人的头脑不太能适应编写汇编代码的繁琐任务。

然而,当我坐下来用某种现代语言编写一些代码时,我会做两件事

  • 我考虑是否有某种语言可以更好地、更清晰、更易于人工维护的方式来完成该程序。

  • 我考虑该语言可能在机器语言中生成什么,以及更改源代码或算法或数据在内存中的位置是否会影响程序运行的速度。

我的一个朋友 David Mossberger 曾经做过一项关于两个非常大的数组相乘的研究。一种乘法是以标准的线性代数“教科书”方式分析行和列来完成的。第二种乘法考虑了 CPU 和内存的缓存,了解 1 和 0 是如何排列的。第二种乘法在 Alpha 处理器(具有大缓存内存)上花费的时间是前者的四十分之一,而在 Intel 处理器(具有较小缓存内存)上花费的时间是前者的十分之一。

多年来,我接触过许多新语言和许多新技术。我能够理解每一种语言和技术,因为我会停下来思考 1 和 0 正在做什么。在过去的 38 年里,很少有新的计算机技术让我感到困惑。

这就是为什么我反对那些认为 Java(或 Python,或 PHP,或任何您想到的)等高级语言是唯一值得教授的语言,而机器和汇编语言不值得教授给学生的大学。

归根结底,一切都归结为 1 和 0,如果您不知道它们在做什么,以及机器实际上是如何工作的,您就会受制于他人。

在很多方面,机器代码和汇编语言就像拉丁语——可能很少使用,但对于严肃的语言爱好者和程序员来说仍然很有用。

把握当下,来自Agape

Jon “maddog” Hall 是 Linux International (www.li.org) 的执行董事,Linux International 是一个由希望支持和推广 Linux 操作系统的终端用户组成的非营利性协会。Hall 先生自 1969 年开始从事商业计算职业生涯,曾担任程序员、系统设计师、系统管理员、产品经理、技术营销经理和教育工作者。他曾在西方电气公司、Aetna Life and Casualty、贝尔实验室、数字设备公司、VA Linux Systems 和 SGI 等公司工作。他现在是自由和开源软件 (FOSS) 业务和技术问题的独立顾问。

加载 Disqus 评论