【问题标题】:Understanding Dijkstra's Mozart programming style了解 Dijkstra 的莫扎特编程风格
【发布时间】:2010-09-22 12:04:46
【问题描述】:

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

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

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

编辑:有关 Dijsktra 观点的更准确解释,请参阅 the response below

【问题讨论】:

  • 比喻不好。 Dijkstra 从不提倡只在你的头脑中 来解决所有问题。他提倡使用形式化的方法(这是可靠的,因为逻辑已经很好理解并且永远是相同的)来构建程序,而不是我们通常在行业中看到的“先程序,后测试”的方法。只有在程序被正式证明满足需求后,才应该对其进行编程。这样一来,错误和“迭代”就被限制在论文中,从未真正实施过。
  • @Eduardo:谢谢并更新。

标签: coding-style dijkstra


【解决方案1】:

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

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

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

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

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

【讨论】:

    【解决方案2】:

    它无法扩展。

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

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


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

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

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


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

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

    【讨论】:

    • Dijkstra 也谈到了这一点,如果你愿意阅读他写的任何东西的话。他说我们把事情分成更小的部分,理解每一部分,然后理解整体。大多数程序员和计算科学家几乎无法处理这些小问题!
    【解决方案3】:

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

    真正的程序员用 Fortran 编写代码。

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

    免得全新一代 程序员在无知中长大 这光辉的过去,我义无反顾 描述,尽我所能通过 代沟,真正的程序员如何 写了代码。我会叫他梅尔,因为 那是他的名字。

    我第一次见到梅尔是在我上班的时候 对于 Royal McBee Computer Corp., 现已解散的子公司 打字机公司。该公司 制造了 LGP-30,一个小型的, 便宜(按照当时的标准) 鼓记忆电脑,刚刚 开始生产 RPC-4000, 大大改进、更大、更好、更快 -- 鼓记忆计算机。核心成本太高,而且不会留下来, 反正。 (这就是你没听过的原因 公司或计算机。)

    我受雇编写 Fortran 这个新奇迹和梅尔的编译器 是我的奇迹指南。梅尔 不赞成编译器。

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

    梅尔用十六进制写了 最流行的计算机程序 公司拥有。它在 LGP-30 上运行 并有潜力地玩二十一点 电脑展上的顾客。它的 效果总是戏剧性的。 LGP-30 每次展会的展位都挤满了人,而且 IBM 的销售人员站着说话 对彼此。不管这 实际销售的计算机是一个问题 我们从未讨论过。

    Mel 的工作是重写 RPC-4000 的二十一点程序。 (港口?那是什么意思?)新的 计算机有一个一加一寻址 方案,其中每台机器 指令,除了 操作码和地址 需要的操作数,有第二个地址 这表明在哪里,在旋转 鼓,下一条指令是 位于。用现代的话来说,每 单个指令后跟一个 去!将 that 放入 Pascal 的管道中,然后 抽它。

    Mel 喜欢 RPC-4000,因为他 可以优化他的代码:也就是说, 找到滚筒上的说明,以便 就在一个人完成工作时, 接下来将是刚刚到达 “读头”,可用于 立即执行。有一个 程序来完成这项工作,一个“优化 assembler”,但 Mel 拒绝使用它。

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

    过了很久才明白 那句话。自从梅尔知道 每个操作的数值 代码,并分配了他自己的鼓 地址,他写的每一条指令 也可以认为是数字 持续的。他可以早一点 “加”指令,说,和乘 由它,如果它有正确的数字 价值。他的代码不容易 别人来修改。

    我比较了梅尔的手工优化 具有相同代码的程序被按摩 通过优化汇编程序, 梅尔总是跑得更​​快。那是 因为“自上而下”的方法 程序设计尚未发明 然而,梅尔不会使用它 反正。他写了最里面的部分 他的程序首先循环,所以他们 将获得最优的第一选择 地址鼓上的位置。这 优化汇编器并不聪明 这样做就够了。

    Mel 从来没有写过延时循环, 或者,即使是在鲁莽的时候 Flexowriter 之间需要延迟 输出字符正常工作。他 刚刚找到鼓上的说明 所以每一个连续的都只是过去 需要时读取头;这 鼓必须执行另一个完整的 寻找下一个革命 操作说明。他创造了一个 这个过程令人难忘的术语。 虽然“最佳”是绝对的 术语,如“独特”,它变得普遍 口头练习使其相对: “不太理想”或“不太理想” 或“不是很理想”。梅尔叫 最大延时位置“最 悲观”。

    在他完成二十一点之后 程序并让它运行,(“即使 初始化程序已优化”,他说 自豪地)他收到了来自 销售部。使用的程序 一个优雅的(优化的)随机数 生成器洗牌“牌”和 从“甲板”交易,以及一些 推销员觉得这太公平了,因为 有时客户会流失。他们 想让梅尔修改程序, 在感测开关的设置 控制台,他们可以改变 赔率,让客户赢。

    梅尔犹豫了。他觉得这显然是 不诚实,它是,它 影响了他的个人诚信 一个程序员,它做到了,所以他 拒绝这样做。首席推销员 和梅尔谈过,大老板也是 而且,在老板的催促下,几个 程序员同行。梅尔终于给了 并写了代码,但他得到了 向后测试,并且,当感觉 打开开关,程序 会作弊,每次都赢。梅尔 对此很高兴,声称他的 潜意识不受控制 合乎道德,并坚决拒绝修复 它。

    在梅尔离开公司后 更环保的 pa$ture$,大老板问 我看看代码,看看我是否 可以找到测试并扭转它。 我有些不情愿地同意了 看。追踪梅尔的代码是真实的 冒险。

    我经常觉得编程是 一种艺术形式,其真正价值只能 被另一个精通的人欣赏 同样的奥术;有可爱的 隐藏的宝石和精彩的政变 人的看法和钦佩,有时 永远,由本质上的 过程。你可以学到很多关于 个人只是通过阅读他的 代码,即使是十六进制。梅尔是,我 想想,一个无名的天才。

    也许我最大的震惊来自于我 发现了一个没有 在里面测试。没有测试。 。常见的 感觉说它必须是一个闭环, 程序会在哪里循环, 永远,无穷无尽。程序控制 然而,直接通过了它,并且 安全地离开另一边。我花了 两周时间搞清楚。

    RPC-4000 计算机有一个真正的 称为索引的现代设施 登记。它允许程序员 编写一个程序循环,该循环使用 内部索引指令;每一次 通过,索引中的数字 寄存器被添加到地址 那条指令,所以它指的是 系列中的下一个数据。他有 只增加索引寄存器 每次通过。梅尔从来没有用过。

    相反,他会取消指令 进入机器寄存器,加一 它的地址,并将其存储回来。他 然后将执行修改后的 指令权从寄存器。 循环是这样写的 花费了额外的执行时间 考虑到——就像这样 指令完成,下一个是 就在鼓的读音头下面, 准备好出发。但是循环没有测试 在里面。

    当我注意到 索引寄存器位,放置的位 地址和操作之间 指令字中的代码,是 打开——但梅尔从未使用过 索引寄存器,将其全部归零 时间。当灯亮起时 差点把我弄瞎了。

    他找到了他正在处理的数据 在内存顶部附近—— 最大的位置说明 可以解决 - 所以,在最后 数据被处理,递增 指令地址会使它 溢出。进位会加一 操作代码,将其更改为 指令集中的下一个:a 跳转指令。果然, 下一个程序指令在 地址位置零,和程序 一路高高兴兴。

    我没有和梅尔保持联系,所以我 不知道他有没有屈服过 被冲刷的变革洪流 编程技术,因为那些 久违的日子。我喜欢认为他 没有。无论如何,我印象深刻 足够我放弃寻找 冒犯测试,告诉大老板我 找不到它。他好像没有 惊讶。

    当我离开公司时,二十一点 如果你程序仍然会作弊 打开右感应开关,并且 我认为应该是这样。一世 不喜欢破解 真正的程序员的代码。

    【讨论】:

    【解决方案4】:

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

    这个帖子中的人们已经讨论了 Dikstra 的观点是多么不切实际。我会试着为他辩护一些。

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

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

    【讨论】:

    • 很好的答案。你的第三点是一件非常有价值的事情,需要保持警惕。
    • 这是否可以解释为,“实验和‘玩耍’是可以的,只要你用它来弄清楚你以后要交付什么,而不是交付实验?不是那种实验的水平是,“提供可以欺骗客户一段时间的东西......”
    • 有计算机科学,也有软件交付,两者不一样。客户测试软件似乎已经演变为当前市场的必要(和邪恶)部分。对于成功的软件产品来说,漂亮、高效、优化的算法可能是必要的,但还不够。
    • 嗯,你有很好的观点。莫扎特编程有它的用处,但这并不是说发布可能有错误的东西(在非关键应用程序中)是 100% 坏的,原因有两个:1,你必须在某个时候把它拿出来,2 ,用户可能是现有的最有效的错误发现工具:)
    【解决方案5】:

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

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

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

    补充说明:

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

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

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

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

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

    我是 Dijkstra 的忠实粉丝,但我认为莫扎特-贝多芬的东西过于简单化和不恰当。我也是贝多芬的忠实粉丝。

    【讨论】:

    • 我同意。我不认为 Dijkstra 是反增量变化。他反对发布未完成/糟糕的软件。我认为他的莫扎特/贝多芬类比是断章取义的。他不希望我破解/削减问题,而是有条不紊地理解和设计稳定的软件。
    • 伟大的台词:“贝多芬没有对公众进行他的交响曲测试”。
    【解决方案6】:

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

    【讨论】:

    【解决方案7】:

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

    【讨论】:

      【解决方案8】:

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

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

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

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

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

      【讨论】:

        【解决方案9】:

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

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

        【讨论】:

          【解决方案10】:

          计算方面的进步值得为荣耀或天才做出牺牲。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-08-04
            • 2014-05-10
            • 1970-01-01
            • 2011-06-18
            • 1970-01-01
            • 2014-01-08
            相关资源
            最近更新 更多