自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

開發(fā) 前端 存儲
在本文中,我將嘗試對流行的(而不是那么流行的)現(xiàn)代編程語言進行客觀,公正的概述,從最壞到最好的排名。

特定編程語言的優(yōu)缺點是什么?X是我的任務(wù)很好的語言嗎?搜尋"最佳編程語言"將為您提供" Python,Java,JavaScript,C#,C ++,PHP"的標準列表,以及優(yōu)缺點的模糊列表??吹竭@樣的文章會讓我感到痛苦,他們的作者一定是完全懶惰,缺乏經(jīng)驗,同時又缺乏想象力。讓我們深入研究一下,找出真正的缺點,而不是什么。

[[357219]]

在本文中,我將嘗試對流行的(而不是那么流行的)現(xiàn)代編程語言進行客觀,公正的概述,從最壞到最好的排名。

請記住,沒有一種編程語言可以完美地適合所有可能的用例。一些語言最適合于前端開發(fā),其他語言最適合于后端/ API開發(fā),其他語言則非常適合系統(tǒng)編程。

我將介紹世界上兩個最常見的語言家族-語言是C衍生的,而語言是ML衍生的。

編程語言只是開發(fā)人員工具箱中的工具。選擇正確的工具來完成這項工作很重要。我真的希望本指南將幫助您選擇最適合您任務(wù)的編程語言。做出正確的選擇可以節(jié)省您數(shù)月(甚至數(shù)年)的開發(fā)工作。

哪些語言特征真正重要?

[[357220]]

大多數(shù)其他類似的文章都根據(jù)受歡迎程度和潛在收入等因素進行比較。受歡迎程度很少是一個很好的衡量標準,尤其是在軟件領(lǐng)域(盡管大型社區(qū)和生態(tài)系統(tǒng)會有所幫助)。相反,我將考慮特定語言的優(yōu)點和缺點。

我將使用大拇指(即+1),大拇指朝下或OK(無論好壞)表情符號來表示特定語言特征的得分。

現(xiàn)在,我們將如何衡量?換句話說,除了語言流行之外,真正重要的是什么?

一、類型系統(tǒng)

[[357221]]

許多人按類型系統(tǒng)發(fā)誓。因此,近年來諸如TypeScript之類的語言開始流行。我傾向于同意,類型系統(tǒng)消除了程序中的大量錯誤,并使重構(gòu)更加容易。但是,"擁有"類型系統(tǒng)只是故事的一部分。

如果語言具有類型系統(tǒng),那么進行類型推斷也非常有用。最好的類型系統(tǒng)能夠推斷大多數(shù)類型,而無需顯式注釋功能簽名。不幸的是,大多數(shù)編程語言僅提供基本的類型推斷。

對于類型系統(tǒng)來說,支持數(shù)字數(shù)據(jù)類型也很好(稍后會詳細介紹)。

最強大的類型系統(tǒng)支持高級類型,這是泛型之上的抽象級別,并允許我們以更高的抽象級別進行編程。

我們還必須記住,人們往往對類型系統(tǒng)過于重視。有些事情遠比靜態(tài)類型重要,選擇類型時,類型系統(tǒng)的存在與否并不是唯一的因素。

(1) 學(xué)習(xí)曲線

[[357222]]

我們可能擁有完美的編程語言,但是如果新入職的開發(fā)人員可能要花費數(shù)月甚至數(shù)年(前期投資)來學(xué)習(xí),它將有什么用?另一方面,某些編程范例需要花費數(shù)年才能變得精通。

一門好的語言應(yīng)該適合初學(xué)者,并且不需要花幾年的時間就能掌握。

(2) 空值

[[357223]]

我稱之為我的十億美元錯誤。它是1965年創(chuàng)建的空引用。當時,我正在設(shè)計第一個全面的類型系統(tǒng),用于面向?qū)ο蟮恼Z言中的引用。我的目標是確保對引用的所有使用都絕對安全,并由編譯器自動執(zhí)行檢查。但是我忍不住要插入一個空引用的誘惑,僅僅是因為它很容易實現(xiàn)。這導(dǎo)致了無數(shù)錯誤,漏洞和系統(tǒng)崩潰,在最近四十年中可能造成十億美元的痛苦和破壞。

-空引用的發(fā)明者托尼·霍爾(Tony Hoare)

為什么空引用不好?空引用中斷類型系統(tǒng)。當null為默認值時,我們將不再依賴編譯器來檢查代碼的有效性。任何可為空的值都是等待爆炸的炸彈。如果我們嘗試使用我們不認為可能為空但實際上為空的值怎么辦?我們得到一個運行時異常。

我們必須依靠手動運行時檢查來確保所處理的值不為null。即使使用靜態(tài)類型的語言,空引用也剝奪了類型系統(tǒng)的許多好處。

實際上,這種運行時檢查(有時稱為空防護)是針對不良語言設(shè)計的解決方法。他們用樣板亂碼。最糟糕的是,我們無法保證不會忘記檢查null。

用一種好的語言,應(yīng)該在編譯時檢查值的缺失或存在。

鼓勵使用其他機制處理缺失數(shù)據(jù)的語言將排名更高。

(3) 錯誤處理

[[357224]]

捕獲異常是處理錯誤的一種壞方法。拋出異常是可以的,但僅在例外情況下,程序無法恢復(fù)并且必須崩潰。就像空值一樣,異常會破壞類型系統(tǒng)。

當使用異常作為錯誤處理的主要方式時,就無法知道函數(shù)是返回期望值還是崩潰。引發(fā)異常的函數(shù)也是不可能組成的。

顯然,僅僅由于我們無法獲取某些數(shù)據(jù)而導(dǎo)致整個應(yīng)用程序崩潰是不可能的。但這確實比我們想要的更經(jīng)常發(fā)生。

一種選擇是手動檢查引發(fā)的異常,但是這種方法很脆弱(我們可能會忘記檢查異常),并且會增加很多噪音:

如今,有更好的錯誤處理機制,可能的錯誤應(yīng)在編譯時進行類型檢查。默認情況下不使用例外的語言將排名更高。

(4) 并發(fā)

[[357225]]

我們已經(jīng)到了摩爾定律的盡頭,處理器將不會更快。我們生活在多核CPU時代,實際上,任何現(xiàn)代應(yīng)用程序都必須利用多核。

不幸的是,當今使用的大多數(shù)編程語言都是在單核計算時代設(shè)計的,根本不具備可在多核上有效運行的功能。

幫助并發(fā)的庫是事后的想法,它們只是向最初不是為并發(fā)設(shè)計的語言添加了創(chuàng)可貼。這并不是真正的良好開發(fā)經(jīng)驗。在現(xiàn)代語言中,必須內(nèi)置并發(fā)支持(請考慮使用Go / Erlang / Elixir)。

(5) 不變性

[[357226]]
我認為,當構(gòu)建可變對象的大對象圖時,大型面向?qū)ο蟮某绦驎絹碓綇?fù)雜。你知道,嘗試理解并牢記當調(diào)用方法時會發(fā)生什么副作用。

— Clojure的創(chuàng)建者Rich Hickey。

如今,使用不變的值進行編程變得越來越流行。甚至像React這樣的現(xiàn)代UI庫也打算與不可變值一起使用。具有對不可變數(shù)據(jù)值的一流支持的語言將排名更高。僅僅因為不變性消除了我們代碼中的一整類錯誤。

什么是不可變狀態(tài)?簡而言之,它是不變的數(shù)據(jù)。就像大多數(shù)編程語言中的字符串一樣。例如,大寫字符串永遠不會更改原始字符串-始終會返回一個新字符串。

不變性進一步推動了這一想法,并確保一切都沒有改變。總會返回一個新數(shù)組,而不是更改原始數(shù)組。更新用戶名?將返回一個新的用戶對象,并更新其名稱,同時保留原始對象。

處于不可變狀態(tài)時,不會共享任何內(nèi)容,因此我們不再需要擔心線程安全性的復(fù)雜性。不變性使我們的代碼易于并行化。

不改變?nèi)魏螤顟B(tài)的函數(shù)稱為純函數(shù),它們很容易測試和推理。使用純函數(shù)時,我們不必擔心函數(shù)之外的任何事情。只需專注于正在使用的這一函數(shù),而忽略其他所有函數(shù)。你可能可以想象,開發(fā)變得多么容易(與OOP相比,必須牢記整個對象圖)。

(6) 生態(tài)系統(tǒng)/工具

[[357227]]

語言可能不是很好,但是它可能具有龐大的生態(tài)系統(tǒng),因此很有吸引力。訪問優(yōu)質(zhì)的庫可以節(jié)省一個月(甚至幾年)的開發(fā)工作。

我們已經(jīng)看到JavaScript和Python等語言會發(fā)生這種情況。

(7) 速度

[[357228]]

語言的編譯速度如何?程序啟動速度有多快?運行時性能如何?所有這些都很重要,并將列入排名。

(8) 年齡

[[357229]]

盡管有一些例外,但通常來說,較新的語言會比較舊的語言更好。僅僅因為更新的語言可以從其前輩的錯誤中學(xué)習(xí)。

