个人编程史第二章第二部分

在本系列的最后一篇文章中,我写了关于编程历史的前二十年,该领域的大多数程序员(自学成才的人)是如何自学的。 没有程序员的学校,没有正式的实践,没有知识体系,没有学科可言。 程序员要么从导师那里学习,要么追求自己的直觉和直觉。

说明这个现实一个真正愉快的故事是梅尔的故事,发布到新闻组由埃德·纳瑟于1983年梅尔裸机程序员¹。 实际上,“裸机”的术语文件条目就是这个故事。

如果您不了解以下故事中的每个字词或技术细节,请不要担心,您仍然会喜欢它,而且我相信您会明白的。 这是一个非常友善的舌头在脸颊响应有点自我严重的信到回收真实男人不吃上世纪80年代的基切比喻和有权Datamation杂志杂志的编辑真正的程序员不使用PASCAL ²作者声称FORTRAN是“真正的程序员”将使用的唯一语言。 Pascal是一种非常结构化的语言,也许是所有语言中最结构化的一种。 故事结束后,我将对此进行解释。

梅尔的故事

最近一篇致力于编程的“男子气概”方面的文章提出了一个光头而未变的声明:

真正的程序员用Fortran编写。

在这个轻度啤酒时代,手持计算器和“用户友好”软件时代,他们也许现在就这样做了,但在“旧时代”中,“软件”一词​​听起来很有趣,而Real Computers是由鼓和真空管制成的,真正的程序员用机器代码编写。 不是Fortran。 不是RATFOR。 甚至不是汇编语言。 机器码。 原始的,未经修饰的,难以理解的十六进制数。 直。

为了避免新一代程序员在对这个辉煌过去的无知中长大,我有责任尽我所能描述一代代程序员如何编写代码。 我称他为梅尔,因为那是他的名字。

我去梅尔(Royal McBee Computer Corp.)工作时第一次见到梅尔,这家打字机公司现已倒闭了。 该公司生产了LGP-30,这是一种小型的,便宜的(按当今的标准)鼓式存储计算机,而刚开始生产RPC-4000,这是一种经过改进,更大,更好,更快的鼓式存储设备。电脑。 核心成本太高,而且无论如何也无法保留。 (这就是为什么您没有听说过公司或计算机的原因。)

我被雇用为这个新奇迹编写Fortran编译器,而Mel是我探索奇迹的指南。 梅尔不赞成编译器。

他问:“如果程序无法重写自己的代码,那有什么用?”

梅尔用十六进制编写了公司拥有的最受欢迎的计算机程序。 它在LGP-30上运行,并在计算机展览会上与潜在客户打了二十一点。 其效果始终是戏剧性的。 LGP-30的摊位在每个展会上都挤满了人,IBM销售人员围坐在一起互相交谈。 我们是否从未讨论过这个实际出售的计算机是一个问题。

梅尔的工作是为RPC-4000重新编写二十一点程序。 (端口?这是什么意思?)新计算机具有一对一的寻址方案,其中除操作代码和所需操作数的地址外,每条机器指令还具有第二个地址,该第二个地址指示何处,在转鼓上,找到了下一条指令。 用现代的话说,每条指令后都跟着去! 将* that *放在Pascal的烟斗中并抽烟。

梅尔(Mel)喜欢RPC-4000,因为他可以优化代码:也就是说,在鼓上找到指令,这样一个人完成工作时,下一个就可以到达“读取头”并可以立即执行。 有一个程序可以做到这一点,即“优化汇编程序”,但梅尔拒绝使用它。

他解释说:“您永远不知道它将放置在什么地方”,因此您必须使用单独的常量。

我很久以前才明白这一点。 由于梅尔知道每个操作代码的数值,并分配了自己的感光鼓地址,因此他编写的每条指令也可以视为数字常数。 如果它具有正确的数值,他可以选择一个较早的“加”指令,然后乘以该指令。 他的代码对其他人来说不容易修改。

我将梅尔的手动优化程序与优化的汇编程序输出的相同代码进行了比较,而梅尔的运行速度始终更快。 那是因为还没有发明程序设计的“自上而下”的方法,而Mel也不会使用它。 他首先编写了程序循环的最内部部分,因此它们将成为硒鼓上最佳地址位置的第一选择。 优化的汇编程序还不够聪明,无法做到这一点。

