当AI生码越来越流行,我们不妨看下古早程序员是怎么写代码。
在《代码整洁之道:程序员的职业素养》这本书中就有描述,截取片段如下:

大意是作者(即Bob大叔)17岁(1969年)的时候,在一家公司兼职程序员。他先把代码写在纸质的“编码表单”上,然后把编码表单交给打孔员。打孔员再将代码变成一张张的按顺序叠放的打孔卡片。接着作者把一捆打孔卡片交给电脑机房的操作员,工作人员再将打孔卡上的信息录入到电脑中运行。第二天,作者拿回大型机打印出来的运行结果。
那么什么是编码表单,什么是打孔卡,下面我们一一介绍。
编码表单
编码表单(Coding Form)是指一张用来手写代码的表格,如下图所示:

上图完整的表格一共有80列、24行,每一个格子写一个字符,每一行就是一行代码。一个示例如下图所示:

上面代码是Fortran语言,一个比较古老的语言,是打孔卡时代使用的语言。其中第一行为:
|
1 |
C CALCULATE AND TYPE THE ROOTS OF A SET OF QUADRATIC EQUATIONS |
C开头的表示当前行为注释行。这行注释的意思是:计算多组二元一次方程的根。而从第二行开始就是程序的实现代码。注意到上面手写的代码中,Φ表示字母O,用来与数字0区分。这段代码的具体内容如下图所示:

其中,第2行代码表示可以接受A、B、C这3个参数。这3个参数分别表示二元一次方程ax^2 + bx + c = 0的3个参数。最多可以接受100组方程。第18行表示打印输出方程的根(包括实根与虚根)。中间的代码是求解过程。
编码表单的作用是方便打孔员转成打孔卡。那么,什么是打孔卡?
打孔卡
在微型(个人)计算机出现前,当时的大型计算机是没有键盘的,输入需要读取打孔卡(punched card)上的信息。一张IBM计算机的打孔卡如下图所示:

卡片顶部打印的文字:Z(1) = Y + W(1)表示了这张卡片承载的信息。
图中的打孔卡一共有80列,结合前文中编码表格的例子,可分为4块区域:
- 第1列:如果是字母C,则为注释。否则为代码。
- 第2~5列:代码的编号标签,给goto语句跳转使用。
- 第6列:如果是加号,表示表达式太长,拆成了多行,当前行是接着上一行。否则是新的一行表达语句。
- 第7~72列:具体语句内容。也就是说一个卡片最多可以承载66个字符。这张卡片承载的内容为:Z(1) = Y + W(1)。
- 第72~80列:表示当前卡片的编号。因为卡片多了之后,一旦掉地上,顺序乱了,将会是灾难性的。编号可以让卡片排序机重新排序。
上面求解二元一次方程的根的代码一共有22行,所以这个程序需要22张打孔卡。(另外还有一种卡片是二进制卡片,每一列表示一条指令,这里不展开说明)
图中挖了孔的(读卡机的光能通过)表示1,没有挖孔的(读卡机的光不能通过)表示0。每一列最多可以打12个孔,图中所示的0 ~ 9,以及0上面没标注出来的11与12。可以表示数字、字母及标点符号。字符的编码规则如下表所示:

比如数字“5”,就是将5挖孔;字母“A”则是将1与12挖孔;左括号“(”则是将5、8与12挖孔。注意到Fortran语言只有大写字母。
一段程序则会变成一捆打孔卡,一个软件则是由很多捆卡片组成。通过叠放顺序决定运行顺序。如果代码有bug,或者编译出错,则是替换或增加其中的某些卡片。于是就有了阿波罗女程序的这个名场面:

程序的输入可以使用数据卡或者磁带;输出则是直接打印出来,或者输出挖孔卡,作为下一个程序的输入。
打孔机
负责将编码表单转成打孔卡的是打孔机,如下图所示:


可见打孔机是有键盘的。那么为什么大型机不直接配一个键盘录入呢?GPT老师给的解释是,当时的计算机很贵,无法一边等输入一边运行,另一个原因是计算机的存储容量有限,无法存储很多程序,而且使用打孔卡可以让机算机批量处理。让便宜的设备负责录入,让昂贵的计算机负责运行。正如Reddit上有人说:打孔卡在很长一段时间里都是最实用、最便宜的解决方案。
直到后面,打孔卡才慢慢退出历史舞台。一方面,大型计算机配置了电传打字机之类的终端(TSO),可以远程登录到大型机编辑和提交作业,另一方面,半导体技术的发展,促使微型计算机快速发展,不管体积还是价格都比大型机大大下降。
制表机
最开始,在大型计算机出现前,打孔卡就已存在,它是给制表机用的。制表机可以用于计数目的。1880的美国人口普查人工数据处理耗费了8年之久。1890的美国人口普查,霍列里斯发明了制表机,将每个人的信息编码成穿孔卡片上的孔位,然后机器通过电接触检测孔的位置,自动计数,使得统计提前了数月完成,并且降低了耗费的资金。下图为1890时期制作打孔卡的方式:

小结
通过理解了打孔卡的原理,我们看到古早程序利用纸张写代码,借助打孔卡录入到大型计算机中,做各种各样的事情。比如开发会计软件、工资系统,取代手工记账;开发大型洗衣机的运行程序;开发通信行业的终端系统等;甚至是送飞船上月。另外我们看到,几十年来,编程的核心没有变,古早程序员们就已经在写条件判断、循环、队列等,现代编程语言废弃了goto之类的使用,增加了很多高级语言及编程范式,让写代码更舒服。如今的AI编程是大语言模型在学习了几十年来人类的编码后,在一个黑箱中建立起了编程的模式。
从手写代码、打孔编码 -> 使用IDE写自然语言编码 -> 让AI编码,工具的升级,让人越来越得到解放。技术门槛下降,但编程的思想与理念依旧需要得到学习、传承与创新。现在的大模型(LLM)虽然代表着人类知识的总和,但它仍然需要有持续的新材料输入才能不停发展。所以起到关键作用的仍然是人。