二、C ++

 

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

 

 

[[357231]]

 

 

讓我們從最壞的情況入手,這可能是計算機科學(xué)中最大的錯誤之一,C ++。是的,C ++不被認為是一種嶄新的現(xiàn)代編程語言。但是今天它仍在廣泛使用,必須將其包括在列表中。

語言家族:C.

(1) 語言功能

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

C ++是一種可怕的語言……而且將項目限制為C意味著人們不會用任何愚蠢的"對象模型" c&@ p弄亂事情。— Linux的創(chuàng)建者Linus Torvalds。

C ++具有許多功能。它嘗試做所有事情,同時又不擅長任何特定的事情。C ++具有g(shù)oto,指針,引用,OOP,運算符重載和許多其他非生產(chǎn)性功能。

為什么C ++如此糟糕?我認為,最大的原因是它的年齡。C ++是在1979年設(shè)計的很早的時候。當時的設(shè)計師缺乏經(jīng)驗,也不知道該關(guān)注什么。當時添加的功能似乎是個好主意。該語言非常流行,這意味著添加了許多功能來支持各種用例(創(chuàng)建更大的功能混亂)。

(2) 速度

C ++因其編譯時間慢而臭名昭著。比Java慢得多,不如Scala。

但是,運行時性能以及啟動時間都很好。

(3) 生態(tài)/工具

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

以上推文很有意義。C ++編譯器

(4) 垃圾收集

我曾希望可以選擇啟用的垃圾收集器將成為C ++ 0x的一部分,但是存在足夠的技術(shù)問題……

-C ++的創(chuàng)建者Bjarne Stroustrup

垃圾回收從未添加到C ++中。手動內(nèi)存管理極易出錯。開發(fā)人員必須擔心手動釋放和分配內(nèi)存。我將永遠不會錯過使用非垃圾收集語言的日子,如今在垃圾收集語言中很容易避免許多錯誤。

(5) attempt失敗的面向?qū)ο缶幊虈L試

我發(fā)明了術(shù)語"面向?qū)ο?quot;,可以告訴您我沒有C ++。

-Alan Kay,面向?qū)ο缶幊痰陌l(fā)明者。

OOP出現(xiàn)于60年代后期,是C ++工作開始時的一項很酷的新技術(shù)。不幸的是,C ++在實現(xiàn)OOP時犯了一些關(guān)鍵錯誤(與Smalltalk等語言不同),這使一個好主意變成了一場噩夢。

與Java相比,C ++的一件好事是C ++中的OOP至少是可選的。

(6) 學(xué)習(xí)曲線

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

> Mercurial_Rhombus on Reddit

C ++是一種復(fù)雜的低級語言,沒有自動內(nèi)存管理。由于其功能膨脹,初學(xué)者不得不花很多時間學(xué)習(xí)該語言。

(7) 并發(fā)

C ++是在單核計算時代設(shè)計的,在過去的十年中僅添加了基本的并發(fā)機制。

(8) 錯誤處理

捕獲/拋出錯誤是首選的錯誤處理機制。

(9) 不變性

沒有對不可變數(shù)據(jù)結(jié)構(gòu)的內(nèi)置支持。

(10) 空值

在C ++中,所有引用都是可為空的。

(11) 結(jié)論0.5星

[[357233]]

最初旨在成為C的更好版本的C ++確實未能實現(xiàn)目標。

C ++的最佳用途可能是系統(tǒng)編程。但是,鑒于存在更好,更現(xiàn)代的替代方案(Rust and Go),C ++甚至不應(yīng)該用于此。我認為C ++毫無優(yōu)勢,請隨時證明我是錯的。

C ++,你該走了。

三、Java

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

[[357235]]

自從MS-DOS以來,Java是計算機行業(yè)中最令人困擾的事情。

-Alan Kay,面向?qū)ο缶幊痰陌l(fā)明者。

自1995年首次出現(xiàn)以來,Java比C ++年齡小16歲。Java是一種簡單得多的語言,這可能有助于其流行。

語言家族:C.

(1) 垃圾收集

Java提供的優(yōu)于C ++的最大好處之一是垃圾收集,垃圾收集本身消除了許多錯誤。

(2) 生態(tài)

Java已經(jīng)存在了很長時間,并且它具有一個龐大的用于后端開發(fā)的生態(tài)系統(tǒng),從而大大減少了開發(fā)工作。

(3) 面向?qū)ο笳Z言

在這里,我不會深入探討OOP的缺點,有關(guān)更詳細的分析,可以閱讀我的其他文章《面向?qū)ο缶幊?mdash;萬億美元災(zāi)難》。

相反,我只是引用一些計算機科學(xué)領(lǐng)域最杰出的人,以得到他們對OOP的看法:

很抱歉,我很久以前就為該主題創(chuàng)造了"對象"一詞,因為它使許多人專注于較小的想法。大想法是消息傳遞。

-OOP的發(fā)明者艾倫·凱(Alan Kay)

艾倫·凱(Alan Kay)是對的,主流的OOP語言專注于錯誤的事物(類和對象),而忽略了消息傳遞。值得慶幸的是,現(xiàn)代語言正確地實現(xiàn)了這個想法(Erlang / Elixir)。

 使用受OOP影響的編程語言,計算機軟件變得更冗長,可讀性更差,描述性更強,更難修改和維護。

—理查德·曼斯菲爾德(Richard Mansfield)

使用過OOP語言(例如Java或C#)并具有使用非OOP語言的經(jīng)驗的任何人都可以聯(lián)系。

(4) 速度

顯然,Java在Java虛擬機之上運行,而Java虛擬機的啟動時間很慢。我已經(jīng)看到,在JVM上運行的程序需要30秒甚至更長的時間才能啟動,這對于現(xiàn)代的云原生程序來說是不可接受的。

在較大的項目上,編譯速度很慢,這極大地影響了開發(fā)人員的生產(chǎn)力(盡管沒有Scala那樣糟糕)。

從好的方面來說,JVM的運行時性能確實不錯。

(5) 學(xué)習(xí)曲線

盡管Java是一種相當簡單的語言,但它對面向?qū)ο缶幊痰年P(guān)注使真正變得很難??梢暂p松編寫一個簡單的程序。但是,知道如何編寫可靠且可維護的面向?qū)ο蟠a可能要花十年的時間。

(6) 并發(fā)

Java是在單核計算時代設(shè)計的,并且像C ++一樣,僅具有基本的并發(fā)支持。

(7) 空值

在Java中,所有引用都是可為空的。

(8) 錯誤處理

捕獲/拋出錯誤是首選的錯誤處理機制。

(9) 不變性

沒有對不可變數(shù)據(jù)結(jié)構(gòu)的內(nèi)置支持。

(10) 結(jié)論 1星

[[357235]]

Java出現(xiàn)時是一種不錯的語言。太糟糕了,Java(與Scala不同)一直只專注于OOP。該語言非常冗長,并且受樣板代碼的影響很大。

Java退休的時候到了。

四、C#

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

[[357237]]

從根本上講,C#和Java之間幾乎沒有什么區(qū)別(因為C#的早期版本實際上是Java的Microsoft實現(xiàn))。

C#與Java共享大多數(shù)缺點。C#于2000年首次出現(xiàn),但比Java年齡小5歲,并且已經(jīng)從Java的錯誤中學(xué)到了一些東西。

語言家族:C.

(1) 語法

C#語法一直領(lǐng)先于Java。C#比樣板代碼遭受的痛苦更少。盡管C#是一種OOP語言,但它在冗長的方面更為重要。很高興看到C#語法在每個版本中都得到了改進,并增加了諸如表達式強健的函數(shù)成員,模式匹配,元組等功能。

(2) 面向?qū)ο笳Z言

就像Java一樣,C#主要關(guān)注OOP。再一次,我不會在這里花太多時間試圖說服OOP的缺點,我只想引用一些計算機科學(xué)領(lǐng)域的杰出人物。

我認為缺乏可重用性的是面向?qū)ο蟮恼Z言,而不是函數(shù)語言。因為面向?qū)ο笳Z言的問題在于它們擁有了它們所伴隨的所有隱式環(huán)境。你想要香蕉,但是得到的是一只大猩猩,拿著香蕉和整個叢林。

— Erlang的創(chuàng)建者Joe Armstrong

我必須同意Joe Armstrong的觀點,與函數(shù)(甚至命令性)代碼相比,重用面向?qū)ο蟮拇a非常困難。

提供面向?qū)ο蟮某绦蜃鳛檎_程序的替代方案……

—計算機科學(xué)的先驅(qū)Edsger W. Dijkstra

在我整個職業(yè)生涯中都使用過OOP和非OOP語言之后,我不得不同意與非OOP代碼相比,OOP代碼更難正確。

(3) 多范式?

C#聲稱是一種多范式語言。特別是,C#聲稱支持函數(shù)編程。我必須不同意,僅僅支持一流的函數(shù)還不足以使一種語言稱為函數(shù)式。

