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

面向?qū)ο缶幊淌怯嬎銠C科學(xué)的最大錯誤

開發(fā) 前端
C++和Java可能是計算機科學(xué)中最嚴(yán)重的錯誤。兩者都受到了OOP創(chuàng)始人Alan Kay本人以及其他許多著名計算機科學(xué)家的嚴(yán)厲批評。然而,C++和Java為最臭名昭著的編程范式--現(xiàn)代OOP鋪平了道路。

 [[385709]]

C++和Java可能是計算機科學(xué)中最嚴(yán)重的錯誤。兩者都受到了OOP創(chuàng)始人Alan Kay本人以及其他許多著名計算機科學(xué)家的嚴(yán)厲批評。然而,C++和Java為最臭名昭著的編程范式--現(xiàn)代OOP鋪平了道路。

它的普及是非常不幸的,它對現(xiàn)代經(jīng)濟造成了極大的破壞,造成了數(shù)萬億美元至數(shù)萬億美元的間接損失。成千上萬人的生命因OOP而喪失。在過去的三十年里,沒有一個行業(yè)不受潛伏的OO危機的影響,它就在我們眼前展開。

為什么OOP如此危險?讓我們找出答案。

想象一下,在一個美麗的周日下午,帶著家人出去兜風(fēng)。外面的天氣很好,陽光明媚。你們所有人都進入車內(nèi),走的是已經(jīng)開過一百萬次的同一條高速公路。

 

 

 

[[385710]]

 

然而這次卻有些不一樣了--車子一直不受控制地加速,即使你松開油門踏板也是如此。剎車也不靈了,似乎失去了動力。為了挽救局面,你鋌而走險,拉起了緊急剎車。這樣一來,在你的車撞上路邊的路堤之前,就在路上留下了一個150英尺長的滑痕。

聽起來像一場噩夢?然而這正是2007年9月讓-布克特在駕駛豐田凱美瑞時發(fā)生的事情。這并不是唯一的此類事件。這是眾多與所謂的“意外加速”有關(guān)的事件之一。“意外加速”已困擾豐田汽車十多年,造成近百人死亡。汽車制造商很快就將矛頭指向了“粘性踏板”、駕駛員失誤,甚至地板墊等方面。然而,一些專家早就懷疑可能是有問題的軟件在作怪。

為了幫助解決這個問題,請來了美國宇航局的軟件專家,結(jié)果一無所獲。直到幾年后,在調(diào)查Bookout事件的過程中,另一個軟件專家團隊才找到了真兇。他們花了近18個月的時間來研究豐田的代碼,他們將豐田的代碼庫描述為“意大利面條代碼”——程序員的行話,意思是混亂的代碼。

軟件專家已經(jīng)演示了超過1000萬種豐田軟件導(dǎo)致意外加速的方法。最終,豐田被迫召回了900多萬輛汽車,并支付了超過30億美元的和解費和罰款。

意大利面條代碼有問題嗎?

 

 

[[385711]]

 

Photo by Andrea Piacquadio from Pexels

某些軟件故障造成的100條生命是太多了,真正令人恐懼的是,豐田代碼的問題不是唯一的。

兩架波音737 Max飛機墜毀,造成346人死亡,損失超過600億美元。這一切都是因為一個軟件bug, 100%肯定是意大利面條式代碼造成的。

意大利面條式的代碼困擾著世界上太多的代碼庫。飛機上的電腦,醫(yī)療設(shè)備,核電站運行的代碼。

程序代碼不是為機器編寫的,而是為人類編寫的。正如馬丁·福勒(Martin Fowler)所說:“任何傻瓜都可以編寫計算機可以理解的代碼。好的程序員編寫人類可以理解的代碼。”

如果代碼不能運行,那么它就是壞的。然而如果人們不能理解代碼,那么它就會被破壞。很快就會。

我們繞個彎子,說說人腦。人腦是世界上最強大的機器。然而,它也有自己的局限性。我們的工作記憶是有限的,人腦一次只能思考5件事情。這就意味著,程序代碼的編寫要以不壓垮人腦為前提。

