almost 2 years ago

Translated from "Appreciating Limited Choice in Languages" by Andrew Binstock, Java Magazine September/October 2016, page 4-5. Copyright Oracle Corporation.

欣賞程式語言有限的選擇

在細節上語言規定越多,越容易有效率地開發

本期我們涵蓋一些 JDK 改善提案 (JDK Enhancement Proposals, JEPs),探討一個近期提出的提案,將 JDK 內建工具的命令列參數標準化,作為支持該提案核心觀點:現有太多種方式從命令列取得協助,因此在使用一個工具時,猜錯了,您必須不斷地嘗試各種可能性,可能是 –help--help,也可能是 -?,還有一個未提到的最後手段,不給任何參數,執行程式,看能從錯誤訊息得到什麼有用的資訊。

我完全支持這標準化,但我認為應該更進一步,在我的觀點,這命令列開關的語法應該被納入語言的風格指南 (style guides) 中,如果 Java 團隊在當初釋出語言時 (當時有建議類別名稱以大寫開頭,常數應全部大寫),對開關的語法有規範標準的公約,這小小的煩惱就不會存在,一個語言在小細節上能越正規,能讓事情更容易完成1

但在理想世界,即使這方案是不充足的,我仍強烈相信:缺少 Java 風格指南2,這件事本身是一種侷限,我期望有一套一致的建議,並被廣泛地遵循,例如,針對左大括弧的位置、縮排的寬度、使用 tab 還是空白、是否使用交錯的 if/else、Javadoc 的多種格式化選項等正式寫出指南,顯然,這同樣能套用更高層次的事物上:全展開的 import 還是使用萬用字元、import 與變數宣告的順序等,當有一份固定的指南,每個 Java 程式都會是一致的,不需要去再次檢查,然後調整成個人或是特定的風格。

說也奇怪,Java 最初出現時,想以某種方式處理當時鬆散語言讓某些工作變成極度冗長乏味的情境,在 Java 之前的主流語言是 C,它是刻意以完全無規範的觀點去設計,即使是現在,在幾回的標準化後,C 在許多地方的行為是沒有定義,或是留給實作者定義。在 90 年代中期3,Java 初次亮相,C 變成輸家。一個整數可大可小,由編譯器定義,如果我沒記錯,最小寬度是 16 位元,16、32 及 64 位元都是合法的整數實作,結果導致,將 C 從一個平台移植到另一個平台是非常瑣碎的一件事,Java 解決了這些問題,資料格式在不同平台有固定的大小,程式可以在不經過修改就能在多種平台上執行。

C 缺乏標準化造成許多無意義的行為,讓原本 AT&T 貝爾實驗室的團隊開發了一個新語言:Go,選擇嚴謹規範的實作,Go 有一個正式的程式風格,所有的程式都使用該風格,有一個格式化工具包含在 Go 的發行版本中,在語言本身,還有額外的限制,例如,任何在 if 之後可執行的程式碼,即便只有一行,都必須以大括弧包覆,許多其他慣例以 “idiomatic Go” 的方式被定義,這令人開心的結果是所有 Go 的程式看起來都一樣,閱讀和編寫都容易。

不只命令列的語法,近幾年 Java 在細節缺少標準化已是一個議題,雖然小但擾人,例如有三種方式可以加註一個欄位不該是空值:@NonNull@Nonnull@NotNull,Checkstyle 及 FindBugs 使用第一個,Java EE 6 和 IntelliJ IDE 則分別使用剩下的兩個,這導致當您從某個環境轉移到另一個開發環境時,您需要改變你的程式與工具才能得到預期的空值檢查,當然,這是站在 Java 自吹自擂的可攜性的對立面:切換 IDE 會造成程式行為不一樣。幸運地,Java 8 所使用 Checker framework 已經形成統一的慣例:@NonNull4

這些確保語法一致性的非難所帶來的便利與好處已被廣為認可的,可以從多數開發組織看到,它們選擇規範專屬的『內部風格』,並強制納入在程式碼檢閱 (code review) 中,因此所有的開發者使用相同的慣例,但這些風格彼此衝突,缺乏一個一致的慣例集合。

多數開發組織選擇規範專屬的『內部風格』,並強制納入在程式碼檢閱 (code review) 中,因此所有的開發者使用相同的慣例,但這些風格彼此衝突,缺乏一個一致的慣例集合。

如果整個世界都是 Java,我想對於這些不一致的容忍不會感到特別繁重,雖然時間會因此無意義的耗費。5

但在這日益增加的多語言世界中,其他語言 (JavaScript、HTML 等) 扮演顯著的角色,缺乏強制的程式碼標準,不只是在 Java,尤其是在那些語言,結合在一起對生產力是一個持續且無意義的累贅。

譯註
1. 有點像 Python 哲學。
2. Java 風格指南是有的,只是很久沒更新了。
3. Java 正式發表於 1995 年,同年的語言還有 Delphi、JavaScript 及 PHP,而最近熱門的 Python 和 Ruby 則在更早的 1991 與 1993。
4. 到目前為止,文中所提到 JSR 308 的 Type Annotations 並不包含在 JDK 8 Update 102 中,需要另外加入 Checker Framework 並使用其中的 compiler 替換 JDK 既有的 compiler,這是 Java 另一個莫名其妙的地方,一個 Java 標準竟然沒有放在 JDK 中,類似的還有 JavaMail 及 Servlet API 都需要引入額外的 JAR 檔才能使用,所以我個人目前暫時不用這些 annotation。
5. 這句翻譯要感謝友人 Linda Hu 的協助。

譯者的告白
標題的翻譯似乎還是沒有很達意,有更好的建議嗎?這是我第一次翻譯 from the editor,算是編輯的話吧?平常沒太認真看,但這次看完,心中的 OS:跟《閒談軟體架構:API Naming Style》有些論點可以相呼應,Java 確實是一個好的語言,至今已 21 個年頭,也略顯老態與凌亂,相較於 Go、Rust 和 Swift 等新語言,Java 無法提供開發者更高的語意層次,真的是很可惜,而且作為一個『靜態強型別』的語言,在 compiler 層級能做的事情還有很多,例如這篇提到的 @NonNull,由 compiler 進行檢查,就可以避免很多的 NullPointerException,而不是放在 container 的執行期檢查層級,只是 Java 後續的方向會是如何呢?我也不知道。

← 閒談軟體架構:API Naming Style 在 Intel x86 Galileo 開發板上與感應器互動 →