曾經有一段時間,不久前,在這些人的選擇,我們有過那種做:我希望它是快速和容易寫程序,但有時也有是更多的運行時錯誤?或者我希望在編譯時免受更多這些錯誤的影響,但是不得不浪費更多時間編寫更多的樣板文件?
這是結束了。當動態語言是避免在代碼中增加更多官僚作風的唯一方式時,動態語言是非常令人興奮的,但動態類型現在被類型推斷所淘汰。所以你確實是對的 - 動態打字不再增加價值,現在更強大的強類型系統正在迎頭趕上。
咦?哪裏?怎麼樣?
像Haskell,MLs,Scala,Rust和一些.NET系列的語言將強大的打字和類型推斷結合在一起,因此您可以獲得最好的效果:所有內容都具有強大的強制類型,但您沒有實際上寫下來,除非編譯器無法找出它,通常它可以。
不要忽略它們是學術。事情變了。在過去幾年中,這些具有強大打字系統的語言一直在逐漸流行起來。 (2),我發現它越來越少見地聽到一種全新的語言,這些天來沒有做運動與類型推斷安全爲方便起見,強類型的組合,至少在一定程度上。今天的全新深奧語言是未來十年的「企業標準」,因此我認爲每個人最終都會採用這種兩全其美的方式。
即使老人Java正在朝這個方向緩慢移動!(例如:鑽石算子;推斷lambda表達式的功能接口)
第一次學習動態語言現在已經太晚了,就好像整個九十年代你推遲用CD播放器替換你的磁帶,然後最後在2002年左右,你可以開始購買CD播放器。
編輯:我重讀你的問題。我同情你對具體代碼的渴望。這是一個羅塞塔石頭。檢查列表是否已排序的通用過程以及調用它的代碼。調用它的代碼每天都會做正確的事情,在閏日中做錯事情,這是編譯時錯誤在很少執行的代碼中遇到錯誤時如何贏得運行時錯誤的一個例子。代碼是未經測試的,只是一個草圖。特別是,我仍然在學習Haskell(因此對新轉換的P:P的熱情),並且我還沒有像過去幾年一樣嚴重使用Python,所以原諒
傳統的靜態類型:
// Java 7 - strong typing but no type inference
// Notice that you get safety, because the wrong usage is caught at compile time
// But you have to type a lot :-(
static interface Comparable { boolean compare(Comparable other); }
...
boolean isListSorted(List<T extends Comparable> xs) {
T prev = null; for(T x: xs) {
if(prev!=null && !prev.compare(xs)) return false;
prev = x;
}
return true;
}
...
public final class String implement Comparable { ... }
public final class Animal /* definitely does not implement Comparable! :-) */ { ... }
...
// proper usage
List<String> names = Lists.newArrayListOf("Red", "Spinelli", "Ankh", "Morporkh", "Sam");
boolean areTheNamesSorted = isListSorted(names);
if(todayIsALeapDay()) {
// bad usage -- the compiler catches it, so you don't have to worry about this happening
// in production when a user enters data that send your app down a rarely-touched codepath
List<Animal> pets = Lists.newArrayListOf(Animal.getCat(), Animal.getDog(), Animal.getBird());
boolean areTheNamesSorted = isListSorted(pets);
}
動態類型:
class Animal:
...
# Python 2.6 -- dynamic typing
# notice how little keystrokes are needed
# but the bug is now
def isListSorted(xs):
# to keep it more similar to the Java7 version, zip is avoied
prev = None
for x in xs:
if prev is not None and not prev.compare(x): return False
prev = x
return True
...
# usage -- beautiful, isn't it?
names = ["Raph", "Argh", "Marge"]
areNamesSorted = isListSorted(names)
if isLeapDayToday():
# ...but here comes trouble in paradise!
animals = [Animal.getCat(), Animal.getDog()]
# raises a runtime exception. I hope your unit tests catch it, but unlike type
# systems it's hard to make absolutely sure you'll be alerted if you forget a test
# besides, then you've just traded the Evil of Having to Write Lots of Type Signatures
# for the Evil of Having to Write Lots of Unit Tests. What kind of terrible deal is that?
areAnimalsSorted = isListSorted(animals)
強大的打字:
-- Haskell - full safety of strong typing, but easy on the fingers and eyes
class Comparable a where
compare :: a -> a -> Bool
end
instance Comparable String where
...
end
data Animal = ...
isListSorted [] = True
isListSorted x:[] = True
isListSorted x1:x2:xs = (compare x1 x2) && (isListSorted xs)
names = ["Raplph", "Argh", "Blarge"]
areNamesSorted = isListSorted names
animals = [Cat, Dog, Parrot]
-- compile time error because [Animal] is not compatible with Comparable a => [a] since
-- Animal is not an instance of comparable
areAnimalsSorted = isListSorted animals
動詞強大的分型:
-- Same Haskell program as before, but we explicitly write down the types
-- Just for educational purposes. Like comments, you can omit them if you don't think
-- the reader needs them because it's obvious. Unlike comments, the compiler verifies their truth!
class Comparable a where
compare :: a -> a -> Bool
end
instance Comparable String where
...
end
data Animal = Cat | Dog | Parrot
isListSorted :: Ord a => [a] -> Bool
isListSorted [] = True
isListSorted x:[] = True
isListSorted x1:x2:xs = (compare x1 x2) && (isListSorted xs)
names :: [String]
names = ["Raplph", "Argh", "Blarge"]
areNamesSorted = isListSorted names
-- compile time error because [Animal] is not compatible with Comparable a => [a] since
-- Animal is not an instance of comparable
animals :: [Animal]
animals = [Cat, Dog, Parrot]
areAnimalsSorted = isListSorted animals