意大利面條代碼使人腦無法理解代碼庫。這具有深遠(yuǎn)的影響--不可能看到某些改變是否會破壞其他東西,對缺陷的詳盡測試變得不可能。

是什么導(dǎo)致意大利面條代碼?

 

 

[[385712]]

 

Photo by Craig Adderley from Pexels

為什么代碼會隨著時間的推移變成意大利面條代碼?因為熵--宇宙中的一切最終都會變得無序、混亂。就像電纜最終會變得糾纏不清一樣,我們的代碼最終也會變得糾纏不清。除非有足夠的約束條件。

為什么我們要在道路上限速?是的,有些人總會討厭它們,但它們可以防止我們撞死人。為什么我們要在馬路上設(shè)置標(biāo)線?為了防止人們走錯路,防止事故的發(fā)生。

類似的方法在編程時完全有意義。這樣的約束不應(yīng)該讓人類程序員去實施。它們應(yīng)該由工具自動執(zhí)行,或者最好由編程范式本身執(zhí)行。

為什么OOP是萬惡之源?

 

 

[[385713]]

 

Photo by NeONBRAND on Unsplash

我們?nèi)绾螆?zhí)行足夠的約束以防止代碼變成意大利面條?兩個選擇--手動,或者自動。手動方式容易出錯,人總會出錯。因此,自動執(zhí)行這種約束是符合邏輯的。

不幸的是,OOP并不是我們一直在尋找的解決方案。它沒有提供任何約束來幫助解決代碼糾纏的問題。人們可以精通各種OOP的最佳實踐,比如依賴注入、測試驅(qū)動開發(fā)、領(lǐng)域驅(qū)動設(shè)計等(確實有幫助)。然而,這些都不是編程范式本身所能強制執(zhí)行的(而且也沒有這樣的工具可以強制執(zhí)行最佳實踐)。

內(nèi)置的OOP功能都無助于防止意大利面條代碼——封裝只是將狀態(tài)隱藏并分散在程序中,這只會讓事情變得更糟。繼承性增加了更多的混亂,OOP多態(tài)性再次讓事情變得更加混亂——在運行時不知道程序到底要走什么執(zhí)行路徑是沒有好處的,尤其是涉及到多級繼承的時候。

OOP進一步加劇了意大利面條代碼的問題

缺乏適當(dāng)?shù)募s束(以防止代碼變得混亂)不是OOP的唯一缺點。

在大多數(shù)面向?qū)ο蟮恼Z言中,默認(rèn)情況下所有內(nèi)容都是通過引用共享的。實際上把一個程序變成了一個巨大的全局狀態(tài)的blob,這與OOP的初衷直接沖突。OOP的創(chuàng)造者Alan Kay有生物學(xué)的背景,他有一個想法,就是想用一種類似生物細(xì)胞的方式來編寫計算機程序的語言(Simula),他想讓獨立的程序(細(xì)胞)通過互相發(fā)送消息來進行交流。獨立程序的狀態(tài)絕不會與外界共享(封裝)。

Alan Kay從未打算讓“細(xì)胞”直接進入其他細(xì)胞的內(nèi)部進行改變。然而,這正是現(xiàn)代OOP中所發(fā)生的事情,因為在現(xiàn)代OOP中,默認(rèn)情況下,所有東西都是通過引用來共享的。這也意味著,回歸變得不可避免。改變程序的一個部分往往會破壞其他地方的東西(這在其他編程范式,如函數(shù)式編程中就不那么常見了)。

我們可以清楚地看到,現(xiàn)代OOP存在著根本性的缺陷。它是每天工作中會折磨你的“怪物”,而且它還會在晚上纏著你。

讓我們來談?wù)効深A(yù)測性

 

 

[[385714]]

 

Photo by samsommer on Unsplash

意大利面代碼是個大問題,面向?qū)ο蟮拇a特別容易意大利化。

意大利面條代碼使軟件無法維護,然而這只是問題的一部分。我們也希望軟件是可靠的。但這還不夠,軟件(或任何其他系統(tǒng))被期望是可預(yù)測的。

任何系統(tǒng)的用戶無論如何都應(yīng)該有同樣的可預(yù)測的體驗。踩汽車油門踏板的結(jié)果總是汽車加速。按下剎車應(yīng)該總是導(dǎo)致汽車減速。用計算機科學(xué)的行話來說,我們希望汽車是確定性的。