語言應(yīng)具有哪些功能?至少,對不可變數(shù)據(jù)結(jié)構(gòu),模式匹配,函數(shù)組合的管道運算符,代數(shù)數(shù)據(jù)類型的內(nèi)置支持。

(4) 并發(fā)

C#是在單核計算時代創(chuàng)建的,就像Java一樣,它僅具有基本的并發(fā)支持。

(5) 空值

在C#中,所有引用都是可為空的。

(6) 錯誤處理

捕獲/拋出錯誤是首選的錯誤處理機制。

(7) 不變性

沒有對不可變數(shù)據(jù)結(jié)構(gòu)的內(nèi)置支持。

(8) 結(jié)論 1.5星

[[357238]]

我在C#的職業(yè)生涯中花費了大量時間,并且總是對這種語言感到沮喪。與Java一樣,我建議您尋找更現(xiàn)代的替代方案。它是相同的Java,但語法更現(xiàn)代。

不幸的是,關(guān)于C#并沒有什么"尖銳"的東西。

Python

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

[[357240]]

自1991年首次出現(xiàn)以來,Python是一門古老的語言。與JavaScript一起,Python是世界上最受歡迎的語言之一。

語言家族:C.

(1) 生態(tài)

Python幾乎有任何庫。與JavaScript不同,Python無法用于前端Web開發(fā),但是Python可以輕松地構(gòu)建大量的數(shù)據(jù)科學(xué)庫。

(2) 學(xué)習(xí)努力

Python是一種非常簡單的語言,初學(xué)者可以在幾周內(nèi)掌握它們。

(3) 類型系統(tǒng)

Python是動態(tài)類型的,關(guān)于類型系統(tǒng)沒有太多要說的了。

(4) 速度

Python是一種解釋型語言,以運行時性能而言,它因為是最慢的編程語言之一而臭名昭著。在運行時性能至關(guān)重要的情況下,使用Cython代替普通的Python可能是一個很好的解決方案。

與本地語言相比,Python的啟動速度也很慢。

(5) 工具

在將Python和其他現(xiàn)代語言一起使用后,很難不對Python的依賴項管理感到失望。pip,pipenv,virtualenv等。相比之下,JavaScript中的NPM是您唯一需要的工具。

(6) 并發(fā)

創(chuàng)建Python時并沒有考慮到并發(fā)性,它僅具有基本的并發(fā)支持。

(7) 空值

在Python中,所有引用都是可為空的。

(8) 錯誤處理

捕獲/拋出錯誤是首選的錯誤處理機制。

不變性

沒有對不可變數(shù)據(jù)結(jié)構(gòu)的內(nèi)置支持。

(9) 結(jié)論 2星

[[357241]]

真的很不幸,Python沒有對函數(shù)式編程的適當支持。函數(shù)式編程非常適合于數(shù)據(jù)科學(xué)試圖解決的問題。即使對于諸如網(wǎng)絡(luò)抓取之類的非常Python的任務(wù),函數(shù)式語言(例如Elixir)也更合適。

我不建議將Python用于大型項目,因為該語言在構(gòu)建時并未考慮到嚴格的軟件工程。

當沒有其他替代方法可用時,Python不應(yīng)用于數(shù)據(jù)科學(xué)以外的其他任何用途。在數(shù)據(jù)科學(xué)領(lǐng)域,Julia似乎是Python的一個很好的現(xiàn)代替代品,盡管它的生態(tài)系統(tǒng)還不如Python成熟。

Rust

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

[[357240]]

Rust是一種現(xiàn)代的低級語言,最初被設(shè)計為C ++的替代語言。

語言家族:C.

(1) 速度

Rust從一開始就被設(shè)計為快速。Rust程序的編譯比Go程序的編譯花費更長的時間。Rust程序的運行時性能比Go快一點。

(2) 空值

我們列表中的第一種語言,帶有現(xiàn)代的null選擇!Rust沒有null或nil值,Rust開發(fā)人員改用Option Pattern。

(3) 錯誤處理

Rust采用了現(xiàn)代的功能性方法來處理錯誤,并使用專用的Result類型來表示可能失敗的操作。它與上面的選項非常相似,但是None情況現(xiàn)在也有一個值。

(4) 內(nèi)存管理

Rust是我們列表中唯一沒有垃圾回收的現(xiàn)代語言。這迫使開發(fā)人員考慮進行低級內(nèi)存管理,并使開發(fā)人員的工作效率下降。

(5) 并發(fā)

由于缺乏垃圾收集,因此在Rust中并發(fā)非常困難。開發(fā)人員必須擔心諸如裝箱和固定之類的事情,這些事情通常會以垃圾回收語言自動完成。

(6) 不變性

Rust沒有對不可變數(shù)據(jù)結(jié)構(gòu)的內(nèi)置支持。

(7) 低級語言

作為一種低級語言,Rust中的開發(fā)人員生產(chǎn)力無法達到其他高級語言中的水平。這也使學(xué)習(xí)努力變得更加困難。

(8) 結(jié)論 2星

[[357240]]

Rust非常適合系統(tǒng)編程。盡管它比Go更復(fù)雜,但它提供了強大的類型系統(tǒng)。Rust為空值提供了一種現(xiàn)代的替代方法,并提供了一種處理錯誤的現(xiàn)代方法。

為什么Rust仍然排名低于TypeScript和JavaScript?它是為系統(tǒng)編程設(shè)計的低級語言。Rust并非非常適合后端/ Web API開發(fā)。它缺少垃圾收集,并且不內(nèi)置對不變性的支持。

TypeScript

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

[[357244]]

TypeScript是一種js編譯語言。它的主要目標是通過向JavaScript添加靜態(tài)類型來制作"更好的JavaScript"。就像JavaScript一樣,TypeScript被用于前端和后端開發(fā)。

TypeScript是由設(shè)計C#的同一人Anders Hejlsberg設(shè)計的。TypeScript代碼感覺非常CSharp,從根本上講,可以將其視為瀏覽器的C#。

語言家族:C.

(1) JavaScript的超集

是的,JavaScript的超集對TypeScript的采用起到了很大的幫助。畢竟,很多人已經(jīng)知道JavaScript。

但是,作為JavaScript的超集更為不利。這意味著TypeScript承載了所有JavaScript包。它受到JavaScript中所有錯誤的設(shè)計決策的限制。

例如,有多少人喜歡this關(guān)鍵字?可能沒人,但是TypeScript故意決定保留它。

類型系統(tǒng)有時真的很奇怪嗎?

  1. [] == ![]; // -> true 
  2. NaN === NaN; // -> false 

換句話說,TypeScript具有JavaScript的所有缺點。成為一門糟糕的語言的超集并不能證明它是好的。

(2) 生態(tài)

TypeScript可以訪問整個JavaScript生態(tài)系統(tǒng),這是巨大的。巨大的好處。與特別是與其他語言(例如Python)相比,Node Package Manager非常令人愉快。

缺點是并非所有JavaScript庫都具有可用的TypeScript聲明。Rambda,一成不變。

(3) 類型系統(tǒng)

我對TypeScript中的類型系統(tǒng)不太滿意。

從好的方面來說,它甚至支持數(shù)值數(shù)據(jù)類型(區(qū)分聯(lián)合)

TypeScript語法不如功能語言更好。事后考慮,在TypeScript 2.0中添加了有區(qū)別的聯(lián)合。在此開關(guān)中,我們將匹配容易出錯的字符串,如果我們錯過了情況,編譯器將不會發(fā)出警告。

TypeScript僅提供基本的類型推斷。另外,在使用TypeScript時,你會發(fā)現(xiàn)使用頻率比你想要的更多。

(4) 空值

TypeScript 2.0添加了對非空類型的支持,可以選擇使用–strictNullChecks編譯器標志啟用它。但。使用非空類型進行編程不是默認設(shè)置,并且在TypeScript中不視為慣用語言。

(5) 錯誤處理

在TypeScript中,錯誤是通過引發(fā)/捕獲異常來處理的。

(6) JS新功能

JavaScript比TypeScript更快地支持酷炫的新功能。使用Babel,甚至可以在JavaScript中啟用實驗性功能,而TypeScript則無法實現(xiàn)。

(7) 不變性

在TypeScript中處理不可變數(shù)據(jù)結(jié)構(gòu)比在JavaScript中要差得多。盡管JavaScript開發(fā)人員可以使用有助于實現(xiàn)不變性的庫,但TypeScript開發(fā)人員通常必須依賴于本機數(shù)組/對象散布運算符(寫時復(fù)制):

不幸的是,本地傳播運算符不會執(zhí)行深層復(fù)制,而手動傳播深層對象很麻煩。復(fù)制大型數(shù)組/對象也不利于性能。

TypeScript中的readonly關(guān)鍵字很好,它使屬性不可變。但是,要支持正確的不可變數(shù)據(jù)結(jié)構(gòu)還有很長的路要走。

JavaScript具有用于處理不可變數(shù)據(jù)的良好庫(例如Rambda / Immutable.js)。但是,使此類庫與TypeScript類型系統(tǒng)一起使用可能非常棘手。

(8) TypeScript和React — 地獄般的匹配嗎?

