20

我看到了 Edsger Dijsktra 看到的这篇关于编程风格的文章。快速解释一下,主要区别在于莫扎特,当类比到编程时,在写任何东西之前完全理解(有争议的)问题,而贝多芬在将笔记写在纸上时做出了决定,并在此过程中进行了许多修改。使用 Mozart 编程,1.0 版将是软件的唯一版本,其目标是无错误地工作和最高效率。此外,Dijkstra 表示,不应该向公众发布没有达到那种细化和稳定性水平的软件。

根据他的观点,有两个问题。莫扎特编程甚至可能吗?如果我们采用莫扎特风格,我们今天编写的软件真的会受益吗?

我的想法。看来,为了解决软件日益复杂的问题,我们已经从这种方法转向敏捷开发、公共 beta 测试和不断修订等定义 Web 开发的方法,其中速度最重要。但是,当我想到 Web 软件可以经历的所有修订时,尤其是在维护期间,通常会在补丁之上应用补丁,然后通过繁琐的重构过程进行改进——莫扎特的方式似乎很有吸引力。它至少会减少那些烦人的软件更新,例如 Digsby、Windows、iTunes 等,其中许多是需要立即发布新版本的不可预见漏洞造成的。

编辑:有关 Dijsktra 观点的更准确解释,请参阅下面的回复。

4

10 回答 10

52

莫扎特编程风格是一个完整的神话(每个人都必须编辑和修改他们最初的努力),虽然“莫扎特”在这个例子中本质上是一个隐喻,但值得注意的是,莫扎特本身实际上是一个神话。

莫扎特是一个被认为是神奇的神童,他在 4 岁时创作了他的第一首奏鸣曲(他实际上是 6 岁,这很糟糕——你永远不会在任何地方听到它演奏)。当然,很少有人提到他的父亲被认为是欧洲最伟大的音乐老师,他强迫他所有的孩子每天练习演奏和作曲几个小时,只要他们能拿起乐器或钢笔。

莫扎特本人小心翼翼地通过销毁他的大部分草稿来维持他的音乐完全从他的脑海中浮现的错觉,尽管足以证明他是一个和其他人一样的编辑。贝多芬只是对这个过程更加诚实(也许是因为他是聋子,并且无法分辨是否有人偷偷摸摸地接近他)。

我什至不会提到莫扎特的旋律是从听鸣禽获得的理论。或者他创建了一个使用骰子随机生成音乐的系统(这实际上很酷,但也可以解释莫扎特的音乐有多少似乎是从无到有的)。

这个故事的寓意是:不要相信炒作。编程是一种工作,接下来是更多的工作来修复你第一次犯的错误,然后是更多的工作来修复你第二次犯的错误,依此类推,直到你死。

于 2008-11-15T16:02:48.693 回答
15

它没有规模。

我可以在脑海中弄清楚一行代码,一个例程,甚至是一个小程序。但是中型节目?可能有一些人可以做到,但是有多少人,他们要花多少钱?他们真的应该编写下一个工资单程序吗?这就像在 muzak 上浪费了莫扎特。

现在,试着想象一个莫扎特乐队。只是几秒钟。


它仍然是一个强大的工具。如果你能在脑海中找出整条线,那就去做吧。如果你能找出一个包含所有有趣案例的小程序,那就去做吧。

从表面上看,它避免了回到绘图板,因为您没有想到一个边缘案例需要完全不同的界面。

更深层次的含义(假头?)可以通过学习另一种人类语言来解释。很长一段时间,您都在思考哪些词代表了您的想法,以及如何将它们排列成一个有效的句子——转录会花费大量的前台周期。
有一天你会注意到你只是说话的一种解放的感觉。它可能感觉像是“用外语思考”,或者好像“单词自然而然”。你有时会在寻找一个特定的单词或习语时绊倒,但大多数时候翻译是在“潜意识 CPU”的巨大资源中运行的


“高目标”是开发一个(大部分)独立于实现语言的解决方案的心理模型,以将问题的解决方案转录问题分开。转录简单、重复且易于训练,抽象的解决方案可以重复使用。