汽車出現(xiàn)隨機行為是非常不可取的,比如油門無法加速,或者剎車無法制動(豐田問題),即使這樣的問題在萬億次中只出現(xiàn)一次。

然而大多數(shù)軟件工程師的心態(tài)是“軟件應(yīng)該足夠好,讓我們的客戶繼續(xù)使用”。我們真的不能做得更好嗎?當(dāng)然,我們可以,而且我們應(yīng)該做得更好!最好的開始是解決我們方案的非確定性。

非確定性101

 

 

[[385715]]

 

在計算機科學(xué)中,非確定性算法是相對于確定性算法而言的,即使對于相同的輸入,也可以在不同的運行中表現(xiàn)出不同的行為。

——維基百科關(guān)于非確定性算法的文章

如果上面維基百科上關(guān)于非確定性的引用你聽起來不順耳,那是因為非確定性沒有任何好處。我們來看看一個簡單調(diào)用函數(shù)的代碼樣本。

 

  1. console.log( 'result', computea(2) ); 
  2. console.log( 'result', computea(2) ); 
  3. console.log( 'result', computea(2) ); 
  4.  
  5. // output
  6. // result 4 
  7. // result 4 
  8. // result 4 

我們不知道這個函數(shù)的作用,但似乎在給定相同輸入的情況下,這個函數(shù)總是返回相同的輸出。現(xiàn)在,讓我們看一下另一個示例,該示例調(diào)用另一個函數(shù) computeb:

 

  1. console.log( 'result', computeb(2) ); 
  2. console.log( 'result', computeb(2) ); 
  3. console.log( 'result', computeb(2) ); 
  4. console.log( 'result', computeb(2) ); 
  5.  
  6. // output
  7. // result 4 
  8. // result 4 
  9. // result 4 
  10. // result 2    <=  not good 

這次,函數(shù)為相同的輸入返回了不同的值。兩者之間有什么區(qū)別?前者的函數(shù)總是在給定相同的輸入的情況下產(chǎn)生相同的輸出,就像數(shù)學(xué)中的函數(shù)一樣。換句話說,函數(shù)是確定性的。后一個函數(shù)可能會產(chǎn)生預(yù)期值,但這是不保證的?;蛘邠Q句話說,這個函數(shù)是不確定的。

