動態類型

2005 年 3 月 14 日

我一直不願意在程式語言的靜態和動態類型辯論中發表任何意見。這是個充滿情緒的話題,人們似乎更傾向於辯論而不是傾聽。但由於我被問過幾次,因此我將分享我的個人經驗。我並非試圖說服任何人,但我希望有人能從中獲得一些思考的材料。

當我第一次意識到這個區別時,我很快就被靜態類型的優點說服了。我早期的程式設計經驗是 Basic 和 Fortran IV,它們的類型有限。然後我轉到 Pascal,它很快成為我喜歡的程式設計語言。

當我接觸物件時,我在 C++ 和 Smalltalk 中工作。有一段時間,我認為 Smalltalk 的動態類型是一個缺點,但為了這個平台其他方面的美妙生產力,這是一個微不足道的代價。

當我參與一些中等規模的 Smalltalk 專案時,我開始真正質疑這一點。靜態類型的普遍論點是,它可以找出難以發現的錯誤。但我發現,在有 SelfTestingCode 的情況下,靜態類型會發現的大部分錯誤都可以透過測試輕鬆找出。由於測試發現的錯誤遠多於類型錯誤,因此無論是在靜態或動態類型語言中,你都需要它們,所以擁有靜態類型對你來說幾乎沒有好處。

看到其他人遵循這個發現路線很有趣。Robert Martin 和 Bruce Eckel 從 C++ 轉到 Python 時也發現了同樣的事情。

然而,找出錯誤並非靜態類型的唯一好處,而我發現其他一些好處在當今更為明顯。

有一天,我發現自己試圖遵循一些寫得很好的 Ruby 程式碼。我發現參數上缺乏類型資訊讓生活變得困難,我一直在自言自語「我這裡到底有什麼?」我沒有在 Smalltalk 中發現這麼大的問題,原因有兩個:出色的環境可以輕鬆啟動除錯器並查看你擁有的內容,其次,常見的慣例是根據類型命名參數。(這很有道理,因為 Smalltalk 具有關鍵字參數而非位置參數,因此關鍵字會說明參數扮演的角色。)

靜態類型有用的另一個領域是,它允許程式設計環境提供更多幫助。這裡的啟示(就像許多事情一樣)是 IntelliJ。使用像這樣的 IDE,我確實感受到類型系統正在幫助我。即使像自動完成這樣的簡單事情,靜態類型也有很大的幫助,而領先的 IDE 可以做得更多。

儘管如此,使用 Smalltalk 和 Ruby 等語言進行編程仍有特別令人滿意的地方 - 我認為這與動態類型有很大關係。在 Camp 4 Coffee 與 Bruce Eckel 聊天時,我們都同意靜態/動態類型爭論最令人沮喪的事情之一是,很難用言語表達在動態類型語言中工作的優點。不知何故,在這種環境中編程時,事情似乎進行得更順利,即使我在 emacs 中使用 Ruby,而不是 IntelliJ。(當然,Smalltalk 既有語言,也有美妙的編程環境。)

我懷疑部分原因是語言的簡潔性允許在語言中執行 DomainSpecificLanguage 等操作。使用 Java 和 C# 等語言時,我總覺得需要跳過文字才能理解正在發生的事情。

無論原因是什麼,這種更好的流程會帶來更多樂趣的編程 - 即使在劣質的環境中也是如此。這似乎並不重要,誰在乎編程人員是否玩得開心?但我確實在乎,因為我真的很喜歡編程。我喜歡快速做事,而無需在思考和執行程式碼之間的廢話上大費周章。對我來說,這就是 Smalltalk 和 Ruby 的樂趣,也是我在任何個人專案中使用它們的原因。而且樂趣有商業價值 - 畢竟,動機是編程人員生產力的主要因素。