我不知道如何教它,但是“在开始编写之前尽可能多地弄清楚”听起来像是朝着这个目标的良好编程实践。

于 2008-11-15T16:54:11.320 回答
14

来自 Usenet 的经典故事,关于真正的莫扎特编程。

真正的程序员用 Fortran 编写。

也许他们现在这样做了,在这个充满精简啤酒、手动计算器和“用户友好”软件的颓废时代,但回到过去的美好时光,当时“软件”这个词听起来很有趣,而真正的计算机是由鼓和真空管制成的,真正的程序员用机器代码编写。不是 Fortran。不是老鼠。甚至不是汇编语言。机器码。原始的、朴素的、难以理解的十六进制数字。直接地。

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

我第一次见到梅尔是在我为打字机公司的现已解散的子公司 Royal McBee Computer Corp. 工作时。该公司制造了 LGP-30,一种小型、便宜(按当时的标准)的鼓式存储器计算机,并且刚刚开始制造 RPC-4000,一个大大改进、更大、更好、更快的鼓-内存计算机。核心成本太高,而且无论如何都不会留在这里。(这就是为什么你还没有听说过这家公司或电脑的原因。)

我受雇为这个新奇迹编写 Fortran 编译器,Mel 是我的向导。梅尔不赞成编译器。

“如果一个程序不能重写自己的代码,”他问道,“那有什么好处呢?”

梅尔用十六进制编写了公司拥有的最流行的计算机程序。它在 LGP-30 上运行,并在电脑展上与潜在客户玩二十一点。它的影响总是戏剧性的。LGP-30 的展台每场都座无虚席,IBM 的销售人员站在一起互相交谈。这是否真正出售计算机是我们从未讨论过的问题。

Mel 的工作是为 RPC-4000 重新编写二十一点程序。(端口?那是什么意思?)新计算机有一个一加一寻址方案,其中每条机器指令,除了操作码和所需操作数的地址外,还有第二个地址,指示位置,在转鼓上,找到了下一条指令。用现代的话来说,每条指令后面都有一个 GO TO!把放在帕斯卡的烟斗里抽。

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

“你永远不知道它会把东西放在哪里”,他解释说,“所以你必须使用单独的常量”。

过了很久我才明白那句话。由于梅尔知道每一个操作码的数值,并分配了自己的鼓地址,所以他写的每条指令也可以被认为是一个数值常数。如果它具有正确的数值,他可以选择较早的“加法”指令,并乘以它。他的代码不容易被别人修改。

我将 Mel 的手动优化程序与优化汇编程序处理的相同代码进行了比较,Mel 总是运行得更快。那是因为“自上而下”的程序设计方法还没有发明出来,梅尔无论如何也不会使用它。他首先编写了程序循环的最里面部分,因此他们将首先选择鼓上的最佳地址位置。优化汇编器不够聪明,无法这样做。

Mel 也从未编写过延时循环,即使在笨拙的 Flexowriter 需要输出字符之间的延迟才能正常工作时也是如此。他只是在鼓上找到指令,这样每一个连续的指令在需要时都刚好经过 读取头;鼓必须再进行一次完整的旋转才能找到下一条指令。他为这个程序创造了一个令人难忘的术语。尽管“最佳”是一个绝对术语,就像“唯一”一样,但将其设为相对已成为常见的口头习惯:“不是很理想”或“不太理想”或“不是很理想”。梅尔将最大时间延迟位置称为“最悲观”。

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

梅尔犹豫了。他觉得这显然是不诚实的,事实确实如此,并且它影响了他作为程序员的个人诚信,它确实如此,所以他拒绝这样做。首席推销员与梅尔交谈,大老板也如此,在老板的催促下,几位资深程序员也如此。梅尔终于屈服了,写了代码,但他的测试倒退了,当感应开关打开时,程序就会作弊,每次都赢。梅尔对此很高兴,声称他的潜意识是无法控制的道德,并且坚决拒绝修复它。

在 Mel 离开公司从事更环保的工作后,Big Boss 让我查看代码,看看我是否能找到测试并反转它。有点不情愿,我同意去看。追踪 Mel 的代码是一次真正的冒险。

