如何判斷開發語言的複雜度?

發表於2011-06-16

一門語言的複雜程度,是由什麼來決定的呢?Whiley網站的Dave發表了一篇博文《Language Complexity?》,文中指出,語言形式上的複雜和語言的複雜程度是兩回事,手工輸入程式碼量的減少,並不意味著語言的複雜度就會降低。

有些開發語言很複雜,有些則比較簡單……對嗎?C++與其他任何語言相比就是一個很好的例子。但是,是什麼決定了語言的複雜度呢?

我正在讀 Bruce Eckel的關於Scala的文章。它確實是一篇很精彩的文章,我很喜歡它。但有件事卻困擾著我,下面這段引用可以很好的概括這件事:

通過上面的程式碼,你可以看出學習Scala比學習Java簡單得多。在輸出“Hello,world!”時,不必再寫那令人討厭的Java形式語句,在Scala中,只需一行語句即可:

不管怎樣,從這篇文章中,我對Scala並沒有獲得同樣的感覺。它似乎在說明去掉“public static void”就可以使一門語言變得簡單。然而我不認為一門語言複雜與否與形式語句有多大關係。當然,它減少了“用手打字”勞動量,但這和語言複雜度是完全不 同的事情。

依我的看法,如果在一門語言背後有一個清晰的思想模型,那麼這門語言就會很容易使用。開發者可以利用它來理解某些結構的產生原因及適用於什麼時候。請看下面Bruce對Traits的描述:

我們在使用Traits時也容易產生混淆。Trait和介面很像,不同之處在於Trait可以包含方法的定義,建立新類時可以成為該類的一部分。

上面描述並不能幫助我理解Traits到底是什麼。問題是:我為什麼要用它們?什麼時候該用它們?什麼時候不該用它們?現在,我不想討論 Traits是(或不是)一個複雜的屬性。關鍵點是:上面的解釋並不能讓我得出“Traits是簡單的”的結論,原因就是它並沒有讓我瞭解Traits背 後的思維模型。

教學生如何程式設計,是理解那些難懂概念的好辦法。為了讓學生確實瞭解某事,你需要建立一個思維模型。例如,在解釋參考/指標時,由方框和箭頭組成圖可以起到很大的作用。不過,在Java中,也確實有很多棘手的問題:

Subtyping。掌握Subtyping什麼時候適用什麼時候不適用,確實是一個難點。當然,學生起初 可以通過記憶來記住子型別關係,你可以這樣解釋“如果A繼承了B,那麼A就是B的子型別”等等。但這並不能幫助構建展示子型別及它所起的作用的思維模型。 對於基元,我們有一個很好的經驗法則:一個數字型別T1轉換為另一數字型別T2,其在精度上沒有任何損失(當然,並不是總會這樣的)。但是,此時的思維模 型是什麼呢?好,第一個問題就產生了:為什麼不同的型別(比如short型別和int型別)會有不同的範圍呢?只有已經理解了數字的二進位制表示的同學才能 理解這個問題。對於物件而言,你可以通過對比靜態模型和動態(換言之:執行時)型別開始講起,大部分時候,這樣比較容易理解的。

動態排程。在一個給定的繼承層次結構中,理清在特定的環境中呼叫了哪個方法,對很多人來說都是一種挑戰。這一切都是因為對此很難給出一個精準的規則所造成的(換句話說,你最近有讀過關於這個主題的《The Java™ Language Specification》一書嗎?)。為了構建一個思維模型,你需要考慮方法簽名,靜態型別及動態型別等等。在某一點,情況不會太遭。但是,隨後考慮到Generics 和Erasure時,思維模型就開始變得越發複雜了。

介面VS抽象類。這又是別外一個經典。至少也有一個簡單的經驗法則:使用介面和抽象類僅僅是為了程式碼重用。但是,這背後的思維模型是什麼呢?好,學生通常都會以這個問題開始:為什麼只能繼承一個類呢?下一步,當你解釋多繼承會帶來很多易犯的錯誤時,事情就會變得難以掌控了。

我確信,在Java中還有很多其他有趣的例子,我們可以在這裡進行討論。


  譯文:CSDN

 

相關文章