用JavaScript [和TypeScript]處理不可變數(shù)據(jù)要比用Clojure這樣的語言處理困難。

-直接來自React文檔

延續(xù)先前的缺點,如果你正在進行前端Web開發(fā),那么你很可能正在使用React。

未為TypeScript創(chuàng)建React。最初,React是針對功能性語言編寫的(稍后會詳細介紹)。編程范例之間存在沖突-TypeScript是OOP優(yōu)先,而React是功能優(yōu)先。

React希望其props(即函數(shù)參數(shù))是不可變的,而TypeScript沒有對不可變數(shù)據(jù)結(jié)構(gòu)的適當內(nèi)置支持。

TypeScript通過JavaScript提供給React開發(fā)的唯一真正好處是,不必擔心PropTypes。

(9) 是TypeScript還是Hypescript?

[[357245]]

TypeScript只是一種炒作嗎?由你決定。我認為是這樣。它的最大好處是可以訪問整個JavaScript生態(tài)系統(tǒng)。

為什么HypeScript如此受歡迎?Java和C#受歡迎的原因相同-得到數(shù)十億公司的龐大營銷預(yù)算的支持。

(10) 結(jié)論 2星

[[357244]]

盡管通常認為TypeScript是"更好的JavaScript",但我認為它比JavaScript低。它提供的超過JavaScript的好處被高估了,特別是對于使用React進行前端Web開發(fā)。

TypeScript確實無法通過保留JavaScript的所有不良部分來交付,實際上無法繼承JavaScript中數(shù)十年的不良設(shè)計決策。

Go

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

[[357247]]

Go旨在幫助提高多核處理器和大型代碼庫時代的編程效率。Go的設(shè)計師主要是因為他們彼此不喜歡C ++,當時在Google廣泛使用了C ++。

語言家族:C.

(1) 并發(fā)

并發(fā)是Go的"殺手級"功能,Go是從頭開始為并發(fā)而構(gòu)建的。就像Erlang / Elixir一樣,Go遵循并發(fā)的消息模型。不幸的是,Go中的goroutine無法提供與Erlang / Elixir進程相同的容錯功能。換句話說,goroutine中的異常將導(dǎo)致整個程序崩潰,而Elixir進程中的異常將導(dǎo)致該程序崩潰。

(2) 速度

Google創(chuàng)建Go的主要原因之一是編譯速度。甚至有個笑話," Google在等待C ++代碼編譯的同時就創(chuàng)建了Go"。

Go是一種非常快速的語言。Go程序的啟動時間非常快。Go可以編譯為本機代碼,因此其運行速度也非常出色。

(3) 學(xué)習(xí)努力

Go是一種簡單的語言,有一定的編程經(jīng)驗的人大概一個月就能學(xué)到一門。

(4) 錯誤處理

Go不支持例外,而是Go使開發(fā)人員明確處理可能的錯誤。與Rust類似,Go返回兩個值-調(diào)用結(jié)果和潛在錯誤。如果一切順利,那么錯誤將為零。

(5) 沒有面向?qū)ο蟮木幊?/p>

盡管有些人可能會不同意,但我個人認為缺少OOP功能是一個很大的優(yōu)勢。

重復(fù)Linus Torvalds:

C ++是一種可怕的[面向?qū)ο骫語言…而且將你的項目限制為C意味著人們不會用任何愚蠢的“對象模型”。

— Linux的創(chuàng)建者Linus Torvalds

Linus Torvalds以對C ++和OOP的公開批評而聞名。他100%正確的一件事是限制程序員他們可以做出的選擇。實際上,程序員選擇的次數(shù)越少,代碼的彈性就越大。

在我看來,Go故意省略了許多OOP功能,以免重復(fù)C ++的錯誤。

(6) 生態(tài)

一些標準庫確實很笨。它的很大一部分與Go本身返回帶外錯誤的哲學(xué)是不一致的(例如,它們?yōu)樗饕皇?int,error)返回像-1的值),而其他則依賴于全局狀態(tài),例如flag和網(wǎng)絡(luò)/ http。

Go的標準庫中缺乏標準化。例如,某些庫在發(fā)生錯誤返回(int,error)的情況下,其他庫則返回諸如-1的值,而其他庫則依賴于全局狀態(tài)(如flag)。

生態(tài)系統(tǒng)遠沒有JavaScript大。

(7) 類型系統(tǒng)

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

 

幾乎每種現(xiàn)代編程語言都有一種或另一種形式的泛型(包括可怕的C#/ Java,甚至C ++都有模板)。泛型允許開發(fā)人員針對不同類型重用函數(shù)實現(xiàn)。如果沒有泛型,則必須分別為整數(shù),雙精度數(shù)和浮點數(shù)分別實現(xiàn)add函數(shù),從而導(dǎo)致大量代碼重復(fù)。換句話說,Go中缺少泛型會導(dǎo)致大量重復(fù)代碼。有人說," Go"是" Go寫一些樣板"的縮寫

(8) 空值

不幸的是,數(shù)十年來,更安全的替代方法已經(jīng)出現(xiàn),Go語言包含了空值。

(9) 不變性

Go沒有對不可變數(shù)據(jù)結(jié)構(gòu)的內(nèi)置支持。

(10) 結(jié)論 2.5星

[[357248]]
Go不是一種好語言。不算太差;只是不好。我們必須謹慎使用不好的語言,因為如果我們不謹慎,在接下來的20年中,我們可能最終會陷入困境。

-雅格(Will Yager)的《為什么Go不好》

如果你不是Google,并且沒有類似Google的用例,那么Go可能不是一個好選擇。Go是最適合系統(tǒng)編程的一種簡單語言。對于API開發(fā),Go不是一個好的選擇(原因是因為有很多更好的選擇可用,稍后再介紹)。

我認為總體而言,Go是一個比Rust更好的選擇(盡管類型系統(tǒng)較弱)。它是一種簡單的語言,非常快,易于學(xué)習(xí)并且具有出色的并發(fā)功能。是的,Go成功實現(xiàn)了成為"更好的C ++"的設(shè)計目標。

(11) 最佳系統(tǒng)語言獎

[[357249]]

最佳系統(tǒng)語言獎歸Go。毫無疑問,Go是系統(tǒng)編程的理想選擇。Go是一種低級語言,它非常適合該領(lǐng)域,這已被大量使用Go構(gòu)建的成功項目所證實,例如Kubernetes,Docker和Terraform。

JavaScript

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

[[357247]]

作為世界上最受歡迎的編程語言,JavaScript不需要介紹。

是的,這不是一個錯誤。JavaScript確實排在Rust,TypeScript和Go之上。讓我們找出原因。

語言家族:C.

(1) 生態(tài)

JavaScript的最大好處是其生態(tài)系統(tǒng)。JavaScript正在用于您可以想到的所有內(nèi)容-前端/后端Web開發(fā),CLI編程,數(shù)據(jù)科學(xué)甚至機器學(xué)習(xí)。JavaScript可能具有一個庫,可滿足您的所有需求。

(2) 學(xué)習(xí)曲線

JavaScript(以及Python)是最容易學(xué)習(xí)的編程語言之一。一個人可以在幾周內(nèi)用JavaScript變得富有成效。

(3) 類型系統(tǒng)

就像Python一樣,JavaScript是動態(tài)類型的,這里沒有太多要說的了。JavaScript的類型系統(tǒng)有時可能很奇怪:

(4) 不變性

如TypeScript部分所述,散布運算符可能會降低性能,甚至在復(fù)制對象時也不會執(zhí)行深層復(fù)制。JavaScript缺少對不可變數(shù)據(jù)結(jié)構(gòu)的內(nèi)置支持,盡管有一些庫可以提供幫助(Ramda / Immutable.js)。

(5) React不是為JavaScript設(shè)計的

在JavaScript中使用React時,必須使用PropTypes。但是,這也意味著必須維護PropType,這可能成為噩夢。

此外,如果您不小心,可能會引入細微的性能問題

這種看上去無辜的代碼可能成為性能的噩夢,因為在JavaScript中 []!= []。上面的代碼將使HugeList在每次更新時都重新呈現(xiàn),即使options值沒有更改。在最終無法使用UI之前,這些問題可能會更加復(fù)雜。

(6) This關(guān)鍵詞

JavaScript的最大反特性可能是this關(guān)鍵字。其行為始終不一致。它是挑剔的,在不同的上下文中可能意味著完全不同的事物。它的行為甚至取決于誰調(diào)用了給定的函數(shù)。通常使用此關(guān)鍵字會導(dǎo)致難以調(diào)試的細微而奇怪的錯誤。

(7) 并發(fā)

JavaScript使用事件循環(huán)支持單線程并發(fā)。這消除了對線程同步機制(如鎖定)的需要。盡管JavaScript并不是在考慮并發(fā)性的情況下構(gòu)建的,但是與大多數(shù)其他語言相比,使用并發(fā)代碼要容易得多。

(8) JS新功能

JavaScript比TypeScript更快地支持酷炫的新功能。使用Babel,甚至可以在JavaScript中啟用實驗功能。

(9) 錯誤處理

捕獲/拋出錯誤是首選的錯誤處理機制。

(10) 結(jié)論 2.5 星

[[357248]]

JavaScript不是一種精心設(shè)計的語言。JavaScript的初始版本在10天內(nèi)就放在一起了(盡管將來的版本已經(jīng)解決了許多缺點)。

盡管有缺點,JavaScript是全棧Web開發(fā)的不錯選擇。通過適當?shù)募o律和評價,JavaScript可以成為一門好語言。

