Type safe Duck Typing

If it walks like a duck and quacks like a duck, I would call it a duck. -- Wikipedia - Duck Typing

Duck Typing
解釋為,如果一隻動物,走起來像鴨子,叫起來像鴨子,就可以把它當作鴨子。翻譯過來就是,如果它含有我想要的功能,那麼我可以把它當作真的來對待。舉例來說,我想要一個可關閉的資源。我想說,「需要有一個close方法。」我不關心它是一個File或Channel或其他任何物件。



Example
class Duck {
def quack = println("Quaaaaaack !")
def feathers = println("The duck has white and gray feathers.")
}
// defined class Duck
 
class Person {
def quack = println("The person imitates a duck.")
def feathers = println("The person takes a feather from the ground and shows it.")
}
// defined class Person
 
def inTheForest(duck: { def quack; def feathers }) = {
duck.quack
duck.feathers
}
// inTheForest: (duck: AnyRef{def quack: Unit; def feathers: Unit})Unit



scala> inTheForest(new Person)
The person imitates a duck.
The person takes a feather from the ground and shows it.

scala> inTheForest(new Duck)
Quaaaaaack !
The duck has white and gray feathers.

scala> inTheForest("Duck")
<console>:7: error: type mismatch;
found : java.lang.String("Duck")
required: AnyRef{def quack: Unit; def feathers: Unit}
inTheForest("Duck")




Duck Typing


Scala也有適當的混入(mixin)(特性(trait)) ,所以你不必去擺弄面向對象編程的缺陷來獲得模塊化的代碼。如果你確實需要一些鴨子類型(duck typing),Scala甚至能為你提供構造類型(structural type)。

Duck Typing(鴨子類型)

Bill Venners: 我觀察到的Scala的其中一件事是,與Java類型系統相比,在Scala的類型系統中,我可以表達更多的關於程序的事情。覺得Java是一個動態語言 的人往往解釋說,他們對類型系統感到很沮喪,並發現如果他們擺脫靜態類型,就會有更好的體驗。然而似乎Scala答案是,試圖讓類型系統更好,改善它,讓 它更有用,使用起來更方便。那麼,什麼事情是在Scala類型系統中可以做到,而在Java類型系統中卻做不到的?

Duck Typing 

Duck Typing 是一種動態類型的概念,對象的類型由其運行時支持的屬性和方法決定。



Martin Odersky: 反對Java類型系統的理由之一是,它不含有duck typing。duck typing的解釋為,如果一隻動物,走起來像鴨子,叫起來像鴨子,就可以把它當作鴨子。翻譯過來就是,如果它含有我想要的功能,那麼我可以把它當作真的 來對待。舉例來說,我想要一個可關閉的資源。我想說,「需要有一個close方法。」我不關心它是一個File或Channel或其他任何對象。

在 Java中,為了完成這個工作,你需要一個包含方法的公共接口,每個人都必須實現該接口。首先,這導致了大量的接口和許多樣板代碼。其次,如果在 既成事實之後再考慮這個接口是不可能的。如果你先寫了這個類,那麼這個類就是已經存在的,你就不可以在不破壞源代碼的情況下再添加新接口,除非你控制所有 客戶端。因此,你就受到了類型強加給你的這些限制。

Scala比Java更富表現力的一個方面是,它可以讓你表達上述事情。在 Scala中,可以有這樣一個類型說明:帶有close方法的任何對 象,close方法不含參數並返回Unit(相當於Java的void)。你還可以結合其他方面的限制。你可以說:繼承於某一特定類的任何類,具有某些帶 有簽名的特殊方法。或者你可以說:繼承於這個類的任何類,並含有一個特定類型的內部類。從本質上講,你可以通過說明類型需求在結構上刻畫類型,以便使用它 們。






大量的其他函數功能(比如模式匹配)已經被引入到 Scala 語言中,但是將其全部列出超出了本文的範圍。Scala 還添加許多目前 Java 編程中沒有的功能,比如操作符重載(它完全不像大多數 Java 開發人員所想像的那樣), 具有 「更高和更低類型邊界」 的泛型、視圖等。與其他功能相比,這些功能使得 Scala 在處理特定任務方面極其強大,比如處理或生成 XML。

Scala 已經提供了對高階函數和閉包的支持,另外還支持序列解析(sequence comprehensions) ,這樣你就可以很容易用Scala寫出漂亮簡潔的代碼。Scala還把函數式和面向對象的編程思想很好地統一到了一種語言裡,它比Java要明顯簡單一些 (雖然它的類型體系(type system)泛型(generics)需 要花費差不同一個數量級的時間去理解,但是,它通常是框架開發者才需要考慮的問題,應用程序開發人員並不需要涉及)。它也使得從傳統的面向對象/Java 編程模式向函數式編程的轉變變得更加容易——這對於編寫並行或異步程序的開發人員尤其意義重大(這是因為現在芯片的主頻已經達到了數個GHz,很難再有提 升了;而芯片集成的核心數則在快速增長。51CTO之前曾發佈過哪種語言將統治多核時代 再看函數式語言特性一 文,對於函數式語言在多核時代的潛力做了相當深入的分析)。你可以在最開始用面向對象的方法編程,然後當你需要它的好處時,就可以遷移到用不變狀態 (immutable state)函數式編程正變得越來越重要,因為我們總是希望能把問題變簡單,並且在一個更高的層次上解決它(如閉包,高階函數,模式匹配,單子 (monad)等),同時我們還需要通過不變狀態(immutable state)實現並發和異步。


最讓我印象深刻的一點就是它的核心語法極其精練簡潔(它的語法手冊只有大概Java的四分之一),但是其方式卻更加強大和靈活,而且非常容易通過庫來擴展,添加新的語義和功能。可以看看這個例子:Scala Actors。因此它非常適合用於創建嵌入式DSL或外部DSL 。有了它以後就真沒必要再用Java,XPath ,XSLT,XQuery,JSP,JSTL,EL和SQL這些東西了——你可以在各種各樣的場合使用DSL。





Scala: Type safe duck typing




Comments