Scott Meyers為Andrei Alexandrescu的《D程式設計語言》作的序

暘谷發表於2013-05-27

enter image description here

Scott Meyers

世界頂級的C++軟體開發技術權威之一。著有兩本暢銷書Effective C++和More Effective C++,曾經是C++ Report的專欄作家。他經常為C/C++ Users Journal和Dr. Dobb's Journal撰稿,也為全球範圍內的客戶做諮詢活動。

enter image description here

Andrei Alexandrescu

世界頂尖的C++專家,2001年撰寫了經典名著《C++設計新思維》(Modern C++ Design),曾榮獲2001年最佳C++圖書稱號,書中所開發的Loki已經成為最負盛名的C++程式庫之一。他被認為是新一代C++的代表人物,因為對Template技術的精湛運用,震撼了整個C++社群,開闢了C++程式設計領域的“Modern C++”新時代。他還與Herb Sutter合著了《C++程式設計規範》(C++ Coding Standards)。他花了8年的時間攻讀機器學習方面的博士學位,專門研究部分自然語言處理結構。自2006年開始,他與D語言的最初設計者及實現者Walter Bright緊密合作,設計和實現D語言及其標準庫,他是D語言很多特性的設計者,也是大多數D語言標準庫的作者。Andrei Alexandrescu在工業界和學術界都有很高的聲譽。現為Facebook研究員。

不管從哪個方面來講,C++都獲得了巨大的成功,但即使是其最狂熱的擁護者也不可否認它是一隻複雜難懂的“猛獸”。這種複雜性也影響到了被廣泛使用的C++後繼者Java和C#的設計。這兩種語言都在儘量避免C++的複雜性,採用的方法是,通過一個更易使用的程式包提供其大部分的功能。

降低複雜性可以採用的基本形式有兩種。一種形式是,去掉“複雜的”語言特性。例如,通過垃圾回收(garbage collection)的方式可以避免C++中對手動管理記憶體的需要。在模板的“成本/效益”測試被認定為失敗時,這些語言的初始版本都選擇了排除C++中與泛型支援相關的所有內容。

降低複雜性的另一種形式是,使用相似但要求更少的結構方式取代“複雜的”C++功能。C++的多重繼承可以改變成使用介面進行擴充套件的單繼承。Java和C#的當前版本都支援模板化的泛型,但它們都比C++的模板更簡單。

這些後繼語言並不只是要求通過降低複雜性來完成C++所能完成的任務,而是被寄予了更多的期望。它們都定義了虛擬機器,增加了對執行時反射(runtime reflection)的支援,並提供了大量的開發庫,這些庫可以讓許多程式設計師將關注點從建立新程式碼轉移到組合現有的元件方面上來。最終結果就是它們被看作是基於C語言的“生產力語言”(productivity language)。如果想快速建立軟體,而它幾乎等同於去組合現有的元件(很多軟體都屬於此類),那麼與C++語言相比,Java和C#都是不錯的選擇。

但C++不是生產力語言,它是一種系統程式語言。它旨在媲美C語言在以下幾個方面的能力:硬體通訊(如驅動程式和嵌入式系統方面),在不經任何調整的情況下可以直接處理基於C語言的庫和資料結構(如遺留系統方面),用盡執行硬體上的所有效能。這裡不是想嘲諷Java和C#語言底層虛擬機器的關鍵效能元件都是使用 C++編寫的,高效能虛擬機器的實現就應該是系統語言乾的事,不適合生產力語言。

D語言的目標是想在系統程式設計領域成為C++的繼任者。像Java和C#語言一樣,D語言也想要避免C++的複雜性。為此,D語言使用一些相同的技術,其中包括加入垃圾回收功能,摒棄手動記憶體管理 ;採用單繼承和多介面,捨棄多繼承。但是,D語言走的又是一條屬於自已的路。

先是從標識出C++的功能性漏洞並修補它們開始。當前的C++未提供對Unicode的支援,而其後繼版本(C++0x)也只提供了有限的支援。D語言從一開始就支援Unicode。當前的C++和C++0x都不支援模組(module)、契約程式設計(contract programming)、單元測試(unit testing)或“安全”(safe)子集(其中不可能出現記憶體錯誤)。D語言提供了上述所有功能,但未對生成高質量原生程式碼的能力產生影響。

針對C++強大與複雜兼有的特點,D語言瞄準的目標是:在保持功能強大的同時降低複雜性。C++中的模板超程式設計人員已證明,編譯時計算是一項很重要的技術,但必須要先克服句法的困難才能將它付諸實踐。D語言提供了類似的功能,但沒有詞法方面的煩惱。在當前的C++裡,即使知道如何編寫函式,你也不一定了解如何才能編寫出與之對應的能在編譯期間進行計算的C++函式。在D語言裡,如果知道如何使用編寫函式,你就能準確地知道如何編寫其編譯時版本,因為兩種情形下的程式碼是一樣的。

最有意思的地方是,在基於執行緒的併發性方面,D語言與其由C++派生出的兄弟語言之間使用的方法是截然不同的。D語言認識到對共享資料不正確的同步訪問(資料競爭)就是一個陷阱—容易陷進去且很難爬出來。因此,它從一開始就約定:預設情況下,資料不會被跨執行緒共享。正如D語言的設計者指出的那樣,在現代硬體深度快取層次的環境裡,記憶體並不是真正跨核心或處理器共享的。既然這樣,那為什麼還要預設給開發者提供的一種抽象呢?這種抽象不僅僅是一種錯覺那麼簡單,它是一種錯誤的觀念—眾所周知,是它滋生了難以除錯的錯誤。

所有這些內容讓D語言在C語言的傳統設計空間裡特別引人注意,這一點已足以成為你閱讀這本書的理由。而本書的作者是Andrei Alexandrescu,閱讀理由變得愈加充分。作為D語言的共同設計者以及絕大部分D語言庫的實現者,沒人能比Andrei更瞭解D語言。他能對D程式語言進行描述,這是很自然的事,他也能解釋D語言為什麼是這個樣子。有些特性出於某種原因存在於D語言裡,而有些應該有的也正缺失的特性出於某種原因卻未包含在D語言裡。要闡明其中的原因,Andrei是不可替代的人選。

這種解釋獨特而富有魅力。其中有些內容似乎有點跑題(但事實上它們只是通往終點的一箇中間站),Andrei對此作了保證:“我知道你在反問自己:編譯時計算真的有必要嗎?很有必要!請容我慢慢道來。”針對聯結器診斷不夠直觀的根本性問題,Andrei說到“如果你忘記了--main,也不用著急。聯結器會使用其本地語言—編碼後的克林貢語 ,流暢、詳盡地 提醒你。”即使是對其他出版物的引用,Alexandrescu也都有提及。他不是簡單地像“Wadler的著作Proofs are programs”這個樣子進行提及,實際提及的樣式非常詳實,如“Wadler的迷人著作Proofs are programs”;關於Friedl的著作Mastering regular expressions不是簡單推薦,而是“熱情推薦”。

一本關於程式語言的書自然滿篇都會帶有樣例程式碼,而這些樣例程式碼同時也說明Andrei是一個注重實踐的作者。這裡有一個他編寫的搜尋函式原型:

bool find(int[] haystack, int needle);

本書描述的是一門很有意思的程式語言,是由一位經驗豐富的作者編寫而成的。我保證你會發現這本書值得一讀。

enter image description here

相關文章