函數(shù)式編程==放心

[[357251]]

> Photo by Ante Hamersmit on Unsplash

讓我們先繞道而行,然后再繼續(xù)排名。為什么要煩惱函數(shù)式編程?函數(shù)式編程使我們高枕無憂。

是的,函數(shù)式編程可能聽起來很嚇人,但實際上沒有什么可擔心的。簡而言之,函數(shù)式語言做出了許多正確的設(shè)計決策,而其他語言則做出了錯誤的決策。在大多數(shù)情況下,函數(shù)式語言將具有正確的功能:具有代數(shù)數(shù)據(jù)類型支持的功能強大的類型系統(tǒng),無null,錯誤處理無異常,內(nèi)置的不變數(shù)據(jù)結(jié)構(gòu),模式匹配,函數(shù)組合運算符。

函數(shù)式編程語言有哪些共同的優(yōu)勢使其在我們的排名中如此高?

(1) 使用純函數(shù)編程

[[357252]]

與命令式(主流語言)不同,函數(shù)式編程語言鼓勵使用純函數(shù)式編程。

什么是純函數(shù)?這個想法非常簡單-給定相同的輸入,純函數(shù)將始終返回相同的輸出。例如,2 + 2將始終返回4,這意味著加法運算符+是純函數(shù)。

純函數(shù)不允許與外界進行交互(進行API調(diào)用,甚至無法寫入控制臺)。甚至不允許更改狀態(tài)。這與OOP所采取的方法完全相反,在OOP中,任何方法都可以自由地改變其他對象的狀態(tài)。

可以很容易地從不純函數(shù)中分辨出純函數(shù)-函數(shù)是不帶參數(shù),還是不返回值?然后,這是一個不純函數(shù)。

這種方法似乎很局限,可能需要一段時間才能習(xí)慣。起初,這肯定讓我感到困惑!

純函數(shù)有什么好處?它們非常易于測試(無需模擬和存根)。關(guān)于純函數(shù)的推理很容易-與OOP不同,無需牢記整個應(yīng)用程序狀態(tài)。您只需要擔心當前正在使用的功能。

純函數(shù)可以輕松組成。純函數(shù)對于并發(fā)非常有用,因為函數(shù)之間沒有共享狀態(tài)。重構(gòu)純函數(shù)是純粹的樂趣-只需復(fù)制和粘貼,無需復(fù)雜的IDE工具。

簡而言之,純函數(shù)將歡樂帶回到編程中。

函數(shù)式編程鼓勵使用純函數(shù)-當90%以上的代碼庫由純函數(shù)組成時,這很好。一些語言將其極端化,并完全禁止使用非純函數(shù)(這并不總是一個好主意)。

(2) 不變的數(shù)據(jù)結(jié)構(gòu)

[[357253]]

下面的所有功能語言都內(nèi)置了對不可變數(shù)據(jù)結(jié)構(gòu)的支持。數(shù)據(jù)結(jié)構(gòu)也是持久的。這只是意味著,無論何時進行更改,我們都不必創(chuàng)建整個結(jié)構(gòu)的深層副本。一次又一次地成像復(fù)制超過100,000個項目的陣列,這一定很慢,對吧?

持久數(shù)據(jù)結(jié)構(gòu)無需創(chuàng)建副本,而是簡單地重用對舊數(shù)據(jù)結(jié)構(gòu)的引用,同時添加所需的更改。

(3) 數(shù)值數(shù)據(jù)類型

[[357254]]

ADT是一種建模應(yīng)用程序狀態(tài)的強大方法??梢詫⑺鼈円暈轭惞檀嫉拿杜e。我們指定類型可以組成的可能的"子類型",以及其構(gòu)造函數(shù)參數(shù):

上面的"形狀"類型可以是正方形,矩形或圓形。Square構(gòu)造函數(shù)采用單個int參數(shù)(寬度),Rectangle采用兩個int參數(shù)(寬度和高度),而Circle采用單個int參數(shù)(其半徑)。

我不了解你,但我肯定會使用舊版本,并以功能語言使用ADT。

(4) 模式匹配

[[357255]]

所有功能語言都對模式匹配提供了極大的支持。通常,模式匹配允許人們編寫非常有表現(xiàn)力的代碼。

這是一個關(guān)于選項(布爾)類型的模式匹配的示例:

相同的代碼,沒有模式匹配:

毫無疑問,模式匹配版本更加富有表現(xiàn)力和簡潔。

模式匹配還提供了編譯時的詳盡性保證,這意味著我們將不會忘記檢查可能的情況。沒有以非功能性語言提供的此類保證。

(5) 空值

[[357256]]

函數(shù)式編程語言通常避免使用空引用。而是使用Option模式(類似于Rust):

(6) 錯誤處理

[[357224]]

通常不建議在功能語言中使用異常。而是使用Result模式(再次,類似于Rust):

要全面了解錯誤處理的功能方式,請確保閱讀OCaml中的Composable Error Handling。

(7) 管道前移運算符

[[357257]]

如果沒有管道前移運算符,函數(shù)調(diào)用往往會變得很嵌套,這使它們的可讀性降低:

函數(shù)式語言具有特殊的管道運算符,使該任務(wù)更加容易:

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

[[357259]]

(8) Huskell

語言家族:ML。

(9) 類型系統(tǒng)

沒有比Haskell更強大的文字系統(tǒng)了。顯然,Haskell支持代數(shù)數(shù)據(jù)類型,但它也支持類型類。它的類型檢查器幾乎可以推斷任何東西。

(10) 學(xué)習(xí)曲線

好家伙!為了有效地使用Haskell,必須首先精通類型理論(這不是我在開玩笑),這不是秘密。OOP需要多年的經(jīng)驗來編寫體面的代碼,而Haskell則需要投入大量時間進行前期學(xué)習(xí),才能提高生產(chǎn)力。

在Haskell中編寫甚至一個簡單的" hello world"程序也需要了解Monads(尤其是IO Monads)。

(11) 社區(qū)

根據(jù)我的經(jīng)驗,Haskell社區(qū)的學(xué)術(shù)性更高。最近在Haskell庫郵件列表中的帖子開始于:

"在一次私人交流中向我指出,元組函數(shù) x->(x,x)實際上是對雙應(yīng)用和一些相關(guān)結(jié)構(gòu)的對角化的特殊情況。"

它收到了39位漂亮的愛好者答復(fù)。

-Hacker News上的momentoftop

上面的引用很好地總結(jié)了Haskell社區(qū)。Haskell社區(qū)對學(xué)術(shù)討論(和類別理論)更感興趣,而不是解決實際問題。

(12) 函數(shù)純度

正如我們已經(jīng)了解的那樣,純函數(shù)是驚人的。副作用(例如,與外界互動,包括變異狀態(tài))是程序中大量錯誤的原因。作為純函數(shù)式語言,Haskell完全禁止使用它們。這意味著函數(shù)永遠不能更改任何值,甚至不允許與外界進行交互(從技術(shù)上來說,甚至不允許進行日志記錄之類的操作)。

當然,Haskell提供了與外界交互的解決方法。您可能會問它如何運作?我們提供了一組說明(IO Monad)。這樣的指令可能會說:讀取鍵盤輸入,然后在某些功能中使用該輸入,然后將結(jié)果打印到控制臺。然后,語言運行庫將獲取此類指令,并為我們執(zhí)行這些指令。我們永遠不會執(zhí)行直接與外界交互的代碼。

不惜一切代價避免成功!

-Haskell的非正式座右銘。

實際上,對函數(shù)純度的這種關(guān)注顯著增加了抽象的數(shù)量,從而增加了復(fù)雜性,并因此降低了開發(fā)人員的生產(chǎn)率。

(13) 空值

就像Rust一樣,Haskell也沒有null引用。它使用選項模式來表示可能不存在的值。

(14) 錯誤處理

盡管某些函數(shù)可能會引發(fā)錯誤,但慣用的Haskell代碼使用的模式類似于Rust中的Result類型。

(15) 不變性

Haskell對不可變數(shù)據(jù)結(jié)構(gòu)提供一流的支持。

(16) 模式匹配

Haskell具有出色的模式匹配支持。

(17) 生態(tài)

標準庫是一團糟,尤其是默認的前奏(核心庫)。默認情況下,Haskell使用引發(fā)異常的函數(shù)而不是返回選項值(函數(shù)編程的黃金標準)。更糟的是,Haskell有兩個包管理器-Cabal和Stack。

(18) 結(jié)論 3星

[[357260]]
核心函數(shù)式編程永遠不會成為主流-它需要深刻理解許多高度抽象的概念。

-David Bryant Copeland獲得了四個更好的軟件設(shè)計規(guī)則