是什么使函數(shù)具有確定性或不確定性?

  • 不依賴外部狀態(tài)的函數(shù)是100%確定性的。
  • 僅調(diào)用其他確定性函數(shù)的函數(shù)是確定性的。

 

  1. function computea(x) { 
  2.   return x * x; 
  3.  
  4. function computeb(x) { 
  5.   returnMath.random() < 0.9 
  6.           ? x * x 
  7.           : x; 

在上面的例子中,computea 是確定性的,在給定相同輸入的情況下,它總是會給出相同的輸出。因為它的輸出只取決于它的參數(shù) x 。

另一方面,computeb 是非確定性的,因為它調(diào)用了另一個非確定性函數(shù) Math.random()。我們怎么知道Math.random()是非確定性的?在內(nèi)部,它依賴于系統(tǒng)時間(外部狀態(tài))來計算隨機值。它也不接受任何參數(shù)--這是一個依賴于外部狀態(tài)的函數(shù)的致命漏洞。

確定性與可預(yù)測性有什么關(guān)系?確定性的代碼是可預(yù)測的代碼,非確定性代碼是不可預(yù)測的代碼。

從確定性到非確定性

我們來看看一個加法函數(shù):

 

  1. function add(a, b) { 
  2.   return a + b; 
  3. }; 

我們始終可以確定,給定 (2, 2) 的輸入,結(jié)果將始終等于 4。我們怎么能這么肯定呢?在大多數(shù)編程語言中,加法運算都是在硬件上實現(xiàn)的,換句話說,CPU負(fù)責(zé)計算的結(jié)果要始終保持不變。除非我們處理的是浮點數(shù)的比較,(但這是另一回事,與非確定性問題無關(guān))?,F(xiàn)在,讓我們把重點放在整數(shù)上。硬件是非??煽康模梢钥隙ǖ氖?,加法的結(jié)果永遠(yuǎn)是正確的。

現(xiàn)在,讓我們將值 2 裝箱:

 

  1. const box = value => ({ value }); 
  2.  
  3. const two = box(2); 
  4. const twoPrime = box(2); 
  5.  
  6. function add(a, b) { 
  7.   return a.value + b.value; 
  8.  
  9. console.log("2 + 2' == " + add(two, twoPrime)); 
  10. console.log("2 + 2' == " + add(two, twoPrime)); 
  11. console.log("2 + 2' == " + add(two, twoPrime)); 
  12.  
  13. // output
  14. // 2 + 2' == 4 
  15. // 2 + 2' == 4 
  16. // 2 + 2' == 4 

到目前為止,函數(shù)是確定性的!

現(xiàn)在,我們對函數(shù)的主體進行一些小的更改:

 

  1. function add(a, b) { 
  2.   a.value += b.value; 
  3.   return a.value; 
  4.  
  5. console.log("2 + 2' == " + add(two, twoPrime)); 
  6. console.log("2 + 2' == " + add(two, twoPrime)); 
  7. console.log("2 + 2' == " + add(two, twoPrime)); 
  8.  
  9. // output
  10. // 2 + 2' == 4 
  11. // 2 + 2' == 6 
  12. // 2 + 2' == 8 

怎么了?突然間,函數(shù)的結(jié)果不再是可預(yù)測的了!它第一次工作正常,但在隨后的每次運行中,它的結(jié)果開始變得越來越不可預(yù)測。它第一次運行得很好,但在隨后的每一次運行中,它的結(jié)果開始變得越來越不可預(yù)測。換句話說,這個函數(shù)不再是確定性的。

為什么它突然變得不確定了?該函數(shù)修改了其范圍外的值,引起了副作用。

讓我們回顧一下

確定性程序可確保 2 + 2 == 4,換句話說,給定輸入 (2, 2),函數(shù) add 始終應(yīng)得到 4 的輸出。不管你調(diào)用函數(shù)多少次,不管你是否并行調(diào)用函數(shù),也不管函數(shù)外的世界是什么樣子。

非確定性程序正好相反,在大多數(shù)情況下,調(diào)用 add(2, 2) 將返回 4 。但偶爾,函數(shù)可能會返回3、5,甚至1004。在程序中,非確定性是非常不可取的,希望你現(xiàn)在能明白為什么。

非確定性代碼的后果是什么?軟件缺陷,也就是通常所說的 “bug”。錯誤使開發(fā)人員浪費了寶貴的調(diào)試時間,如果他們進入生產(chǎn)領(lǐng)域,會大大降低客戶體驗。

為了使我們的程序更可靠,我們應(yīng)該首先解決非確定性問題。

副作用

 

 

[[385716]]

 

Photo by Igor Yemelianov on Unsplash

這給我們帶來了副作用的問題。

什么是副作用?如果你正在服用治療頭痛的藥物,但這種藥物讓你惡心,那么惡心就是一種副作用。簡單來說,就是一些不理想的東西。

想象一下,你已經(jīng)購買了一個計算器,你把它帶回家,開始使用,然后突然發(fā)現(xiàn)這不是一個簡單的計算器。你給自己弄了個扭曲的計算器!您輸入 10 * 11,它將輸出 110,但它同時還向您大喊一百和十。這是副作用。接下來,輸入 41+1,它會打印42,并注釋“42,生命的意義”。還有副作用!你很困惑,然后開始和你的另一半說你想要點披薩。計算器聽到了對話,大聲說“ok”,然后點了一份披薩。還有副作用!

讓我們回到加法函數(shù):

 

  1. function add(a, b) { 
  2.   a.value += b.value; 
  3.   return a.value; 

是的,該函數(shù)執(zhí)行了預(yù)期的操作,將 a 添加到 b。然而,它也引入了一個副作用,調(diào)用 a.value += b.value 導(dǎo)致對象 a 發(fā)生變化。函數(shù)參數(shù) a 引用的是對象 2,因此是 2,value 不再等于 2。第一次調(diào)用后,其值變?yōu)?4,第二次調(diào)用后,其值為 6,依此類推。

純度

在討論了確定性和副作用之后,我們準(zhǔn)備談?wù)劶兒瘮?shù),純函數(shù)是指既具有確定性,又沒有副作用的函數(shù)。

再一次,確定性意味著可預(yù)測--在給定相同輸入的情況下,函數(shù)總是返回相同的結(jié)果。而無副作用意味著該函數(shù)除了返回一個值之外,不會做任何其他事情,這樣的函數(shù)才是純粹的。

純函數(shù)有什么好處?正如我已經(jīng)說過的,它們是可以預(yù)測的。這使得它們非常容易測試,對純函數(shù)進行推理很容易——不像OOP,不需要記住整個應(yīng)用程序的狀態(tài)。您只需要關(guān)心正在處理的當(dāng)前函數(shù)。

純函數(shù)可以很容易地組合(因為它們不會改變其作用域之外的任何東西)。純函數(shù)非常適合并發(fā),因為函數(shù)之間不共享任何狀態(tài)。重構(gòu)純函數(shù)是一件非常有趣的事情——只需復(fù)制粘貼,不需要復(fù)雜的IDE工具。

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

面向?qū)ο缶幊痰募兌热绾?

為了舉例說明,我們來討論一下OOP的兩個功能:getter和setter。

getter的結(jié)果依賴于外部狀態(tài)——對象狀態(tài)。多次調(diào)用getter可能會導(dǎo)致不同的輸出,這取決于系統(tǒng)的狀態(tài)。這使得getter具有內(nèi)在的不確定性。

現(xiàn)在說說setter,Setters的目的是改變對象的狀態(tài),這使得它們本身就具有副作用。

這意味著OOP中的所有方法(也許除了靜態(tài)方法)要么是非確定性的,要么會引起副作用,兩者都不好。因此,面向?qū)ο蟮某绦蛟O(shè)計絕不是純粹的,它與純粹完全相反。