即使笨拙的Flexowriter需要输出字符之间的延迟才能正常工作,Mel也从未编写过时间延迟循环。 他只是将指令放在鼓上,所以每一个连续的指令在需要时都只是“过去”了。 鼓必须再执行一次完整的旋转才能找到下一条指令。 他为这一程序创造了一个难忘的名词。 尽管“最优”是一个绝对术语,例如“独特”,但使其相对成为一种普遍的口头惯例:“不是很理想”或“不太理想”或“不是很理想”。 梅尔称最大延时位置为“最悲观”。

在他完成了二十一点程序并使其运行之后(“甚至优化了初始化程序”,他自豪地说),他从销售部门收到了“变更请求”。 该程序使用了一个优雅的(优化的)随机数生成器来混洗“卡片”并从“卡片组”中进行交易,一些销售人员认为这太公平了,因为有时客户会流失。 他们希望梅尔修改程序,以便在控制台上设置感应开关时,他们可以改变赔率并让客户获胜。

梅尔退缩了。 他认为这显然是不诚实的,而且确实影响了他作为程序员的个人品格,因此他拒绝这样做。 首席销售员与梅尔(Mel),大老板(Big Boss)进行了交谈,并在老板的敦促下,与一些资深程序员进行了交谈。 梅尔终于屈服并编写了代码,但他却倒退了测试,当打开感应开关时,程序就会作弊,每次都赢。 梅尔对此很高兴,声称自己的潜意识是无法控制的道德,并坚决拒绝解决。

在梅尔离开公司以更环保的态度离开之后,大老板让我看一下代码,看看我是否可以找到测试并撤消它。 我有点勉强地同意看。 跟踪梅尔的代码是一次真正的冒险。

我常常觉得编程是一种艺术形式,只有真正精通同一奥术的人才能欣赏它的真正价值。 这个过程的本质使人们看不到可爱的宝石和出色的妙招,有时甚至永远无法掩盖。 您可以通过阅读代码(即使是十六进制的代码)也可以学到很多关于一个人的知识。 我认为梅尔是一个无名的天才。

也许当我发现一个没有测试的无辜循环时,我最大的震惊就来了。 没有测试。 *没有*。 常识说,它必须是一个闭环,程序将在其中无限循环。 但是,程序控制直接通过它,并安全地从另一端通过。 我花了两个星期才弄清楚。

RPC-4000计算机具有称为索引寄存器的真正现代化的功能。 它允许程序员编写程序循环,该循环使用内部的索引指令。 每次通过时,索引寄存器中的数字都会添加到该指令的地址中,因此它将引用系列中的下一个数据。 他只需要每次都增加索引寄存器。 梅尔从未使用过它。

取而代之的是,他会将指令拉入机器寄存器,在其地址中添加一个,然后再存储回去。 然后,他将直接从寄存器执行修改后的指令。 编写该循环是为了考虑到这一额外的执行时间-就像该指令完成时一样,下一条指令正好在感光鼓的读取头下方,可以开始使用。 但是循环中没有测试。

当我注意到索引寄存器位(位于指令字中的地址和操作代码之间的位)被打开时,最重要的线索就出现了-但梅尔从未使用索引寄存器,一直使它为零。 当光亮时,我几乎看不见了。

他将正在处理的数据放置在内存顶部附近(指令可以寻址的最大位置),因此,在处理完最后一个数据之后,增加指令地址将使其溢出。 进位将向操作码添加一个,从而将其更改为指令集中的下一个:跳转指令。 果然,下一条程序指令位于地址0处,程序顺利进行。

我没有与Mel保持联系,所以我不知道他是否曾经屈服于自从那些漫长的日子以来淹没在编程技术中的大量变革。 我喜欢认为他没有。 无论如何,给我留下了深刻的印象,我放弃了寻找令人讨厌的测试,并告诉大老板我找不到它。 他似乎并不感到惊讶。

当我离开公司时,如果您打开正确的感应开关,二十一点程序仍然会作弊,我认为应该是这样。 我对破解Real Programmer的代码感到不自在。