我真的很想喜歡Haskell。不幸的是,Haskell可能會永遠局限于學(xué)術(shù)界。Haskell是函數(shù)式編程語言中最糟糕的嗎?我認為是你來決定的。

OCaml

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

[[357260]]

OCaml是一種函數(shù)式編程語言。OCaml代表對象Caml,但是具有諷刺意味的是,很少會在OCaml中找到使用對象的人。

OCaml幾乎和Java一樣古老,名稱中的"對象"部分可能反映了那個時代的"對象"炒作。OCaml只是在Caml離開的地方接機。

語言家族:ML。

(1) 類型系統(tǒng)

OCaml的類型系統(tǒng)幾乎與Haskell一樣好。最大的缺點是缺少類型類,但它支持仿函數(shù)(高階模塊)。

OCaml是靜態(tài)類型的,其類型推斷幾乎與Haskell一樣好。

(2) 生態(tài)

OCaml社區(qū)很小,這意味著您不會找到常見用例的高質(zhì)量庫。例如,OCaml缺少一個不錯的Web框架。

與其他語言相比,OCaml庫的文檔非常糟糕。

(3) 工具

工具是一團糟。共有三個包管理員-Opam,Dune和Esy。

OCaml以非常糟糕的編譯器錯誤消息而聞名。雖然不是交易破壞者,但這有點令人沮喪,并且會影響開發(fā)人員的生產(chǎn)率。

(4) 學(xué)習(xí)資源

學(xué)習(xí)OCaml的首選書籍是Real World OCaml。自2013年以來,該書尚未更新,并且許多示例已過時。使用現(xiàn)代工具不可能遵循本書。

通常,語言教程非常差(與其他語言相比)。它們大多是學(xué)術(shù)課程的講義。

(5) 并發(fā)

" Multicore即將到來的任何一天™️" —在OCaml中并發(fā)地總結(jié)了故事。OCaml開發(fā)人員一直在等待適當?shù)亩嗪酥С郑⑶宜坪醪粫诓痪玫膶硖砑拥皆撜Z言中。OCaml似乎是唯一缺少適當?shù)亩嗪酥С值墓δ苷Z言。

(6) 空值

OCaml沒有空引用,并使用選項模式來表示可能不存在的值。

(7) 錯誤處理

慣用的OCaml代碼使用Result類型模式。

(8) 不變性

OCaml對不可變數(shù)據(jù)結(jié)構(gòu)提供一流的支持。

(9) 模式匹配

OCaml具有出色的模式匹配支持。

(10) 結(jié)論 3星

[[357260]]

OCaml是一種很好的函數(shù)式語言。它的主要缺點是并發(fā)支持差,社區(qū)很小(因此生態(tài)系統(tǒng)很小,缺乏學(xué)習(xí)資源)。

鑒于其缺點,我不建議在生產(chǎn)中使用OCaml。

· 離開OCaml

Scala

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

[[357259]]

Scala是為數(shù)不多的真正多范例語言之一,對面向?qū)ο蠛秃瘮?shù)式編程都提供了很好的支持。

語言家族:C.

(1) 生態(tài)

Scala在Java虛擬機之上運行,這意味著它可以訪問龐大的Java庫生態(tài)系統(tǒng)。在后端工作時,這確實是提高開發(fā)人員工作效率的福音。

(2) 類型系統(tǒng)

Scala可能是唯一具有不健全的類型系統(tǒng)的類型化函數(shù)式語言,并且缺乏適當?shù)念愋屯茢唷cala中的類型系統(tǒng)不如其他函數(shù)式語言那么好。

從好的方面來說,Scala支持更高種類的類型和類型類。

盡管存在缺點,但類型系統(tǒng)仍然非常好,因此表示贊許。

(3) 簡潔/可讀

盡管Scala代碼非常簡潔,尤其是與Java相比,但代碼可讀性不強。

Scala是實際上屬于C語言編程語言家族的幾種函數(shù)式語言之一。C系列語言旨在與命令式編程一起使用,而ML系列語言旨在與功能性編程一起使用。因此,在Scala中使用類似C語法的函數(shù)式編程有時會感到很奇怪。

Scala中的代數(shù)數(shù)據(jù)類型沒有正確的語法,這會對可讀性產(chǎn)生不利影響

就可讀性而言,ML語言的ADT無疑是贏家。

(4) 速度

就編譯速度而言,Scala可能是最差的編程語言之一。一個簡單的" hello world"程序可能需要10秒鐘才能在較舊的硬件上進行編譯。Scala編譯器不是并發(fā)的(使用單個內(nèi)核編譯代碼),這不利于編譯速度。

Scala在Java虛擬機之上運行,這意味著程序?qū)⒒ㄙM更長的時間啟動。

(5) 學(xué)習(xí)曲線

Scala具有很多功能,這使得學(xué)習(xí)變得更加困難。就像C ++一樣,該語言具有許多功能。

Scala是最困難的函數(shù)式語言之一(僅次于Haskell)。實際上,它的易學(xué)性是離開Scala時公司的首要決定因素。

(6) 不變性

Scala對不可變數(shù)據(jù)結(jié)構(gòu)(使用案例類)具有一流的支持。

(7) 空值

不利的一面是,Scala支持空引用。從好的方面來看,使用潛在缺失值的慣用方式是使用選項模式(就像其他功能語言一樣)。

(8) 錯誤處理

就像其他功能語言一樣,Scala習(xí)慣將Result模式用于錯誤處理。

(9) 并發(fā)

Scala在JVM之上運行,而JVM并不是真正為并發(fā)而構(gòu)建的。從好的方面來說,Akka工具包非常成熟,并且在JVM上提供了類似于Erlang的并發(fā)。

(10) 模式匹配

Scala具有出色的模式匹配支持。

(11) 結(jié)論 3星

[[357260]]

我真的很想喜歡Scala,但我不能。Scala嘗試做太多事情。為了同時支持OOP和FP,其設(shè)計人員必須做出很多權(quán)衡。正如俄羅斯諺語所說的那樣:"追趕兩只兔子的人一只都抓不到"。

Elm

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

[[357264]]

Elm是一種功能強大的js編譯語言,主要用于前端Web開發(fā)。

Elm之所以與眾不同,是因為它承諾永遠不會出現(xiàn)運行時異常。用Elm編寫的應(yīng)用程序非常強大。

語言家族:ML。

(1) 非常好的錯誤消息

Elm編譯器提供了我見過的一些最好的錯誤消息,這使該語言甚至對于初學(xué)者來說也更加容易上手。

(2) 錯誤處理

Elm如何處理錯誤?就像許多其他功能語言一樣,使用Resultdata類型。

(3) 函數(shù)純度

就像Haskell一樣,Elm是一種純函數(shù)式語言。

Elm是通過消除所有運行時異常來提高生產(chǎn)率,還是通過在所有地方強制執(zhí)行功能純凈來使生產(chǎn)率降低?以我的經(jīng)驗,在Elm中進行任何重大的重構(gòu)都是一場噩夢,因為其中涉及大量的"管道"。

自己決定,但我會拒絕Elm的這一特性。

(4) 選項過于自以為是

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

> Quigglez on Reddit

Elm是一種自以為是的語言。到目前為止,使用制表符被視為語法錯誤。

Elm對"永遠不會出錯"的關(guān)注正在扼殺該語言。最新版本(0.19)引入了一項重大更改,這使得與JavaScript庫的互操作幾乎不可能。當然,這樣做的目的是讓人們在Elm中編寫自己的圖書館,以幫助生態(tài)系統(tǒng)發(fā)展。但是,很少有公司有資源來重新實現(xiàn)Elm中的所有功能。這使許多人永遠離開了Elm。

Elm的設(shè)計師似乎過于專注于函數(shù)純度,將"永無錯誤"的想法推向了極致。

(5) React沒有反應(yīng)

Elm利用自己的虛擬DOM,與ReasonML等語言不同,它不使用React。這意味著開發(fā)人員無法訪問為React制作的龐大的庫和組件生態(tài)系統(tǒng)。

(6) 語言發(fā)展

遺憾的是,距離Elm的新版本(0.19.1)已經(jīng)過去了一年多。開發(fā)流程的透明度為零,任何人都無法為開發(fā)做出貢獻。在每一個主要版本中,Elm都引入了重大更改,這使得某些語言無法使用。一年多來,我們從未真正聽到過其創(chuàng)建者的任何消息。我們甚至都不知道他是否仍在全職從事Elm。到現(xiàn)在,該語言可能實際上已經(jīng)消失了。

(7) 模式匹配

Elm有很好的模式匹配支持。

(8) 不變性

Elm對不可變數(shù)據(jù)結(jié)構(gòu)提供一流的支持。

(9) 空值

Elm不支持可為空的引用,就像其他函數(shù)式語言一樣,它使用Option模式。

(10) 結(jié)論 3.5星

[[357265]]

Elm是一門出色的語言。不幸的是,它似乎沒有未來。但這可能是進入函數(shù)式編程的好方法。

F#

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

[[357267]]