我经常觉得编程是一种艺术形式,它的真正价值只有另一个精通同样神秘艺术的人才能欣赏;由于过程的本质,有一些可爱的宝石和辉煌的政变隐藏在人类的视野和钦佩之下,有时是永远的。你可以通过阅读他的代码来了解他的很多信息,即使是十六进制的。梅尔是,我认为,一个无名的天才。

当我发现一个没有测试的无辜循环时,也许我最大的震惊来了。没有测试。。常识说它必须是一个闭环,程序将在其中无限循环。然而,程序控制权直接通过了它,并且安全地从另一边传了出去。我花了两个星期才弄明白。

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

相反,他会将指令拉入机器寄存器,将其地址加一,然后将其存储回来。然后,他将直接从寄存器执行修改后的指令。编写循环是为了考虑到这个额外的执行时间——就在这条指令完成时,下一条指令就在鼓的读磁头下方,准备好了。但是循环中没有测试。

当我注意到索引寄存器位(位于指令字中地址和操作码之间的位)被打开时,重要的线索出现了——但梅尔从未使用过索引寄存器,一直保持为零。当灯亮起时,它几乎使我失明。

他将他正在处理的数据定位在内存顶部附近——指令可以寻址的最大位置——因此,在处理完最后一个数据之后,增加指令地址会使其溢出。进位会将操作码加一,将其更改为指令集中的下一个:跳转指令。果然,下一条程序指令在地址位置 0 中,程序愉快地运行了。

我没有与 Mel 保持联系,所以我不知道他是否曾经屈服于自那些早已过去的日子以来冲刷编程技术的变革洪流。我喜欢认为他没有。无论如何,我印象深刻,以至于我放弃了寻找有问题的测试,并告诉大老板我找不到它。他似乎并不感到惊讶。

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

于 2008-11-15T15:46:21.050 回答
14

Edsger Dijkstra 在这段名为“思想纪律”的YouTube 视频中讨论了他对莫扎特与贝多芬编程的看法。

替代文字

该线程中的人们几乎讨论了 Dikstra 的观点是如何不切实际的。我会试着为他辩护一些。

  • Dijkstra 反对公司本质上是在客户身上“测试”他们的软件。 发布 1.0 版,然后立即修补 1.1。他认为该程序应该被完善到“热修复”补丁几乎是不道德的程度。
  • 认为软件应该一蹴而就,或者永远不需要进行更改。 他经常讨论他的设计理念,其中之一是模块化和易于更改。但是,他经常认为,在您完全理解了问题之后,应该以这种方式编写单个算法。那是他纪律的一部分。
  • 在他与程序员打交道的丰富经验之后,他发现,除非程序员突破自己的知识极限,否则他们不会快乐。他说程序员不想编写他们完全并且 100% 理解的东西,因为其中没有挑战。 程序员总是想处于知识的边缘。 虽然他理解程序员为什么会这样,但他表示这并不代表低容错编程。

我相信 Dijkstra 的“纪律”也有一些行业或编程应用。美国宇航局漫游者、医疗行业嵌入式设备(即分发药物等)、某些转移我们资金的金融软件。这些领域没有发布后增量变化的奢侈品,需要更多的“莫扎特方法”。

于 2008-11-15T19:37:38.713 回答
6

我认为莫扎特的故事混淆了交付与开发的方式。贝多芬没有对公众对他的交响曲进行测试。(看看他在第一次公开表演后改变了多少乐谱会很有趣。)

我也不认为 Dijkstra 坚持要在你的脑海中完成这一切。毕竟,他写了一些关于纪律编程的书,这些书涉及到在纸上解决它,并且在他希望看到数学质量的学科的同时,你注意到数学家在解决一个问题时可能会消耗多少纸和黑板吗?

我赞成Simucal 的回应,但我认为莫扎特-贝多芬的比喻应该被抛弃。这个鞋拔子将 Dijkstra 对纪律和理解的坚持推到了一个不属于它的角落。

补充说明:

电视普及不是那么热,它混淆了一些关于音乐创作的东西,一个作曲家在做什么,一个程序员在做什么。用 Dijkstra 自己的话来说,在他 1972 年的图灵奖演讲中:“我们不能忘记,编写程序不是我们的业务;设计将显示所需行为的计算类是我们的业务。” 作曲家可能会发现所需的行为。

此外,在 Dijkstra 的 1.0 版本应该是最终版本的概念中,我们很容易混淆期望的行为和功能如何随着时间的推移而演变。我相信他认为所有未来的版本都是因为第一个版本没有经过深思熟虑并且没有严格可靠地完成,因此过于简单化了。

即使没有上市时间紧迫性,我认为我们现在更好地理解了重要类型的软件随着用户体验以及他们对它的实用目的而发展。明显的反例是游戏(还要考虑戏剧电影是如何开发的)。你认为贝多芬在没有他之前的所有经验和探索的情况下能写出第九交响曲吗?你认为观众能听到它的原貌吗?他应该等到他有完美的奏鸣曲吗?我确信 Dijkstra 没有提出这个建议,但我确实认为他对莫扎特-贝多芬的看法太过分了,无法说明他的观点。

此外,考虑下国际象棋软件。新版本不是因为以前的版本没有正确播放。它是关于利用国际象棋启发式和可用计算机能力的进步。对于这种情况和许多其他情况,认为版本 1.0 是最终版本的想法是不成立的。我理解他反对发布已知不可靠且可能受损的软件是正确的,这些软件的缺陷需要在维护和未来版本中弥补。但莫扎特的反驳对我来说站不住脚。

那么,Dijkstra 是继续驾驶他购买的第一辆汽车,还是那辆汽车的复制品?也许有计划的过时,但其中很多与前几代汽车技术不可能提供甚至考虑的改进和可靠性有关。

我是 Dijkstra 的忠实粉丝,但我认为莫扎特-贝多芬的东西太简单了,也不合适。我也是贝多芬的忠实粉丝。

于 2008-11-15T20:27:38.597 回答
5

我认为使用莫扎特编程似乎是可能的。我知道有一家公司,暴雪,它在软件产品做好并准备好之前不会发布软件产品。这并不意味着暗黑破坏神 3 会在一个令人眼花缭乱的编码过程中从某人的脑海中完整而完整。这确实意味着这就是我们其他人的样子。暴雪将在内部测试他们的游戏,在他们解决所有问题之前不会向世界其他地方展示。大多数公司不采用这种方法,而是宁愿在软件足以解决问题时发布软件,然后在出现问题时修复错误并添加功能。这种方法(在不同程度上)适用于大多数公司。

于 2008-11-15T16:49:37.913 回答
4

好吧,我们不可能都像莫扎特一样优秀,不是吗?也许贝多芬编程更容易。

于 2008-11-15T15:43:36.347 回答
1

如果 Apple 采用“莫扎特”编程,那么今天就不会有 Mac OS X 或 iTunes。

如果谷歌采用“莫扎特”编程,就没有 Gmail 或谷歌阅读器了。

如果 SO 开发人员采用“莫扎特”编程,那么今天就不会有 SO。

如果微软采用“莫扎特”编程,今天就不会有 Windows(嗯,我认为那会很好)。

所以答案是否定的。没有什么是完美的,也没有什么是完美的,包括软件。

于 2008-11-15T15:58:37.220 回答
1

我认为这个想法是提前计划。您至少需要对您正在尝试做的事情以及您计划如何到达那里有某种大纲。如果您只是坐在键盘前,希望“缪斯女神”将您带到您的程序需要去的地方,那么结果可能会相当不平衡,并且您需要更长的时间才能到达那里。

任何类型的写作都是如此。很少有作家只是坐在打字机前毫无想法,然后开始敲打,直到制作出畅销小说。哎呀,我的岳父(一名高中英语老师)实际上为他的信件写了大纲。

于 2008-11-24T14:35:36.247 回答
0

计算的进步值得在这里和那里牺牲荣耀或天才。

于 2008-11-15T16:06:30.153 回答