有一個銀彈

但是我們很少有人敢嘗試。

 

 

 

[[385717]]

 

Photo by Mohamed Nohassi on Unsplash

無知不是恥辱,而是不愿學(xué)習(xí)。

— Benjamin Franklin

在軟件失敗的陰霾世界中,仍有一線希望,那將會解決大部分問題,即使不是所有問題。一個真正的銀彈。但前提是你愿意學(xué)習(xí)和應(yīng)用——大多數(shù)人都不愿意。

銀彈的定義是什么?可以用來解決我們所有問題的東西。數(shù)學(xué)是靈丹妙藥嗎?如果說有什么區(qū)別的話,那就是它幾乎是一顆銀彈。

我們應(yīng)該感謝成千上萬的聰明的男人和女人,幾千年來他們辛勤工作,為我們提供數(shù)學(xué)。歐幾里得,畢達哥拉斯,阿基米德,艾薩克·牛頓,萊昂哈德·歐拉,阿朗佐·丘奇,還有很多很多其他人。

如果不確定性(即不可預(yù)測)的事物成為現(xiàn)代科學(xué)的支柱,你認(rèn)為我們的世界會走多遠(yuǎn)?可能不會太遠(yuǎn),我們會停留在中世紀(jì)。這在醫(yī)學(xué)界確實發(fā)生過——在過去,沒有嚴(yán)格的試驗來證實某種特定治療或藥物的療效。人們依靠醫(yī)生的意見來治療他們的健康問題(不幸的是,這在俄羅斯等國家仍然發(fā)生)。在過去,放血等無效的技術(shù)一直很流行。像砷這樣不安全的物質(zhì)被廣泛使用。

不幸的是,今天的軟件行業(yè)與過去的醫(yī)藥太相似了。它不是建立在堅實的基礎(chǔ)上。相反,現(xiàn)代軟件業(yè)大多是建立在一個薄弱的搖搖欲墜的基礎(chǔ)上,稱為面向?qū)ο蟮木幊?。如果人的生命直接依賴于軟件,OOP早就消失了,就像放血和其他不安全的做法一樣,被人遺忘了。

堅實的基礎(chǔ)

 

 

[[385718]]

 