F#可以總結(jié)為.NET的OCaml。它的語法與OCaml非常相似,只是有一些細微的差別。F#于2005年首次出現(xiàn),是一種非常成熟的語言,具有出色的工具和豐富的生態(tài)系統(tǒng)。

語言家族:ML。

(1) 類型系統(tǒng)

類型系統(tǒng)的唯一缺點是缺少高級類型。類型系統(tǒng)仍然非常牢固,編譯器能夠推斷出幾乎所有內(nèi)容。F#對ADT具有適當?shù)闹С帧?/p>

(2) 功能性,但不純粹

與Haskell / Elm不同,F(xiàn)#非常實用,并且不強制執(zhí)行函數(shù)純度。

(3) 學(xué)習(xí)資源

F#有一些非常好的學(xué)習(xí)資源,可能與Elixir相當。

(4) 學(xué)習(xí)努力

F#是最容易使用的函數(shù)式語言之一。

(5) 生態(tài)

F#社區(qū)很小,與Elixir等語言不同,它根本沒有相同的強大庫。

(6) #C#互操作

從好的方面來說,F(xiàn)#可以訪問整個.NET / C#生態(tài)系統(tǒng)。與現(xiàn)有C#代碼互操作確實很好。

(7) 并發(fā)

F#在CLR之上運行,它沒有Elixir從Erlang VM中獲得的同樣出色的并發(fā)支持(稍后會詳細介紹)。

(8) 空值

F#代碼中通常不使用空值。它使用選項模式來表示可能不存在的值。

(9) 錯誤處理

慣用的F#代碼使用Result模式進行錯誤處理。

(10) 不變性

F#對不可變數(shù)據(jù)結(jié)構(gòu)具有一流的支持。

(11) 模式匹配

F#具有強大的模式匹配支持。

(12) 結(jié)論 4星

[[357267]]

F#是一種非??煽康木幊陶Z言,具有非常好的類型系統(tǒng)。對于Web API開發(fā),它幾乎與Elixir一樣好(稍后會詳細介紹)。但是,F(xiàn)#的問題不是它所擁有的,而是它所沒有的。為了與Elixir進行比較,其并發(fā)功能,豐富的生態(tài)系統(tǒng)和令人驚嘆的社區(qū)勝過F#提供的任何靜態(tài)鍵入好處。

· Dark的新后端將在F#中

(13) 獲獎情況

[[357268]]

F#獲得了兩個獎項。

F#獲得了Fintech最佳語言獎。財務(wù)是F#的最大應(yīng)用之一,這已經(jīng)不是什么秘密了。

F#還獲得了企業(yè)軟件最佳語言獎。其豐富的類型系統(tǒng)允許對復(fù)雜的業(yè)務(wù)邏輯進行建模。強烈建議您閱讀《領(lǐng)域建模使功能》一書。

ReasonML

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

[[357270]]

ReasonML是一種功能強大的js編譯語言,主要用于前端Web開發(fā)。

ReasonML不是一種新語言,它是OCaml(一種古老且嘗試過的編程語言)的新語法。ReasonML由Facebook支持。

通過利用JavaScript生態(tài)系統(tǒng),ReasonML不會遭受與OCaml相同的弊端。

語言家族:ML。

(1) 不是JavaScript的超集

ReasonML的語法與JavaScript相似,這使具有JavaScript經(jīng)驗的任何人都可以更容易地使用它。但是,與TypeScript不同,ReasonML甚至沒有嘗試成為JavaScript的超集(這是我們已經(jīng)學(xué)到的一件好事)。與TypeScript不同,ReasonML不必繼承數(shù)十年來JavaScript做出的錯誤設(shè)計決策。

(2) 學(xué)習(xí)曲線

由于ReasonML甚至沒有嘗試成為JavaScript的超集,因此它使該語言比JavaScript簡單得多。具備JavaScript函數(shù)編程經(jīng)驗的人可以在一周左右的時間內(nèi)使用ReasonML。

ReasonML確實是最簡單的編程語言之一。

(3) 函數(shù)式,但不純粹

與Elm不同,ReasonML甚至沒有嘗試成為純函數(shù)式語言,也沒有"永遠不會出現(xiàn)運行錯誤"的目標。這意味著ReasonML非常實用,專注于開發(fā)人員的生產(chǎn)力,并快速實現(xiàn)結(jié)果。

(4) 類型系統(tǒng)

ReasonML實際上是OCaml,這意味著它的類型系統(tǒng)幾乎與Haskell一樣好。最大的缺點是缺少類型類,但它支持仿函數(shù)(高階模塊)。

ReasonML是靜態(tài)類型的,其類型推斷幾乎與Haskell一樣好。

(5) 生態(tài)

就像TypeScript一樣,ReasonML可以訪問整個JavaScript生態(tài)系統(tǒng)。

(6) JavaScript / TypeScript互操作

ReasonML編譯為純JavaScript。因此,可以在同一項目中同時使用ReasonML和JavaScript / TypeScript。

(7) ReasonML和React –天生一對

如果您正在進行前端Web開發(fā),那么您很可能正在使用React。您知道嗎,React最初是用OCaml編寫的,然后才移植到JavaScript以幫助采用?

由于ReasonML是靜態(tài)類型的,因此無需擔心PropTypes。

還記得JavaScript一節(jié)中看起來很天真的示例,它可能導(dǎo)致性能下降嗎?

ReasonML對不可變數(shù)據(jù)結(jié)構(gòu)提供了適當?shù)闹С?,并且此類代碼不會產(chǎn)生性能問題:

與JavaScript不同,ReasonML無需重新渲染任何內(nèi)容,即開即用的出色React性能!

(8) 工具

ReasonML尚未像TypeScript這樣的替代品那么成熟,并且該工具可能存在一些問題。例如,官方建議的VSCode擴展原因語言服務(wù)器當前已損壞,但是存在其他替代方法。

ReasonML在后臺使用OCaml編譯器,而OCaml則以非常糟糕的編譯器錯誤消息而聞名。雖然不是交易破壞者,但這有點令人沮喪,并且會影響開發(fā)人員的生產(chǎn)率。

我希望隨著語言的成熟,工具也會有所改進。

(9) 空值

ReasonML沒有空引用,并且使用Option模式來表示可能不存在的值。

(10) 不變性

ReasonML對不可變數(shù)據(jù)結(jié)構(gòu)具有一流的支持。

(11) 模式匹配

ReasonML具有強大的模式匹配支持。

(12) 結(jié)論 4.5星

[[357270]]

ReasonML可能是TypeScript一直以來的目標,但是失敗了。ReasonML將靜態(tài)類型添加到JavaScript,同時刪除所有不良功能(并添加真正重要的現(xiàn)代功能)。

(13) 最佳前端語言獎

[[357271]]

最佳前端語言獎歸于ReasonML。毫無疑問,ReasonML是前端Web開發(fā)的最佳選擇。

Elixir

那些讓碼農(nóng)倍感痛苦的現(xiàn)代編程語言

[[357270]]

Elixir可能是世界上最受歡迎的函數(shù)式編程語言。就像ReasonML一樣,Elixir并不是真正的新語言。取而代之的是,Elixir建立在Erlang超過三十年的成功基礎(chǔ)上。

Elixir是Go的函數(shù)表親。與Go一樣,Elixir也是從頭開始設(shè)計的,用于并發(fā)以利用多個處理器內(nèi)核。

與其他一些功能語言不同,Elixir非常實用。它專注于獲得結(jié)果。在Elixir社區(qū)中,您不會找到長時間的學(xué)術(shù)討論。Elixir論壇上充滿了針對實際現(xiàn)實問題的解決方案,社區(qū)對初學(xué)者非常友好。

語言家族:ML。

(1) 生態(tài)

真正使Elixir發(fā)光的是其生態(tài)系統(tǒng)。在大多數(shù)其他語言中,有兩種語言,然后是生態(tài)系統(tǒng),這是兩個獨立的部分。在Elixir中,核心Elixir團隊正在開發(fā)生態(tài)系統(tǒng)中的核心框架。Elixir的創(chuàng)建者JoséValim還是Phoenix和Ecto(Elixir生態(tài)系統(tǒng)中的超酷庫)的主要貢獻者。

在大多數(shù)其他語言中,有多個不同的庫專注于同一任務(wù)-許多不同的Web服務(wù)器,許多不同的ORM等。在Elixir中,開發(fā)工作實際上集中在少數(shù)幾個核心庫上,這導(dǎo)致了出色的庫質(zhì)量。

Elixir庫的文檔非常好,有很多示例。與某些其他語言不同,標準庫的文檔也很好。

(2) Phoenix框架

Phoenix框架的口號是" Phoenix感覺不錯"。與其他語言的框架不同,Phoenix具有許多內(nèi)置功能。開箱即用,它支持WebSocket,路由,HTML模板語言,國際化,JSON編碼器/解碼器,無縫ORM集成(Ecto),會話,SPA工具包等。

Phoenix框架以其出色的性能而聞名,它能夠在一臺計算機上處理數(shù)百萬個同時連接。

(3) 全棧

