糟糕的科学代码胜过遵循“最佳实践”的代码(2014)

科学研究常常依赖由领域专家编写的快速、一次性的脚本,而专业开发者则倾向于把更重的“最佳实践”和抽象结构带入,即使是很小、很实验性的代码库。评论者争论哪一种更糟:是脆弱、缺乏文档、损害可复现性的科学代码,还是难以理解、修改和适应不断变化研究问题的过度工程系统。许多人最终认为,真正的问题在于激励机制和具体语境,并呼吁在简单性与工程纪律之间取得平衡,同时设立专门的研究软件工程师来弥合这一鸿沟。

对这篇文章的总体反应

  • 许多人把这篇文章看作是一通抱怨或稻草人论证:它用极端例子对比了“糟糕科学家的代码”和“糟糕程序员的代码”。
  • 也有人认为它非常有共鸣,尤其是对过度工程和教条式“最佳实践”的批评。
  • 还有不少人认为,真正该被批评的是“糟糕的程序员”(通常是初级开发者或教条式照搬模式的人),而不是整个软件工程。

科学家 vs. 软件工程师

  • 常见观点是:科学家往往在工程上投入不足(代码凌乱、临时拼凑、一次性脚本);软件工程师往往工程过度(抽象层过多、继承、 “企业级” 模式)。
  • 有人认为科学家通常在自己的领域更聪明,也更适合处理一次性的工具;反对者则指出,领域知识并不能替代软件技能。
  • 多位评论者指出,现实中大量科学代码都有 bug、不可复现,而且一年后往往连运行都做不到。

过度工程、“最佳实践”与复杂性

  • 受到强烈批评的包括:
    • 过度抽象(深层继承、插件系统、许多小文件、层层间接)。
    • 以模式驱动的设计(把“Clean Code”字面化、微函数、蔓延的模块图)。
    • 企业 Java / 重型面向对象作为不必要复杂性的历史来源。
  • 反方观点认为:这些是对最佳实践的滥用,而不是最佳实践本身;好的工程目标是用最简单的设计来支持长期变化。

科学代码中的病态问题

  • 反复出现的问题包括:没有测试、没有版本控制、硬编码路径和数据、缺少文档的构建步骤、硬件使用不当(例如把所有数据都加载进 RAM)。
  • 可复现性被普遍认为很差;有人说这正是重复性危机的基础。
  • 也有人指出,学术界历史上对“手工”复现的要求就不同,并不一定要求一键重跑。

帝国理工学院 COVID 模型示例

  • 一些帖子把它当作警示故事:大型、生命周期很长的科学代码存在严重 bug(非确定性、内存问题、脆弱设计),据称产生了误导性的政策相关结果。
  • 这被当作“快速且粗糙”的研究代码在被重新用于现实决策时可能很危险的证据。

协作与角色

  • 许多人主张设立专门的“研究软件工程师”,在领域知识和工程纪律之间搭桥。
  • 让领域专家与注重可维护性的开发者配对被认为是理想方案,但资金不足;学术界的激励机制更重论文,而不是稳健的软件。