Photo by Zoltan Tasi on Unsplash

有沒有其他選擇?在編程的世界里,我們能不能有像數(shù)學(xué)一樣可靠的東西?是的,可以!許多數(shù)學(xué)概念可以直接轉(zhuǎn)化為編程,并為所謂的函數(shù)式編程奠定基礎(chǔ)。

是什么讓它如此穩(wěn)健?它是基于數(shù)學(xué),特別是Lambda微積分。

來做個比較,現(xiàn)代的OOP是基于什么呢?是的,真正的艾倫·凱是基于生物細(xì)胞的。然而,現(xiàn)代的Java/C# OOP是基于一組荒謬的思想,如類、繼承和封裝,它沒有天才Alan Kay所發(fā)明的原始思想,剩下的只是一套創(chuàng)可貼,用來彌補其劣等思想的缺陷。

函數(shù)式編程呢?它的核心構(gòu)建塊是一個函數(shù),在大多數(shù)情況下是一個純函數(shù),純函數(shù)是確定性的,這使它們可預(yù)測,這意味著由純函數(shù)組成的程序?qū)⑹强深A(yù)測的。它們會永遠(yuǎn)沒有bug嗎?不,但是如果程序中有一個錯誤,它也是確定的——相同的輸入總是會出現(xiàn)相同的錯誤,這使得它更容易修復(fù)。

我怎么到這里了?

在過去,在過程/函數(shù)出現(xiàn)之前 goto 語句在編程語言中被廣泛使用。goto 語句只是允許程序在執(zhí)行期間跳轉(zhuǎn)到代碼的任何部分。這讓開發(fā)人員真的很難回答 “我是怎么執(zhí)行到這一步的?” 的問題。是的,這也造成了大量的BUG。

如今,一個非常類似的問題正在發(fā)生。只不過這次的難題是 “我怎么會變成這個樣子”,而不是 “我怎么會變成這個執(zhí)行點”。

OOP(以及一般的命令式編程)使得回答 “我是如何達到這個狀態(tài)的?” 這個問題變得很難。在OOP中,所有的東西都是通過引用傳遞的。這在技術(shù)上意味著,任何對象都可以被任何其他對象突變(OOP沒有任何限制來阻止這一點)。而且封裝也沒有任何幫助--調(diào)用一個方法來突變某個對象字段并不比直接突變它好。這意味著,程序很快就會變成一團亂七八糟的依賴關(guān)系,實際上使整個程序成為一個全局狀態(tài)的大塊頭。

有什么辦法可以讓我們不再問 “我怎么會變成這樣” 的問題?你可能已經(jīng)猜到了,函數(shù)式編程。

過去很多人都抵制停止使用 goto 的建議,就像今天很多人抵制函數(shù)式編程,和不可變狀態(tài)的理念一樣。

但是等等,意大利面條代碼呢?

在OOP中,它被認(rèn)為是 “優(yōu)先選擇組成而不是繼承” 的最佳實踐。從理論上講,這種最佳做法應(yīng)該對意大利面條代碼有所幫助。不幸的是,這只是一種 “最佳實踐”。面向?qū)ο蟮木幊谭妒奖旧聿]有為執(zhí)行這樣的最佳實踐設(shè)置任何約束。這取決于你團隊中的初級開發(fā)人員是否遵循這樣的最佳實踐,以及這些實踐是否在代碼審查中得到執(zhí)行(這并不總是發(fā)生)。

那函數(shù)式編程呢?在函數(shù)式編程中,函數(shù)式組成(和分解)是構(gòu)建程序的唯一方法。這意味著,編程范式本身就強制執(zhí)行組成。這正是我們一直在尋找的東西!

函數(shù)調(diào)用其他函數(shù),大的函數(shù)總是由小的函數(shù)組成,就是這樣。與OOP中不同的是,函數(shù)式編程中的組成是自然的。此外,這使得像重構(gòu)這樣的過程變得極為簡單——只需簡單地剪切代碼,并將其粘貼到一個新的函數(shù)中。不需要管理復(fù)雜的對象依賴關(guān)系,不需要復(fù)雜的工具(如Resharper)。