Phoenix框架最近引入了LiveView,它允許在Elixir(認為單頁應(yīng)用程序)內(nèi)構(gòu)建豐富的實時Web界面。無需JavaScript,無需React!

LiveView甚至負責同步客戶端和服務(wù)器狀態(tài),這意味著我們不必擔心開發(fā)和維護REST / GraphQL API。

(4) 數(shù)據(jù)處理

對于許多與數(shù)據(jù)處理有關(guān)的任務(wù),Elixir可以替代Python。在Python和Elixir中都構(gòu)建了一個Web抓取工具之后,Elixir無疑是完成任務(wù)的更好的語言和生態(tài)系統(tǒng)。

諸如Broadway之類的工具允許在Elixir中構(gòu)建數(shù)據(jù)提取/數(shù)據(jù)處理管道。

(5) 類型系統(tǒng)

我認為,缺少適當?shù)撵o態(tài)類型是Elixir的最大缺點。雖然Elixir不是靜態(tài)類型的,但編譯器(以及透析器)將在編譯時報告很多錯誤。與動態(tài)類型的語言(例如JavaScript,Python和Clojure)相比,這有很長的路要走。

(6) 速度

Elixir編譯器是多線程的,可提供極快的編譯速度。與Java虛擬機不同,Erlang VM快速啟動。對于Elixir的用例,運行時性能非常好。

(7) 可靠性

Elixir建立在Erlang之上,Erlang被使用了30多年來構(gòu)建世界上最可靠的軟件。在Erlang VM上運行的某些程序已經(jīng)能夠?qū)崿F(xiàn)99.9999999%的可靠性。世界上沒有其他平臺可以擁有同等水平的可靠性。

(8) 并發(fā)

大多數(shù)其他編程語言尚未設(shè)計用于并發(fā)。這意味著編寫使用多個線程/處理器內(nèi)核的代碼絕非易事。其他編程語言使用執(zhí)行并行代碼(和共享內(nèi)存,線程從中讀取/寫入)的線程。這種方法通常容易出錯,容易出現(xiàn)死鎖,并導(dǎo)致復(fù)雜度成指數(shù)增長。

Elixir建立在以其出色的并發(fā)功能而聞名的Erlang之上,并采用了一種完全不同的并發(fā)方法,稱為actor模型。在此模型中,流程(參與者)之間沒有任何共享。每個進程都維護自己的內(nèi)部狀態(tài),并且各個進程之間進行通信的唯一方法是發(fā)送消息。

順便說一下,參與者模型實際上是其創(chuàng)建者Alan Kay最初打算使用的OOP,其中沒有任何共享,對象僅通過傳遞消息進行通信。

讓我們快速比較一下Elixir和它的命令表親Go。與Go不同,Elixir完全是為容錯而設(shè)計的。每當goroutine崩潰時,整個Go程序都會關(guān)閉。在Elixir中,每當一個進程死亡時,只有那個單個進程死亡,而不會影響程序的其余部分。更好的是,失敗的進程將由其主管自動重啟。這允許失敗的進程重試失敗的操作。

Elixir的流程也非常輕巧,可以在一臺機器上輕松運行數(shù)十萬個流程。

(9) 縮放

讓我們再與Go進行比較。Go和Elixir中的并發(fā)利用并發(fā)進程之間的消息傳遞。由于Go可以編譯為本地代碼,因此Go程序?qū)⒃诘谝慌_計算機上運行得更快。

但是,一旦您開始擴展到第一臺機器之外,Go程序就會開始丟失。為什么?因為Elixir是從頭開始設(shè)計的,因此可以在多臺機器上運行。當涉及到分發(fā)和擴展時,Elixir在其之上運行的Erlang VM確實令人眼前一亮。它無縫地處理了許多繁瑣的事情,例如集群,RPC功能和網(wǎng)絡(luò)。

從某種意義上說,Erlang VM在微服務(wù)成為現(xiàn)實之前就已經(jīng)在進行微服務(wù)了。每個進程都可以視為微服務(wù)-就像微服務(wù)一樣,進程彼此獨立。通過語言內(nèi)置的通信機制,進程可以跨多臺機器運行的情況并不少見。

沒有Kubernetes復(fù)雜性的微服務(wù)?檢查一下這就是Elixir真正設(shè)計的目的。

(10) 錯誤處理

Elixir采用非常獨特的方法來處理錯誤。盡管純函數(shù)式語言(Haskell / Elm)旨在最大程度地減少錯誤發(fā)生的可能性,但Elixir認為錯誤不可避免地會發(fā)生。

在Elixir中,拋出異常很好,而通常不建議捕獲異常。相反,流程主管將自動重新啟動失敗的流程,以保持程序運行。

(11) 學(xué)習(xí)曲線

Elixir是一種簡單的語言,人們可以在大約一兩個月后拿起Elixir。使學(xué)習(xí)變得有些困難的是OTP。

OTP是Elixir的"殺手feature"。OTP是Elixir構(gòu)建的Erlang的一組工具和庫。正是"秘密調(diào)味料"極大地簡化了構(gòu)建并發(fā)和分布式程序的過程。

盡管Elixir本身很簡單,但將頭纏在OTP上可能要花費一些時間,但這確實對我有用。

(12) 學(xué)習(xí)資源

作為最受歡迎的函數(shù)式編程語言,Elixir具有豐富的學(xué)習(xí)資源。關(guān)于實用程序程序員,有許多驚人的Elixir書。學(xué)習(xí)資源幾乎總是對初學(xué)者非常友好。

(13) 模式匹配

Elixir具有出色的模式匹配支持。

(14) numbers運算數(shù)字

Elixir無法很好地處理計算密集型任務(wù)。對于此類任務(wù),應(yīng)選擇本機編譯語言(Go / Rust是不錯的選擇)。

(15) 好吧,和Erlang有什么關(guān)系?

出于所有意圖和目的,Elixir和Erlang完全相同。Erlang是一種功能強大的語言,具有奇怪的語法。Elixir可以被認為是Erlang的一種更好,更現(xiàn)代的語法(以及非常好的生態(tài)系統(tǒng)和社區(qū))。

(16) 結(jié)論 4.5星

[[357270]]

Elixir可能是所有函數(shù)式語言中最成熟的。它還在用于功能編程的虛擬機之上運行。它是專為并發(fā)而設(shè)計的,非常適合現(xiàn)代多核處理器時代。

(17) 獲獎情況

[[357273]]

Elixir獲得兩個獎項。

它的彈性,函數(shù)至上的方法和令人驚嘆的生態(tài)系統(tǒng)使其成為構(gòu)建Web API的最佳語言。

OTP和參與者模型使Elixir成為構(gòu)建并發(fā)和分布式軟件的最佳語言。與命令式表弟Go不同,用Elixir編寫的軟件可以水平擴展到數(shù)千臺服務(wù)器,并且具有開箱即用的容錯能力。

為什么不使用正確的工具進行工作?

[[357274]]

> Photo by Haupes Co. on Unsplash

你會用螺絲刀打釘嗎?可能不會。然后,我們可能不應(yīng)該嘗試對所有內(nèi)容都使用一種編程語言,每種語言都有自己的位置。

Go是用于系統(tǒng)編程的最佳語言。前端開發(fā)的最佳選擇無疑是ReasonML,它滿足了出色編程語言的大多數(shù)要求。Web API開發(fā)的絕對贏家是Elixir,它的唯一缺點是缺少靜態(tài)類型系統(tǒng)(它被強大的生態(tài)系統(tǒng),社區(qū),可靠性和并發(fā)功能所抵消)。對于任何種類的并發(fā)/分布式軟件,最好的選擇還是Elixir。

如果你正在從事數(shù)據(jù)科學(xué)工作,那么不幸的是,唯一合理的選擇是Python。

我真的希望這篇文章有用。比較編程語言絕非易事,但我已盡力而為。

 

責任編輯:趙寧寧 來源: 今日頭條
相關(guān)推薦

2020-12-18 07:41:01

碼農(nóng)編程語言

2014-02-27 09:55:03

2020-05-25 14:17:49

碼農(nóng)編程語言GitHub

2020-02-01 15:54:45

程序員人生第一份工作播客

2019-04-19 09:09:51

2022-11-30 14:57:39

產(chǎn)業(yè)互聯(lián)網(wǎng)

2014-04-04 10:27:50

碼農(nóng)工作效率

2020-03-10 17:50:21

編程技巧編程語言

2020-08-05 12:27:18

Go語言碼農(nóng)

2015-03-30 11:21:27

編程編程反思

2020-02-28 10:51:17

編程代碼開發(fā)

2013-11-14 13:58:06

硅谷碼農(nóng)

2015-05-12 10:15:15

程序員

2020-09-30 11:14:24

AI碼農(nóng)架構(gòu)

2023-07-16 22:34:55

2023-12-15 14:38:00

GoRust編程語言

2017-03-15 13:41:16

數(shù)據(jù)庫SQL調(diào)試

2021-12-23 23:11:37

C語言編程工具

2014-05-23 10:25:48

Clojure

2013-10-17 10:13:30

碼農(nóng)程序員
點贊
收藏

51CTO技術(shù)棧公眾號