梅尔·凯伊(Mel Kaye),站在右边。

正如这个故事很好地说明的那样,前几代程序员已经习惯了使用特有的方法和高度个性化的编程风格来按自己的意愿进行操作。 有时候,他们之间对学者及其为促进结构化程序设计所做的努力感到不满。

为了使非程序员的读者受益,结构化编程的概念与编程语言紧密相关,因此人们称其为“结构化编程语言”,有时也简称为“结构化语言”。 在非结构化语言中,代码的格式不会为我们提供有关控制流 (执行语句或指令的顺序)的任何线索。 这是用伪代码 (不是用任何特定计算机语言编写的程序的描述)写成的样子:

1 START PROGRAM2 GET list_of_names from user3 COUNT = number of items in list_of_names4 READ first item from list_of_names5 DO thing a6 DO thing b7 IF result of thing b is TRUE GOTO line 118 DO thing c9 DO thing d10 END IF11 DELETE first item from list_of_names12 SUBTRACT 1 from COUNT13 IF COUNT = 014 EXIT15 END IF16 GOTO LINE 417 END IF18 END PROGRAM

只要列表中有要处理的名称,该代码就会循环,并且如果第7行的结果“评估”为TRUE,它将跳过第8和9行。 只需看一眼,该代码的结构就不会告诉您。 您必须逐行阅读才能知道。 即使这样,也没有线索告诉您第8行和第9行是特殊情况,“事物b的结果”通常为TRUE。

“结构化语言”将是不提供GOTO指令(上面的第7和16行),而是提供更高级别的概念(如WHILE和FUNCTION)的语言,如下例所示:

START PROGRAMGET list_of_names from user

WHILE list_of_names is not empty    READ first item from list_of_names    DO thing a    DO thing b

IF result of thing b is TRUE        DO somethingSpecial    END IF

DELETE first item from list_of_namesEND WHILE

FUNCTION somethingSpecial    DO thing c    DO thing dEND FUNCTION

END PROGRAM

这两个示例执行相同的操作; 但是,结构化编程的支持者认为,第二种方法更具可读性,较少出错,并且易于编写/更快,因此提高了生产率。 尤其重要的是可读性,因为在发生这种情况时,程序员要花更多的时间来阅读已经编写的代码(即使是自己编写的代码),而不是编写代码。³

六十年代,迪克斯特拉发表了七篇论文。 在1996年对一千多名计算机科学教授进行的民意测验中,其中四篇论文被选为有史以来有关计算机科学的38篇最具影响力的论文之一。 但是到目前为止,他最知名的贡献是为保护结构化编程而写的一小段短五页的信,该信于1968年发送给当时计算机科学领域的领先期刊《计算机协会杂志的编辑。 迪克斯特拉(Dijkstra)给这封信写了一个不切实际的标题: “反对Goto声明的案例” ,但编辑Niklaus Wirth(于1970年创建Pascal)使用当时流行的新闻陈词滥调地将标题更改为“ Go To Statement About Harmonful

给编辑的这封信引发了至少二十年的争论,并且(可能)仍然是有史以来最知名的(但也许读得最少的)计算机科学文章。 寻找当代的引文和讨论不必走远。 该出版物在许多方面都具有重要意义,尤其是它引发了最早的(也许是第一个) 好家伙其中宗教战争 真正的程序员不使用PASCAL梅尔的故事都只是小例子。 从1970年起,狂热的倡导和极权主义者对竞争性概念模型的至高无上的主张将标志着编程的进步。

编程(可能比其他任何应用科学都重要)激发了对完美和纯净的狂热追求。 弗雷德·布鲁克斯(Fred Brooks)提出,这可能是由于以下事实:“ 与诗人一样,程序员的工作仅与纯粹的思想观念有所不同。 他通过发挥想象力在空中空中建造城堡。 很少有创作媒体如此灵活,易于抛光和返工,因此能够实现宏伟的概念结构。”⁹

商业内幕 》 ( Business Insider)在2015年发表的一篇文章对“ 为什么程序员在编程语言上陷入'宗教战争' ”这一浪漫的解释,说:“ ……每种编程语言都代表着一种哲学,就像代表一种产品一样。”

