5年前,Scala 似乎曾要成為編程語言中下一個佼佼者司光,因?yàn)樗軌騼?yōu)雅得使用面向?qū)ο缶幊谭妒竭M(jìn)行函數(shù)編程琅坡。
現(xiàn)如今,隨著像 LinkedIn 和 Yammer 這些公司的棄用残家,Scala 的光環(huán)正逐漸黯淡榆俺。
2012 年的 TIOBE 編程語言受歡迎度排行榜上,Scala 排名第 13 位坞淮;2016 年 8 月竟下降到第 32 位茴晋,現(xiàn)在只有不到 6% 的編程社區(qū)在使用它。
不祥的預(yù)兆:Lightbend回窘,Scala 的母公司诺擅,在先前的 Scala 版本上發(fā)布了一款使用 Java API 的新框架。
有趣的是啡直,作為一家領(lǐng)先的軟件產(chǎn)品工程公司的 CTO烁涌,我見了很多軟件開發(fā)主管苍碟,我知道的至少有兩個人,曾經(jīng)在使用了 Scala 一年多后撮执,便痛苦的決定放棄使用它微峰。這是為什么呢?
最初是什么給了 Scala 如此高的知名度呢抒钱,而如今又是什么導(dǎo)致了它的衰退呢蜓肆?
有沒有一些案例,能夠證明使用 Scala 仍然是最好的選擇呢谋币?
想要知道 Scala 最初是如何火起來的仗扬,就要先了解現(xiàn)代編程范式的演變。首先蕾额,程序化編程厉颤,程序被視為是應(yīng)該被一個接一個執(zhí)行的一系列聲明。然后是面向?qū)ο缶幊谭布颍廊绾螆?zhí)行對象上的操作,以及如何與相互交流精肃,從而完成任務(wù)秤涩。
相比之下,函數(shù)式編程將一個程序作為數(shù)學(xué)函數(shù)來評估司抱,以生成一個結(jié)果值筐眷。該函數(shù)可以調(diào)用嵌套函數(shù),而嵌套函數(shù)又可以調(diào)用更多的嵌套函數(shù)习柠。一個嵌套函數(shù)求出一個結(jié)果匀谣。然后,該結(jié)果會被傳遞給封閉的函數(shù)资溃,這是使用嵌套函數(shù)值來計(jì)算它自己的返回值武翎。為了使函數(shù)能夠方便傳遞數(shù)據(jù),并且從其他函數(shù)中溶锭,函數(shù)編程通常作為一個集合宝恶,以最可能的方式定義數(shù)據(jù)結(jié)構(gòu)。它們還允許函數(shù)間傳遞趴捅,就像它們是數(shù)據(jù)參數(shù)一樣垫毙。在這個參數(shù)內(nèi)的一個例子是不允許產(chǎn)生任何副作用,像修改一個全局變量保持狀態(tài)信息拱绑。相反综芥,它只允許接收參數(shù),并且為了生成其返回值猎拨,會對它們進(jìn)行一些操作膀藐。執(zhí)行一個函數(shù)程序包括評估最外層的功能屠阻,這反過來又導(dǎo)致了對所有的嵌套函數(shù)評估,而最基本的功能遞歸向下是沒有嵌套功能的消请。
為什么函數(shù)式編程如此重要栏笆?
· 清晰:沒有副作用的編程能創(chuàng)建出更容易有規(guī)律可循的代碼 - 一個函數(shù)通過輸入和輸出完全被描述出來。一個函數(shù)今天可以生成正確答案臊泰,明天也會生成正確答案蛉加。這樣創(chuàng)建的代碼更容易調(diào)試,測試和重用缸逃。
· 簡潔:在函數(shù)語言中针饥,數(shù)據(jù)通過通用集合數(shù)據(jù)類型從嵌套函數(shù)隱式傳遞到其父函數(shù)。
· 高效:由于函數(shù)沒有副作用需频,運(yùn)算可以重新排序或并行執(zhí)行丁眼,以優(yōu)化其性能,或者昭殉,如果它們的結(jié)果沒有被其他任何函數(shù)使用苞七,則可以完全跳過。
函數(shù)編程語言已經(jīng)存在了幾十年挪丢,開始于 John McCarthy 的 LISP 語言蹂风,這是20世紀(jì)50年代在麻省理工學(xué)院創(chuàng)建的。然而乾蓬,這些總是被視為細(xì)分語言惠啄,感興趣的主要是院士和理論家。Scala 開始還作為一個學(xué)術(shù)項(xiàng)目任内,2001年由 Martin Odersky 創(chuàng)建于 Ecole Polytechnique Federale de Lausanne撵渡。隨之,Scala 的設(shè)計(jì)者做出了幾個重要決定死嗦,將 Scala 定位為函數(shù)編程到主流的突破性語言趋距。
· Scala 代碼在 Java 虛擬機(jī)(JVM)中運(yùn)行。這意味著它可以輕松部署在任何運(yùn)行 Java(大約85%的PC)的機(jī)器上越除。還意味著棚品,Scala 代碼在理論上可以與 Java 代碼相互操作,為 Java 開發(fā)團(tuán)隊(duì)提供了一個橋梁廊敌,以輕松進(jìn)入 Scala铜跑。
· Scala 在語法上和 Java 相似,并且像 Java 一樣骡澈,在編譯時執(zhí)行類型檢查而不是在運(yùn)行時锅纺,從而消除了由類型不兼容而導(dǎo)致運(yùn)行錯誤的可能性。這些相似之處減少了 Java 程序員的初始學(xué)**曲線肋殴。
· Scala 內(nèi)置對模式匹配的支持囤锉,可以基于值模式來匹配任意數(shù)據(jù)類型坦弟,以便于對每個匹配模式執(zhí)行不同的操作。
· Scala 將 Akka 作為一個標(biāo)準(zhǔn)庫官地,支持豐富的并發(fā)模型酿傍。這使得程序員很容易的就可以實(shí)現(xiàn)流數(shù)據(jù)的復(fù)雜創(chuàng)建或處理。
看到這里驱入,也難怪 Scala 當(dāng)時那么受歡迎赤炒,被視為引領(lǐng)函數(shù)編程的主流語言。然而用 William H. Calvin 的話來說亏较,“你總是可以通過背后的箭頭發(fā)現(xiàn)先驅(qū)者莺褒。”毫無疑問雪情,Scala 便是函數(shù)編程得以普及的先驅(qū)遵岩。那么,為什么現(xiàn)在的趨勢又轉(zhuǎn)向 Scala 了呢巡通,今天它的開發(fā)者們是又如何到了穩(wěn)步縮減的地步尘执?
· Java 編程語言引入了函數(shù)式編程結(jié)構(gòu),始于2014年初發(fā)布的 Java 8宴凉。Scala 和 Java 支持的函數(shù)編程方式有著微妙的差別正卧,有爭議的是,Scala 的方法更勝一籌跪解。但是,作為優(yōu)秀的函數(shù)編程語言签孔,Java 已經(jīng)超越了Scala叉讥,因?yàn)槌绦騿T們對 Java 已經(jīng)很了解了。這讓人聯(lián)想到 Adobe Flex 和 Microsoft Silverlight饥追,它在 Web UI 程序員中有相當(dāng)大的跟風(fēng)性图仓,直到發(fā)布了 HTML 5,HTML 5 提供了足夠的 Web UI 特性但绕,使其成為主流技術(shù)救崔。
· Scala 是一門很難掌握的語言,因?yàn)樗囊?guī)則是基于數(shù)學(xué)類型理論下的捏顺,只有最具學(xué)術(shù)和數(shù)學(xué)天分的程序員才能夠完全理解六孵。此外,Scala 的很多語言特性幅骄,包括隱性和宏劫窒,可能導(dǎo)致程序控制意外流到代碼庫的其他部分,這使得大多數(shù)程序員難以跟蹤或調(diào)試其代碼拆座。一個能夠領(lǐng)會這一切的優(yōu)秀程序員主巍,使用 Scala 會比使用 Java 更高效冠息,但是一個普通程序員的生產(chǎn)力,從功能實(shí)現(xiàn)上來看孕索,效率則會相反逛艰。這不僅僅是由于學(xué)**曲線的短期下降 — 這是一些開發(fā)團(tuán)隊(duì)使用 Scala 一整年后的觀察結(jié)果。
· 不像 Java搞旭,Scala有一個靈活的語法散怖,通常會提供很多方法來達(dá)到相同的結(jié)果。除了讓 Scala 為更多的程序員所用外选脊,Scala 社區(qū)似乎花了很多時間來討論杭抠,這個幾個功能解決方案哪個是正確的。這些爭論聚集了很高的熱度恳啥,并且防止出現(xiàn)在其他更具限制性的語言(如Java)中存在的嘗試和真正的實(shí)現(xiàn)模式偏灿。
· Scala 還沒有做好保持兼容性的工作,無論是早期版本的 Scala 還是 Java钝的。
鑒于這些問題翁垂,Scala 很可能永遠(yuǎn)不會演變成 Java 這樣的主流編程語言,但仍然會有一些特殊案例硝桩,選擇 Scala 這種編程語言才是最合適的:
· 大數(shù)據(jù)處理:Scala 的優(yōu)勢非常適合大數(shù)據(jù)編程模型沿猜,其中任務(wù)采用了不可變集合作為輸入,使用 map 和 reduce 處理轉(zhuǎn)換集合碗脊,并生成新的結(jié)果集合啼肩。對于 Spark 等大數(shù)據(jù)工具,使用 Scala 的優(yōu)勢是壓倒性的衙伶,因?yàn)橐粋€程序的 Scala 版本通常比等效的 Java 程序縮短 5 到 10 倍祈坠。
· 創(chuàng)建特定領(lǐng)域的語言:通過為用戶提供可用于編寫腳本的特定領(lǐng)域的語言(DSL),可以很好的解決許多問題矢劲。例如赦拘,假設(shè)你的用戶要求用一個工具,使他們能夠安排和運(yùn)行自動化質(zhì)量檢測芬沉。由于你不能預(yù)測所有需要運(yùn)行的測試組合躺同,因此你需要為他們提供一種腳本語言,以便于他們?yōu)槿魏螆鼍岸x這些測試的順序和位置丸逸。由于其模式匹配蹋艺,語法靈活,操作符重載等特性黄刚,使 Scala 能夠獨(dú)特地適用于 DSLs 開發(fā)车海。
總結(jié)
Scala 在函數(shù)編程普及的過程中起到了關(guān)鍵性的催化劑作用,它對 Java 中的函數(shù)式編程設(shè)計(jì)產(chǎn)生了很大的影響。Scala 可能永遠(yuǎn)不會成為下一個巨星編程語言侍芝,但是研铆,在未來幾年內(nèi),它將成為大數(shù)據(jù)編程等細(xì)分問題領(lǐng)域的首選語言州叠。
英文原文:The Rise and Fall of Scala
譯文作者:DevStore-糖果果