可以清楚地看到,OOP對于代碼組織來說是一個較差的選擇。這是函數(shù)式編程的明顯勝利。

但是OOP和FP是相輔相成的!

抱歉讓您失望,它們不是互補的。

面向?qū)ο缶幊膛c函數(shù)式編程完全相反。說OOP和FP是互補的,可能就等于說放血和抗生素是互補的,是嗎?

OOP違反了許多基本的FP原則:

  • FP提倡純凈,而OOP提倡雜質(zhì)。
  • FP代碼基本上是確定性的,因此是可預(yù)測的。OOP代碼本質(zhì)上是不確定性的,因此是不可預(yù)測的。
  • 組合在FP中是自然的,在OOP中不是自然的。
  • OOP通常會導(dǎo)致錯誤百出的軟件和意大利面條式的代碼。FP產(chǎn)生了可靠、可預(yù)測和可維護的軟件。
  • 在FP中很少需要調(diào)試,而簡單的單元測試往往不需要調(diào)試。另一方面,OOP程序員生活在調(diào)試器中。
  • OOP程序員把大部分時間花在修復(fù)bug上。FP程序員把大部分時間花在交付結(jié)果上。

歸根結(jié)底,函數(shù)式編程是軟件世界的數(shù)學(xué)。如果數(shù)學(xué)已經(jīng)為現(xiàn)代科學(xué)打下了堅實的基礎(chǔ),那么它也可以以函數(shù)式編程的形式為我們的軟件打下堅實的基礎(chǔ)。

采取行動,為時已晚

OOP是一個非常大且代價高昂的錯誤,讓我們最終都承認(rèn)吧。

想到我坐的車運行著用OOP編寫的軟件,我就害怕。知道帶我和我的家人去度假的飛機使用面向?qū)ο蟮拇a并沒有讓我感到更安全。

現(xiàn)在是我們大家最終采取行動的時候了。我們都應(yīng)該從一小步開始,認(rèn)識到面向?qū)ο缶幊痰奈kU,并開始努力學(xué)習(xí)函數(shù)式編程。這不是一個快速的過程,至少需要十年的時間,我們大多數(shù)人才能實現(xiàn)轉(zhuǎn)變。我相信,在不久的將來,那些一直使用OOP的人將會被視為 “恐龍”,就像今天的COBOL程序員一樣,被淘汰。C ++和Java將會消亡, C#將死亡,TypeScript也將很快成為歷史。

我希望你今天就行動起來——如果你還沒有開始學(xué)習(xí)函數(shù)式編程,就開始學(xué)習(xí)吧。成為真正的好手,并傳播這個詞。F#、ReasonML和Elixir都是入門的好選擇。

巨大的軟件革命已經(jīng)開始。你們會加入,還是會被甩在后面?

責(zé)任編輯:華軒 來源: 前端全棧開發(fā)者
相關(guān)推薦

2021-01-15 11:37:28

面向?qū)ο缶幊?/a>計算機科學(xué)OOP

2013-01-09 09:27:09

面向?qū)ο?/a>計算機編程

2011-10-17 09:50:38

編程

2012-09-10 09:43:21

編程編程學(xué)習(xí)編程錯誤

2021-01-26 09:19:50

計算機數(shù)據(jù)中心故障IT服務(wù)

2019-04-30 15:14:11

數(shù)據(jù)科學(xué)家計算機

2019-09-10 12:58:03

電腦編程語言硬件

2010-07-21 16:10:25

計算機

2021-05-28 05:34:06

Golang語言編程

2013-01-10 10:05:29

編程面向?qū)ο缶幊?/a>

2023-01-10 09:38:09

面向對象系統(tǒng)

2023-07-07 10:53:08

2017-05-15 12:58:00

編程javaapl

2020-11-11 11:00:58

計算機程序員編程

2009-05-22 10:43:44

2017-04-21 09:07:39

JavaScript對象編程

2012-01-17 09:34:52

JavaScript

2019-04-30 09:45:12

計算機互聯(lián)網(wǎng) 技術(shù)

2010-11-17 11:31:22

Scala基礎(chǔ)面向?qū)ο?/a>Scala

2018-07-06 14:12:50

計算機薪酬錢景
點贊
收藏

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