自从发表《认为有害的声明》以来,就没有缺乏发动战争的理由。 在其出版之前,仅创建了200种语言,但是从那时起,又产生了数千种语言。

在本系列文章中,我将不再写许多重要的语言,因为我特别关注企业IT和IT项目失败。 例如,我喜欢Python和Ruby语言,但是它们在公司IT和项目失败中没有扮演重要角色。 相反,您会发现研究人员正在使用Python进行数据挖掘和人工智能。 而且,Python和Ruby都经常出现在Google,Dropbox或Uber这样的互联网公司中,而在创业公司中也很常见。

照明和边缘

我认为1949年后的头二十年是编程的黑暗时代。 从那时起,没有多少历史文献可供编程 。 有关计算机本身的历史文档很多。 如我先前所写,硬件工程受到高度尊重和认可。 电气工程行业的组织得很好,有据可查,并且被认为非常重要。 然而程序员却默默无闻。

典型的程序员是自学成才的,具有高度的内在动力。 除了少数年轻的神童外,程序员比以前受过高等教育的可能性更高,他们通常拥有硕士或博士学位,这就是他们成为计算机附近的任何事物的开始。 他们往往是非常聪明的一群。

没有程序员的学校或课程,而当计算机花费数百万美元时,就不会有临时的程序员。 仅仅由于当时成为一名程序员有多么困难,它们才是人类最耀眼的光芒。

对于我们所知道的每一个Dijkstra或Knuth或Wirth,都有一千个Mels,它们创造出纯净的天才,优雅和稀有之美的作品,这些东西将永远丢失,因为磁带和打孔卡保留了最深刻的思想。隐藏的一代变得过时了,被毫不客气地装在了盒子里,看不见了。“程序员的麻烦是,你永远不能说出程序员在做什么,直到为时已晚。”

〜西摩·克雷
克雷超级计算机的发明者

<-上一章

下一章->

[1] Post,Ed(1983年7月)。 “真正的程序员不使用Pascal” 数据化 原始内容 存档 于2012-02-02)。 “……真正的程序员使用FORTRAN。 吃乳蛋饼的人使用PASCAL…”

[2] Martin,Robert C.和Lei Han。 干净的代码。 电子工业出版社,2012

[3] http://www.catb.org/jargon/html/H/holy-wars.html

[4] Brooks,Frederick P. 神话般的月刊和其他有关软件工程的文章 。 教堂山,北卡罗来纳大学教堂山分校计算机科学系,1974年,第21页

[5] http://www.businessinsider.com/why-coders-get-into-religious-wars-over-programming-languages-2015-6

本文是我即将出版的《混沌工厂》一书的节选,该书解释了为什么大多数公司和政府无法编写“有效”的软件,以及如何对其进行修复。

From: https://hackernoon.com/the-second-decade-of-programming-all-about-real-programmers-2556758b5e51

