其實(shí),站在一個(gè)初學(xué)者的角度,我沒有辦法很好的回答這些問題。我一開始去學(xué)習(xí)這門語言,只是想去了解函數(shù)式編程這種與之前所學(xué)的、所用的編程方式完全不同的編程思維。你問我學(xué)會(huì)了能做什么,呵呵,多學(xué)點(diǎn)東西又不會(huì)死。 下面是正文: 2012年,我和我的合伙人共同創(chuàng)辦了一家公司----Better,一家新型的面向企業(yè)的線上學(xué)習(xí)平臺(tái)。 我們的目標(biāo)是讓大公司更快、更便宜地開發(fā),提供適應(yīng)性,跨平臺(tái),多語言的在線課程。 從第一天起,我們就決定使用Haskell作為我們的主要開發(fā)語言,直到我們的團(tuán)隊(duì)已經(jīng)擴(kuò)展到了10個(gè)開發(fā)人員,它仍然是我們?cè)诤蠖耸褂玫奈ㄒ徽Z言。 經(jīng)過一段時(shí)間的試驗(yàn)和開發(fā),Better在幾個(gè)月的時(shí)間里,經(jīng)常性收入從0美元增長(zhǎng)到了500K+,客戶包括了美國(guó)運(yùn)通和Swissport等大型企業(yè)。然而,分布式的模式被證明是更有效的解決方案,我們最終出售給GRC Solutions,一家澳大利亞的合規(guī)公司。 盡管大家對(duì)Haskell的興趣似乎在不停的增長(zhǎng),但它在生產(chǎn)環(huán)境中的使用仍然少之又少。有些人甚至錯(cuò)誤的認(rèn)為這只是一門學(xué)術(shù)語言,別的什么都做不了。在這篇文章中,我想告訴大家我對(duì)項(xiàng)目中使用Haskell的一些看法。你能用它完成項(xiàng)目么?它能在實(shí)踐中保持穩(wěn)定么?你能招到相應(yīng)的開發(fā)人員么?是否更多的公司應(yīng)該使用它? 我對(duì)上面問題的回答是YES。這可能不會(huì)適用于所有的問題或者所有的團(tuán)隊(duì),但這樣做絕對(duì)值得考慮。對(duì)于構(gòu)建服務(wù)端,Haskell可能是你現(xiàn)在所能找到的最接近秘密武器的東西。 為什么我們選擇Haskell?在創(chuàng)建Better幾年前,我為一家財(cái)務(wù)顧問公司開發(fā)了一個(gè)預(yù)測(cè)模型。第一款原型是使用Python開發(fā)的,結(jié)果這個(gè)模型很脆弱而且總是會(huì)出錯(cuò)。我該如何確保變量的類型不會(huì)改變?我該如何避免函數(shù)中某個(gè)值發(fā)生突變?我需要花很多時(shí)間去寫大量的測(cè)試用例,才能保證程序不出錯(cuò)。 我回想起了大學(xué)時(shí)學(xué)過的Haskell。用Haskell做了幾天的實(shí)驗(yàn)之后,我驚訝的發(fā)現(xiàn),Haskell似乎更適合這個(gè)任務(wù)。工作了一周之后,我得到了一個(gè)粗糙版本的預(yù)測(cè)模型。后來,當(dāng)我們開始創(chuàng)辦Batter時(shí),我相信Haskell會(huì)比其他常用的語言更有效率。 Haskell擁有純凈、惰性、靜態(tài)強(qiáng)類型和類型推斷等特性,這些特性讓它跟別的語言區(qū)分開來。純凈而沒有副作用,讓開發(fā)者更容易查找程序中存在的問題。惰性讓我們更好進(jìn)行函數(shù)組合和性能優(yōu)化(以更難以理解的存儲(chǔ)開銷為代價(jià))。靜態(tài)強(qiáng)類型和類型推斷機(jī)制,保證了程序的一致性,讓重構(gòu)更快樂,順手消除了一大波bug,還不用編寫和維護(hù)測(cè)試用例。把這些特性疊加在一起,絕對(duì)是一種愉快而且高效的開發(fā)體驗(yàn)。 使用Haskell能把事情辦好么?如果你從頭開始構(gòu)建項(xiàng)目,Haskell完全能夠讓你用相當(dāng)有限的知識(shí)完成工作。用Haskell寫的代碼可能不會(huì)特別整潔和高效。但是最終你會(huì)發(fā)現(xiàn),僅僅使用5行代碼,就可以建立一個(gè)標(biāo)準(zhǔn)的可以被不斷重用的抽象。 對(duì)有經(jīng)驗(yàn)的開發(fā)者來說,提高Haskell的運(yùn)行效率是一個(gè)不小的挑戰(zhàn)。這對(duì)新手來說實(shí)在是太不友好了,為了提高效率,你往往需要學(xué)習(xí)很多東西。Haskell十分重視概念和抽象,很多Haskell中的概念只是名字看上去比較嚇人,其實(shí)很好理解。學(xué)習(xí)Haskell時(shí),可以參考一些教科書,但是很多博客和論文也具有很重要的學(xué)習(xí)價(jià)值。Haskell不可能符合所有人的胃口,但其中思想的價(jià)值遠(yuǎn)超語言本身。如果通過學(xué)習(xí)Haskell,能夠影響你在編寫程序時(shí)的思維方式,那么目的就達(dá)到了。 在實(shí)際的使用中,我們對(duì)Haskell最大的抱怨之一是基本的工具支持。使用cabal-install構(gòu)建項(xiàng)目太不順利了。之后出現(xiàn)的Stack倒是減少了這方面的槽點(diǎn)。Stack對(duì)初學(xué)者來說是十分友好的,它讓大型Haskell項(xiàng)目的管理更加方便。你可以做許多其他工具鏈方面的標(biāo)準(zhǔn),像github上面的fork庫(kù),依賴fork庫(kù)就不必再發(fā)布包了。 Haskell的工具支持完全沒有達(dá)到它應(yīng)該有的樣子,特別是在IDE和編輯器的支持上??赡艽嬖诟鞣N不同的集成開發(fā)環(huán)境,而且目前來看還是十分混亂的,沒有一個(gè)通用的標(biāo)準(zhǔn)。對(duì)Haskell如此豐富而且有用的類型信息來說,這簡(jiǎn)直是個(gè)恥辱。 如果談到各種各樣的庫(kù),它們的覆蓋面雖然不是很大,但還是足夠使用的。我們也用Haskell寫了一些比較粗糙的內(nèi)部庫(kù)(比如通過Mandrill的API發(fā)送郵件)。Haskell同樣也有些很出名的庫(kù),但是去確定使用哪個(gè)更好并不容易,而且質(zhì)量差異也很大。如果不算內(nèi)存出現(xiàn)的問題的話,我們只遇到過一個(gè)嚴(yán)重的庫(kù)錯(cuò)誤,這個(gè)bug導(dǎo)致無法進(jìn)行https連接。 至于語言本身,Haskell的惰性要求使用者考慮更多的空間復(fù)雜度。其實(shí)是有很好的工具和技術(shù)能夠幫助開發(fā)者做到這一點(diǎn)的。你當(dāng)然可以編寫節(jié)省空間的代碼,但這需要你有意識(shí)的去做這些事情。至于語言本身,Haskell的惰性計(jì)算需要你考慮更多的空間復(fù)雜性。有很好的工具和技術(shù)來幫助解決這個(gè)問題,你當(dāng)然可以編寫節(jié)省空間的代碼,但它需要比使用嚴(yán)格的語言更有意識(shí)的努力。 也許你會(huì)通過使用更好和更強(qiáng)大的抽象來回收這種心理負(fù)荷。 還有一些其他小麻煩,如字符串類型之間的轉(zhuǎn)換,標(biāo)準(zhǔn)風(fēng)格的缺乏,沒有良好的記錄語法。Lenses確實(shí)解決了記錄的問題,但是這東西不好調(diào)試,而且需要花很多時(shí)間學(xué)習(xí)。 在日常使用中,Haskell其實(shí)是特別務(wù)實(shí)的。最關(guān)鍵的一點(diǎn),我認(rèn)為很難找到一個(gè)Haskell代碼庫(kù)有值得重構(gòu)的點(diǎn)。類型推斷系統(tǒng)和純度能夠在你閱讀代碼尋找bug時(shí)給你更多的信心。 Better在經(jīng)歷了幾次推到重寫之后,還是放棄了創(chuàng)建一個(gè)偉大軟件的雄心壯志。盡管我們對(duì)市場(chǎng)的判斷總是出錯(cuò),工程團(tuán)隊(duì)卻從未失敗過。 軟件穩(wěn)定么?Batter平臺(tái)每周大約會(huì)產(chǎn)生50萬次的用戶學(xué)習(xí)行為,它已經(jīng)運(yùn)行了一年多,沒有停機(jī),也沒有維護(hù)。我們至今還沒有找到任何bug。到最后,在停止平臺(tái)的開發(fā)之前,我們做了一次重大的重構(gòu)。 我只是舉些例子來當(dāng)證據(jù),軟件運(yùn)行的那么穩(wěn)定讓我也感到很驚訝。 我們有一個(gè)偉大的工程師團(tuán)隊(duì),他們值得信任,我也同樣信任Haskell。 我們沒有使用測(cè)試驅(qū)動(dòng)開發(fā),我們僅僅針對(duì)關(guān)鍵部分進(jìn)行了測(cè)試。 這似乎是正確的成本/質(zhì)量權(quán)衡方式。如果你現(xiàn)在問我,我仍然會(huì)這么做。 Haskell的類型推斷系統(tǒng)使開發(fā)者不必像在弱類型語言中那樣,需要寫一堆的測(cè)試用例來捕獲不一致。 具有類型推斷系統(tǒng),可以減少編寫和維護(hù)測(cè)試用例帶來的成本。我認(rèn)為,測(cè)試驅(qū)動(dòng)開發(fā)的論點(diǎn)不僅僅是編寫測(cè)試來捕捉bug, 它同樣有助于開發(fā)人員更清楚地思考問題。 然而,Haskell的純凈和類型比測(cè)試驅(qū)動(dòng)開發(fā)這種方式強(qiáng)有力多了?!耙坏┚幾g通過,它就能工作”,這句話可不是個(gè)玩笑哦。 我可不是說測(cè)試不重要,相反,測(cè)試其實(shí)是相當(dāng)重要的。 類型系統(tǒng)能夠保證類型的一致性,但是一致的程序也可以做錯(cuò)事。測(cè)試是迭代速度和質(zhì)量之間的折衷, 不同的業(yè)務(wù)需要不同的權(quán)衡。 Haskell也有方便你做測(cè)試的優(yōu)秀工具。 例如,QuickCheck可以基于工程師所指定的程序應(yīng)該保持的屬性,來自動(dòng)生成大量的隨機(jī)測(cè)試用例(利用Haskell的類型系統(tǒng))。 因此,Haskell似乎特別適合用于對(duì)軟件的正確性和質(zhì)量要求較高的項(xiàng)目中。 你可能期望以減少迭代速度為代價(jià)保證它的安全性,但有趣的是,你將會(huì)發(fā)現(xiàn)自己的迭代速度遠(yuǎn)比比使用弱類型,非純凈語言更快。 你能雇到寫Haskell的人么?Better這個(gè)項(xiàng)目是在蘇黎世進(jìn)行的。我們剛開始進(jìn)行時(shí),不知道這里有誰會(huì)使用Haskell,但是招聘開發(fā)人員比我們預(yù)想的要容易的多,這很大程度上都要?dú)w功于Haskell。找到合適的開發(fā)者還是需要花一些力氣的,但我們的經(jīng)驗(yàn)是,很多來面試的開發(fā)人員得知能夠用Haskell開發(fā)項(xiàng)目時(shí)都表現(xiàn)的很興奮。我們終結(jié)了一個(gè)偉大的團(tuán)隊(duì),其中幾個(gè)人是從國(guó)外搬到蘇黎世與我們合作的。很早的時(shí)候我們就決定公司不走遠(yuǎn)程開發(fā)的模式,但如果您的團(tuán)隊(duì)愿意接受遠(yuǎn)程開發(fā),您應(yīng)該會(huì)有更多的可供選擇的機(jī)會(huì)。 我們根據(jù)我們自己的需求,將技術(shù),興趣和動(dòng)機(jī)這些條件混合起來作為招人的標(biāo)準(zhǔn),根據(jù)這些標(biāo)準(zhǔn)我們招到了幾個(gè)技術(shù)很棒的Haskellers。我們當(dāng)然雇傭過只有一些Haskell基礎(chǔ)的人。我們的一位開發(fā)人員是直接從物理學(xué)學(xué)位過來的,在生產(chǎn)環(huán)境的指導(dǎo)下迅速成為了經(jīng)驗(yàn)豐富的開發(fā)人員。 雖然我們的薪資水平不能與Google,IBM蘇黎世研究院或本地的大型銀行相提并論,但我們?nèi)匀荒芪絻?yōu)秀的人才。使用Haskell是我們能做到這一點(diǎn)的原因之一 ---- 好的開發(fā)人員傾向于使用更好的技術(shù)。 它對(duì)公司的文化有什么影響么?很難將編程語言對(duì)工程師文化,雇傭決策,管理風(fēng)格和個(gè)人特性的影響分離開來,因此我們的工程師文化是深受Haskell影響的。 人們不會(huì)為了高薪而學(xué)習(xí)Haskell。市面上并沒有足夠的需要Haskell的工作。這種語言也比其他語言更難學(xué)習(xí),這會(huì)過濾掉那些不愿意努力學(xué)習(xí)有趣的東西如functors,applicatives和monads的人。 這樣做的好處是,如果你雇傭的人花了一點(diǎn)時(shí)間學(xué)習(xí)了Haskell,他們可能會(huì)比平常人更有內(nèi)在動(dòng)機(jī)來編寫代碼和學(xué)習(xí)新東西。缺點(diǎn)是他們很有可能厭惡工作,因?yàn)楣ぷ魇窃诶速M(fèi)和減少學(xué)習(xí)的機(jī)會(huì)。 因此,我認(rèn)為選擇Haskell有助于建立我們想要的工程師文化,但它不是魔法 ---- 我們也花了很大的力氣去招聘,我們?cè)噲D做的更加公平,我們尋找那些能夠駕馭各種語言的開發(fā)者。 那么,你應(yīng)該使用Haskell嗎?Haskell并不適合所有人。它不同于大多數(shù)開發(fā)人員的習(xí)慣。它需要學(xué)習(xí)各種很抽象的概念。它的生態(tài)系統(tǒng)不像現(xiàn)在流行的那些語言那么成熟。它不是最快的語言,黑客一起快速開發(fā)原型也需要2天。它有垃圾收集,因此它不適合實(shí)時(shí)系統(tǒng)。它的空間復(fù)雜度總是變幻莫測(cè)的。擁有Haskell生產(chǎn)經(jīng)驗(yàn)的人少之又少。 但如果缺點(diǎn)不會(huì)破壞你的面試,你可能會(huì)得到一個(gè)很棒的待遇。 Haskell適合在小型的,技術(shù)熟練的和不斷成長(zhǎng)的團(tuán)隊(duì)中使用。隨著你的代碼庫(kù)的擴(kuò)展和發(fā)展,Haskell處理復(fù)雜性,澄清思維和確保一致性的能力是一個(gè)福音。 你不用擔(dān)心服務(wù)器會(huì)崩潰這種問題,放心去睡大覺就好啦。你不需要花很多時(shí)間在舊代碼中尋找bug。你能夠相當(dāng)自信、敏捷地重構(gòu)。在招聘時(shí),你也會(huì)從Java,Node和Ruby等等市場(chǎng)中脫穎而出。你會(huì)開始在全新的抽象方式中考慮如何構(gòu)建程序。誰知道呢,你甚至?xí)窒硎苣愕墓ぷ髂亍?/p> 如果回頭重新去過在Better的那幾年,很多事情我也許會(huì)做不同的選擇,但是選擇Haskell作為主要的開發(fā)語言這一點(diǎn),我始終不會(huì)改變。 |
|