為什麼 2010 年前後誕生的語言(如 Golang, Rust, Swift)都是強類型 + 靜態?
當然仍然有新語言(如julia)是動態類型的 但是影響力不及前面三個
動態類型一時爽,代碼重構火葬場
動態類型語言使用api時候,不看源碼或者文檔,幾乎沒法判斷參數和返回值類型…接觸新庫的時候太累……
因為時代的變革。
編程語言進化目前大概有三個階段:
1. 原始階段。彙編/ C/C++之類的,重性能,因為那個年代的計算資源相當匱乏。這個階段其實也誕生不少優秀的語言,比如lisp。可是出彩的還是C和C++。
2. 發展階段。大概是90年代開始,Pentium處理器的出現應該是代表計算機進入了一個新時代,摩爾定律光輝普照,這個年代湧現出了不少動態語言,比如Ruby、Python、Lua、JavaScript,當然也少不了Java。都是以人為本,提升生產效率。
3. 躍進階段。也就是2010年以後,尤其是智能手機、雲計算等出現,之前的語言滿足不了需求了,因為規模越來越大的同時,對安全的要求也越來越高了。也就是說,現代對編程語言的需求是:安全和高效率(性能和開發速度),所以就湧現出Golang、Rust、Swift這種強類型靜態語言。Golang的側重點在於工程化和並發,這也和摩爾定律在CPU上失效進入多核時代有關係。Rust主打安全和高效(性能+開發速度)。Swift誕生之初目的很明確了,就是為了替代ObjectiveC,而且也從Rust中取經,也比較注重安全和性能。所以強類型+靜態就成為了一種主流選擇。(突然感覺D語言有點生不逢時 )
所以說,這是時代的變革,時代的選擇。
大型程序還是需要靜態類型來檢查一些編碼上的錯誤,能早點檢查總比後面跑出問題好動態類型語言適合快速開發小程序,但在大型程序上,少寫這些類型注釋省不了什麼時間,哪怕不考慮可能出現名字寫錯這種難以檢查的問題,因為,做項目時候,設計比編碼重要,如果編碼占時間太多,那是碼農。。。動態類型語言的運行效率也是很難優化的,因為類型不確定,所有操作幾乎都需要用多態來做(調用虛函數),包括簡單的加加減減,要優化也比較困難,無論是AOT的類型推導還是JIT編譯都麻煩,不如一開始就設計為靜態類型了,這樣大家都happy
強類型沒什麼可說的,弱類型的問題大家已經說的很多了,從Javascript到C都有同樣的問題,重載都能被搞出來不少幺蛾子。做新語言大概會第一時間繞開這個坑,弱類型帶來的好處實在有限。
至於動態或者靜態就是取捨問題了,個人認為,靠程序員之間的文檔協定來搞定一個大型應用是一個非常挑戰的事情,還不如把行為和類型聯繫起來,通過類型檢查來約束行為。人總是有點惰性的,如果照著文檔的約定不好實現,很有可能就會偷懶的違背約定,後面的維護就會困難重重。而違反介面層面的規定會直接在編譯過程失敗。
嚴格約束帶來的好處就在於可以對未知的部分做很多合理假設,通過介面可以確認更多的信息,比如入參會不會被修改、調用會不會產生IO,不至於讓開發者調用一下介面還要看看具體實現。而嚴格約束也會限制程序的寫法,靈活性會受限。所以這幾年湧現出來的新語言也是在找這個平衡,很多靜態類型的語言也不用顯式地聲明對象類型,一些動態語言也在加類型約束。
在生產工具極大豐富的現在,語言的演進並不是一個換代的過程,而是一個補充的過程。微服務等實戰,允許線上不同的業務類型選用更豐富的語言工具箱,拆服務的話,可以在必要時發揮靜態語言的性能優勢或者工程優勢。
然而 web 的話,對付兩下 json / orm / html 就能想起來動態語言的好。感覺這些靜態語言扎堆出現最主要原因是: 碰巧
另外和 CPU 主頻達到瓶頸有點關係
還有就是這個時間點有很多人玩膩了動態語言和虛擬機, 過幾年玩膩了靜態語言說不定又跑去玩動態語言和虛擬機現在不管動靜態都是強類型, 除了彙編已經基本沒有弱類型語言了, 而這個時間點附近誕生的新語言也有很多動態的啊: CoffeeScript, Elixir, Dart 等 Timeline of programming languages還覺得動態語言有優勢的人可以去看看haskell,F#。
靜態語言可以有動態語言的所有真正有用的優點(比如不用寫類型,腳本化等等),反之卻不成立。
其實很簡單的道理,即使是所謂的動態類型,代碼執行的時候,還是需要解釋器/編譯器識別出真正的類型,那為什麼不讓編譯器早點分析出來?如果只是不想寫類型,由編譯器做類型推斷就好了。
還是anders的那句話:你告訴編譯器越多,它能幫助你越多。因為動態類型語言怎麼搞都差不多,只有靜態類型語言才能think different。
花在維護上時間大於寫新代碼的時間,這樣的模塊都應該用靜態語言來寫。所以你看 Lua 是唯一做的對的動態語言,只做 embed/extension。當然 Lua 也有問題,就是一旦用 Lua 寫的代碼成熟了,還是沒辦法像 refactor 那樣 piecemeal 地變成靜態語言。什麼時候動靜轉換像 refactor 那樣常見了,動態語言才能發展。
因為工業界終於捨得去看 type inference 的論文了話說回來,GHC 那一堆擴展的類型(比如多元類、存在量化、類型族)啥時候才有個「工業」語言能用上呢?
跟歷史有關係吧第一個時期,靜態類型語言黃金時代,因為硬體能力不足,軟體開發人員需要認真管理各類資源,不然系統速度太慢。第二個時期,動態類型語言黃金時代,硬體大爆發,瞬間滿足了大部分軟體的硬體需求,而隨著軟體規模不斷擴大,快速完成高可讀性的代碼很重要。人力成本是公司最大的一部分。動態語言有效解決該類問題,迎來了春天。第三個時期,將會是靜態類型語言的新黃金時代。動態類型語言不滿足人民群眾日益增長的性能需求,同時暴露了對類型過於寬鬆而造成的可維護性,可調試性下降。靜態類型語言開始總結經驗,學習動態類型語言的有點,很多人都提到了類型自動推導,智能指針,內存靜態檢查等智能功能。同時,不斷改進原有能力,如concept,traits等提升模板可維護性。當然,動態類型語言也在革新,但估摸著,在性能和可維護性雙重優勢的情況下,靜態類型語言會更強勢一些。
只是學術界在這方面積累的一次釋放而已
「根據Curry–Howard correspondence,程序不就是類型的證明嗎,有什麼難懂的嗎?」
沒有強類型,沒有函數範式指針(這個術語叫什麼?),一個大型項目,甚至中型項目,就全靠程序猿的規範約束,相當不靠譜
還有由於是動態類型,IDE不僅沒法做檢查,而且連基本的查找和重構都很難保證,隱含的bug發現不了,實際上相當耽誤開發進度julia是用來做科學計算的啊,在互聯網領域肯定沒前面三個影響力大了。
動態語言已經把業務做的差不多了,性能問題始終無法解決,傳統的靜態語言不足以支撐快速迭代和互聯網行業的高速發展,於是出現了新型的靜態語言,借鑒了動態語言的快速開發的特點,又不失靜態語言越過虛擬機直接操作CPU和內存的特點。這是複雜的互聯網產品發展至今的必然產物。如今的互聯網不是CGI不是ISAPI/NSAPI,也不是PHP弄個MVC框架寫幾個頁面就可以了的。
誕生和發展是兩個事情。從10年到現在javascript的發展無比迅猛。這三個靜態語言也就Go的發展非常快(swift是繼承了另一個靜態語言社區)。綜合來看這五年靜態語言的增長並沒有領先動態語言。
換個角度看,也正是ECMAScript6/python的優秀與強勢導致創造新動態語言的idea沒有土壤,更多只能創造一些衍生項目如Dark。而C/C++/obj-c的不合時宜與反思是導致新靜態語言大量出現的土壤。誕生與發展雖有關聯但不是線性關係。其實弱類型的做小型短平快的項目還挺好的,到了大型系統上,尤其是若干個版本迭代後,各種隱含的bug,會導致整體結構混亂不堪,難以維護。
所以,對於大型系統來說,強類型至少是比弱類型要合適的。
因為JavaScript 是前車之鑒,Rust 痛定思痛。
推薦閱讀:
※python3 為什麼取消了sort方法中的cmp參數?
※為什麼C++中會把文件操作抽象為fstream?
※為什麼 Python 3.0 設計成不與 Python 2.X 兼容?主要有哪些地方需要突破才導致這一決定?
※怎樣才叫 「精通」 C語言?
※有沒有合適的學習路線來學習封裝在IDE下的原理?