编程的第二个十年:关于Real™编程器的全部相关推荐

  1. gdiplus::real_编程的第二个十年:关于Real™编程器的全部

    gdiplus::real 个人编程史第二章第二部分 在本系列的最后一篇文章中,我写到了在编程历史的前二十年中,该领域的大多数程序员(即编写在现实生活中使用过的程序的程序员)是自学成才的. 没有为程序 ...

  2. python对象编程例子-python(十二)面向对象编程、类

    面向对象编程 面向对象--Object Oriented Programming,简称oop,是一种程序设计思想.在说面向对象之前,先说一下什么是编程范式,编程范式你按照什么方式来去编程,去实现一个功 ...

  3. 歌词big big no_编程的第二个十年:Big Iron

    歌词big big no 个人编程史的第二章 恐龙在地球上漫游¹ 第一台计算机一天要花费数百万美元,相当于今天的数千万美元. 促使他们成立的公司一年最多只能卖出几十个. 计算机本身(称为大型机)和制造 ...

  4. C语言编程>第二十周 ② 下列给定程序中,函数fun的功能是:求出数组中最大数和次最大数,并把最大数和b[0]中的数对调、次最大数和b[1]中的数对调。

    例题:下列给定程序中,函数fun的功能是:求出数组中最大数和次最大数,并把最大数和b[0]中的数对调.次最大数和b[1]中的数对调. 注意:不要改动main函数,不能增行或删行,也不能更改程序的结构. ...

  5. C语言编程>第二十二周 ④ 从键盘输入一组小写字母,保存在字符数组str中,请补充fun函数,该函数的功能是:把字符数组str中字符下标为偶数的小写字母转换成对应的大写字母,结果仍保存在原数组

    例题:从键盘输入一组小写字母,保存在字符数组str中,请补充fun函数,该函数的功能是:把字符数组str中字符下标为偶数的小写字母转换成对应的大写字母,结果仍保存在原数组中. 例如,输入 " ...

  6. C语言编程>第二十二周 ⑥ 请补充fun函数,该函数的功能是:把字符下标能被2和3同时整除的字符从字符串s中删除,把剩余的字符重新保存在字符串s中。

    例题:请补充fun函数,该函数的功能是:把字符下标能被2和3同时整除的字符从字符串s中删除,把剩余的字符重新保存在字符串s中.字符串s从键盘输入,其长度作为参数传入fun函数. 例如,输入 " ...

  7. C语言编程>第二十六周 ⑥ 请补充fun函数,该函数的功能是:按 “0”到 “9”统计一个字符串中的奇数数字字符各自出现的次数,结果保存在数组num中。注意:不能使用字符串库函数。

    例题:请补充fun函数,该函数的功能是:按 "0"到 "9"统计一个字符串中的奇数数字字符各自出现的次数,结果保存在数组num中.注意:不能使用字符串库函数. ...

  8. C语言编程>第二十二周 ③ 下列给定的程序中,函数fun的功能是根据整型形参n,计算如下公式的值:

    例题:下列给定的程序中,函数fun的功能是根据整型形参n,计算如下公式的值: 例如,若n=1000,则应输出0.000155. 注意:不要改动main函数,不能增行或删行,也不能更改程序的结构. 代码 ...

  9. C语言编程>第二十六周 ① 函数fun的功能是:将形参b所指数组中的前半部分元素的值和后半部分元素的值对换。形参n中存放数组中数据的个数,若n为奇数,则中间的元素不动。

    例题:函数fun的功能是:将形参b所指数组中的前半部分元素的值和后半部分元素的值对换.形参n中存放数组中数据的个数,若n为奇数,则中间的元素不动. 例如,若a所指数组中的数据依次为:11 22 33 ...

最新文章

  1. Session原理、安全以及最基本的Express和Redis实现
  2. NestedScrolling CoordinatorLayout
  3. dragsort html拖拽排序 的应用
  4. Python2.7连接MySQL5.7 附demo
  5. ubuntu下载工具aria2 uGet
  6. android tabhost黑色背景,android更改FragmentTabHost背景和文本颜色
  7. day059-60 ajax初识 登录认证练习 form装饰器, form和ajax上传文件 contentType
  8. svn服务端及客户端搭建和使用(一)
  9. Himall商城枚举帮助类EnumHelper(3)
  10. yii2 smarty php,YII2 整合smarty
  11. php 时间 增加天数,php实现当前时间加天数的方法
  12. Warbler, A Little Birdie To Introduce Your Rails App To Java
  13. Kaldi的安装与测试
  14. 华大单片机开发板HC32L13X上手入门
  15. [css选择器] 后代选择器
  16. 循环-05. 兔子繁衍问题(15)
  17. python股票查询系统_使用python获取股票的上市日期等基本信息
  18. torch.repeat()与numpy.repeat()和 numpy.tile()比较
  19. 如何为Github Pages设置动态的背景图片?
  20. 高等代数--多项式与线性空间

热门文章

  1. 虚拟内存(为什么要有虚拟内存)
  2. 软件工程应用与实践(1)——项目简介,小组分工
  3. C# 开发企业内部微应用接入钉钉获取用户信息
  4. javascript 中innerHTML的用法
  5. mysql 缓冲区溢出_MariaDB缓冲区溢出漏洞
  6. Android UI(ToggleButton)详解
  7. Webpack 安装css-loader和style-loader报错
  8. STM32 的核心Cortex-M3 处理器
  9. 竟然有删不了的文件夹?
  10. 【计算机网络】计算机网络、互联网、互连网、因特网、万维网