爲何糟糕的科研代碼勝過嚴格遵循編程規範的代碼

【CSDN 編者按】懶惰是許多問題的根源,許多程序員有太多的時間,他們用這些時間沉迷於“API 設計”,於是就產生了怪物。

本文經授權轉載自寶玉老師的個人博客(微博@寶玉xp ),鏈接https://baoyu.io/translations/software-engineering/why-bad-scientific-code-beats-code-following-best-practices

原文鏈接:https://medium.com/@mbostock/what-makes-software-good-943557f8a488

作者 | Proper Fixation

出品 | baoyu.io

我剛讀了一篇名爲“科學代碼的低質量”的文章,作者認爲科學家編寫的代碼質量不如“軟件工程師”的情況。

在過去的十多年裡,我一直在一個以數學或物理背景人士爲主的環境中工作,這裡的人對“軟件工程”的瞭解相對有限。

一直以來,最大的混亂往往是那些自認爲是程序員的少數人造成的。我必須承認,自己也曾製造過幾次大混亂,而這些混亂至今還未得到解決。還有幾次其他的大混亂,幸好代碼被廢棄了,這意味着給我的僱主造成的損害僅限於我薪水的浪費,沒有對他人的工作效率產生負面影響。

我聲稱自己基本上已經改過自新了。我努力保持事情的簡單無聊,並且我認爲在過去 5-6 年裡,我沒有做過什麼讓許多人因爲處理我錯誤的聰明創意而奇怪地看着我。

我也知道一些程序員明確地沒有改過自新。人們怪異地看着他們,而他們則認爲自己是對的,是其他人瘋了。

同時,那些不是程序員,但更像是數學家、物理學家、算法開發者、科學家等人,通常會犯以下幾種錯誤:

函數過長

取名不佳(如 m、k、longWindedNameThatYouCantReallyReadBTWProgrammersDoThatALotToo)

隨處訪問 – 全局變量/單例、“全能對象”等

崩潰(空指針、邊界錯誤),主要依靠 valgrind 和大量測試來減輕

對並行編程錯誤的漠不關心(幾乎完全依靠工具解決)

過於輕易地使用那些由聰明的程序員編寫的庫,這些庫中充滿了重載操作符和模板等複雜內容

我覺得這些還算可以處理。如果有人需要我的幫助來調試某些東西,我通常能夠理解這些人在軟件方面想要做什麼。在算法層面,我可能不完全理解他們。但是他們想把哪個變量傳遞給哪個函數,我通常都能明白。

而軟件工程師的錯誤則完全不同:

複雜的多重/虛擬繼承

主要由輕量包裝構成的 7 到 14 層棧幀,其中包括函數指針/虛函數,可能還在中斷處理程序中

文件散佈在無數目錄中

使用來自地獄的動態結構進行查詢 - 如運行時拼接各種部分形成的名稱的字典等

動態加載和其他難以追蹤的技術

一系列近乎相同的名稱,如 DriverController、ControllerManager、DriverManager、ManagerController、controlDriver 等,它們相互調用

模板調用重載函數,希望在模板定義的地方可見聲明,或許不可見

使用裝飾器、元類、代碼生成等技術

其結果是,你不知道誰調用了什麼或爲什麼,調試器的作用有限,集成開發環境和搜索工具幾乎

無法使用。你幾乎不得不放棄理解這一切,直到淚水不自覺地流出。

當然,這是一個誇張的描述,不是每個人在任何時候都是罪人,而且我主要是一名“程序員”而不是“科學家”,我真誠地認爲我的工作總體上是有積極成效的 - 但你應該明白我的意思。

科學代碼能從更好的“軟件工程”中受益嗎?也許可以,但我不相信軟件工程師能帶來這些益處!

簡單的思維、無憂無慮的近乎無能有時可能比滿懷好意卻鋪設了通往地獄的高速公路的工業級專業更爲有益。計算機外的“真實世界”充滿了這樣的例子。

哦,還有一個非常尖銳的觀察,我害怕這太過真實而不能忽略:懶惰是許多問題的根源。科學家忙於科學研究,因此他們沒有時間無謂地增加代碼的複雜度。許多程序員的工作實際上並不複雜 - 任務很簡單 - 所以他們有太多的時間,他們用這些時間沉迷於“API 設計”,於是就產生了怪物。

(實際上,當工作在技術或社會層面上遠非瑣碎時,程序員糟糕的訓練使他們的注意力偏離了直接的職責 - 這個東西是否真的運行良好、易於使用、高效/經濟等 - 而是宣稱自己只負責神聖的 API,並開始使其變得異常複雜。與此同時,從功能上來說,這個東西幾乎無法運行。)