函數(shù)式編程是未來(lái)的優(yōu)秀編碼范例嗎?
函數(shù)式編程已經(jīng)存在了六十年了,但是到目前為止,它并沒(méi)有停止克服面向?qū)ο缶幊痰钠毡槭褂谩? 隨著機(jī)器學(xué)習(xí)和大數(shù)據(jù)的爆炸性增長(zhǎng),由于可以并行化純函數(shù)的簡(jiǎn)單性,函數(shù)式編程正變得越來(lái)越流行。 數(shù)據(jù)分析任務(wù)和工作流的代碼也更易于遵循,測(cè)試和維護(hù),使用功能范式有助于日后的使用。
甚至像Java和Python這樣的面向?qū)ο蟮木幊陶Z(yǔ)言也從內(nèi)置于地圖,過(guò)濾器和簡(jiǎn)化功能的功能性編程中采用了巨大的概念。 它們還具有聲明純內(nèi)聯(lián)lambda函數(shù)以及創(chuàng)建一等和高階函數(shù)以將函數(shù)作為參數(shù)傳遞的功能。
簡(jiǎn)而言之,函數(shù)式編程需要為固定變量構(gòu)建純函數(shù)并通過(guò)其響應(yīng)更改狀態(tài)。 相反,其他編程語(yǔ)言具有通過(guò)更改程序中變量引用來(lái)更改應(yīng)用程序狀態(tài)的能力。 您可以在本文中了解功能編程與面向?qū)ο蟪绦虻母鄥^(qū)別。
由于其純粹的性質(zhì),函數(shù)式編程對(duì)于令人垂涎的任務(wù)(如機(jī)器學(xué)習(xí)和數(shù)據(jù)分析)印象深刻。 但是,這并不意味著您應(yīng)該放棄其他編程語(yǔ)言而完全發(fā)揮作用,因?yàn)槊糠N編程語(yǔ)言都具有比其他編程語(yǔ)言更好的任務(wù)。 但是,至關(guān)重要的是要學(xué)習(xí)基本原理,以便在必要時(shí)可以將其應(yīng)用于自己的利益。 出于這些原因,功能編程被稱(chēng)為未來(lái),但也許機(jī)器學(xué)習(xí)和大數(shù)據(jù)的未來(lái)才是軟件開(kāi)發(fā)的全部。
考慮到這一點(diǎn),讓我們看看為什么軟件開(kāi)發(fā)人員會(huì)愛(ài)上函數(shù)式編程,使它成為未來(lái)計(jì)算機(jī)科學(xué)的組成部分。 我們還考慮一下面向?qū)ο缶幊痰囊恍┕δ?,看看功能性編程是否可以完全替代它?劇透:兩者可能會(huì)在軟件開(kāi)發(fā)甚至同一應(yīng)用程序中共存。
純函數(shù)的使用
純函數(shù)會(huì)重復(fù)產(chǎn)生相同的結(jié)果,并且沒(méi)有影響最終結(jié)果的外部值。 由于純函數(shù)的這一特性,使用函數(shù)編程創(chuàng)建的算法可輕松識(shí)別和糾正錯(cuò)誤。
純函數(shù)通常采用數(shù)學(xué)求解方法。 例如,如果您在計(jì)算器中鍵入3 + 3,答案將為6。純函數(shù)也是如此。 不涉及外部元素,因此使功能程序純凈。 一個(gè)示例是內(nèi)聯(lián)lambda函數(shù),該函數(shù)將n作為輸入并返回n + n。
調(diào)試對(duì)于程序員和開(kāi)發(fā)人員都是一個(gè)長(zhǎng)期的問(wèn)題,這就是為什么他們轉(zhuǎn)向功能編程的原因,因?yàn)樗某绦蛴捎谑褂眉兒瘮?shù)而易于調(diào)試。
最佳透明度
> Photo by Pixabay on Pexels.com
純函數(shù)的使用使函數(shù)式編程完全透明。 函數(shù)式編程語(yǔ)言中純函數(shù)和不純函數(shù)之間的顯著區(qū)別極大地提高了這些程序?qū)崿F(xiàn)的透明性。
此外,純函數(shù)僅在不考慮外部元素的情況下工作。 這意味著他們僅處理用戶(hù)的條目。 相反,非功能性編程語(yǔ)言會(huì)導(dǎo)致額外的輸入和返回輸出,這些輸入和返回輸出與用戶(hù)的信息有些不同。
由于函數(shù)式編程不涉及任何外部元素,因此該算法不會(huì)偏離用戶(hù)的輸入。 因此,無(wú)論輸出如何,它都符合信息并且沒(méi)有任何危險(xiǎn)的方面。
提高可讀性
函數(shù)式編程提供了許多好處,包括提高了值的可讀性。 使用純值意味著它們的狀態(tài)一直保持到最后。 這些值還增強(qiáng)了程序的可讀性,這使開(kāi)發(fā)人員不必費(fèi)力即可掌握代碼。
由于絕大多數(shù)函數(shù)式編程語(yǔ)言都是高級(jí)語(yǔ)言,并且用戶(hù)將每個(gè)函數(shù)都視為一種價(jià)值,因此對(duì)于開(kāi)發(fā)人員而言,毫不費(fèi)力地調(diào)用該函數(shù)程序并將這些值最終合并到其他各種函數(shù)中即可。
靜態(tài)變量
用外行的語(yǔ)言來(lái)說(shuō),"變量"是不斷變化的狀態(tài)。 但是,這與功能編程相反。
在這里,程序員/開(kāi)發(fā)人員無(wú)法立即修改變量; 它已經(jīng)被煽動(dòng)。 人們可能會(huì)認(rèn)為,變量的恒定性與遞歸結(jié)合可能會(huì)導(dǎo)致性能下降。
但是,有必要理解此功能可確保程序直到最后都保持不變。 除了函數(shù)式編程通過(guò)使用純函數(shù)提供的寶貴保護(hù)外,這種方法還使函數(shù)式編程語(yǔ)言在安全性方面優(yōu)于同類(lèi)語(yǔ)言。
安全性是軟件開(kāi)發(fā)中的關(guān)鍵要素,促使開(kāi)發(fā)人員轉(zhuǎn)向功能編程以提高其系統(tǒng)安全性。
無(wú)縫并行編程
> Photo by Isaac Quesada on Pexels.com
通常認(rèn)為函數(shù)式編程具有開(kāi)發(fā)完整的并行程序的能力。 不可否認(rèn),開(kāi)發(fā)應(yīng)用程序是最容易被理解的使用方案之一,尤其是在采用功能性編程的開(kāi)發(fā)人員中。
其背后的主要因素是各種函數(shù)式編程語(yǔ)言中變量的靜態(tài)應(yīng)用。 由于純函數(shù)不會(huì)修改變量,而只能在用戶(hù)輸入上起作用,因此處理并行性變得不太復(fù)雜。
此外,考慮到程序的可靠性提高,大大減少了出錯(cuò)的余地,從而提高了程序的效率。
驗(yàn)證功能簽名
簽名驗(yàn)證是軟件開(kāi)發(fā)的關(guān)鍵方面。 與其他排除函數(shù)程序的方式相比,函數(shù)程序設(shè)計(jì)因其使函數(shù)簽名極其有效和值得的能力而受到高度評(píng)價(jià)。 函數(shù)式編程語(yǔ)言的純變量可確保簽名概述有關(guān)函數(shù)工作的所有信息以及其參數(shù)詳細(xì)信息和任何其他必要的詳細(xì)信息。
此外,這是功能編程成為軟件開(kāi)發(fā)的未來(lái)的另一個(gè)實(shí)際原因。
作為一種功能性編程語(yǔ)言,Scala允許開(kāi)發(fā)人員同時(shí)使用OOP和FP(功能性編程)編寫(xiě)代碼。 Scala主要致力于使用專(zhuān)有的純函數(shù)和恒定值編寫(xiě)軟件。 該語(yǔ)言正在逐漸發(fā)揮作用。
為什么函數(shù)式編程不會(huì)棄用面向?qū)ο蟮木幊?/strong>
> Photo by Christina Morillo on Pexels.com
面向?qū)ο缶幊?OOP)已成為軟件開(kāi)發(fā)的重要組成部分。 盡管引入了許多編程語(yǔ)言(例如C ++和Java),但是希望開(kāi)發(fā)移動(dòng)軟件的開(kāi)發(fā)人員必須掌握面向?qū)ο蟮姆椒ā? 考慮到OOP語(yǔ)言(例如PHP和Python)的流行,這同樣適用于復(fù)雜的Web開(kāi)發(fā)。
一些IT專(zhuān)業(yè)人員認(rèn)為面向?qū)ο蟮木幊桃堰^(guò)時(shí),因此掌握其概念完全是浪費(fèi)時(shí)間。 他們發(fā)現(xiàn)使用對(duì)象代替像Visual Basic這樣的語(yǔ)言中的傳統(tǒng)編程的自上而下的方法是不合邏輯的。
如果您已經(jīng)編寫(xiě)了此類(lèi)軟件的代碼,則可能習(xí)慣于將復(fù)雜的問(wèn)題分解為不太復(fù)雜的問(wèn)題,并以代碼為單位分別解決它們。 如果您對(duì)函數(shù)式編程有所了解,可以將代碼元素視為適當(dāng)?shù)臄?shù)學(xué)函數(shù),并禁止它們篡改其他方面,即,輸出反映了用戶(hù)的輸入。
盡管功能編程越來(lái)越流行,但是仍然使用面向?qū)ο蟮木幊獭?函數(shù)式編程未棄用OOP的一些原因包括:
1. 通過(guò)繼承重用代碼
假設(shè)一個(gè)人除了您的桌子對(duì)象還想要金屬桌子對(duì)象,而另一個(gè)人需要玻璃對(duì)象。 每個(gè)人都單獨(dú)構(gòu)建對(duì)象,但是卻意識(shí)到它們之間的相似之處。 每個(gè)對(duì)象只是一個(gè)不同類(lèi)型的表。 這就是繼承方法證明可以節(jié)省時(shí)間的地方。 在這里,您需要?jiǎng)?chuàng)建一個(gè)通用類(lèi)(表),然后定義子類(lèi)(金屬和玻璃)以采用通用玻璃功能。
當(dāng)然,金屬和玻璃桌具有其獨(dú)特的品質(zhì)和功能。 由于兩者之間存在相似之處,因此兩個(gè)繼承類(lèi)可以重用主流代碼,而不必再次編寫(xiě)這些函數(shù)。
例如,如果您想對(duì)所有表對(duì)象進(jìn)行更改,而不論其類(lèi)型如何,您所需要做的就是對(duì)表類(lèi)進(jìn)行調(diào)整,并且所有表對(duì)象都將采用新代碼。 這就是為什么某些開(kāi)發(fā)人員仍然更喜歡OOP而不是函數(shù)式編程的原因。
2. 多態(tài)性的靈活性
根據(jù)上面的示例,您不需要很多功能即可上手。 例如,金屬和玻璃物體具有某些共性,但每個(gè)物體都有其他獨(dú)特的特征。
3. 有效的問(wèn)題解決
像C這樣的編程語(yǔ)言在編程世界中享有良好的聲譽(yù),但是除非您對(duì)此感到滿(mǎn)意,否則強(qiáng)烈建議不要使用自上而下的語(yǔ)言開(kāi)發(fā)軟件。 這是因?yàn)橛捎趶?fù)雜性,項(xiàng)目崩潰的可能性更高。 另一方面,以功能編程語(yǔ)言(例如Haskell或ML)編寫(xiě)程序可以是常規(guī)的。
一旦開(kāi)始使用面向?qū)ο蟮木幊?,它通常是最自然,最明智的方法?OOP語(yǔ)言使開(kāi)發(fā)人員可以將您的軟件分為中等大小的問(wèn)題,這些問(wèn)題可以獨(dú)立解決。
4. 數(shù)據(jù)抽象
數(shù)據(jù)抽象不會(huì)向用戶(hù)顯示瑣碎的元素; 相反,它僅顯示基本細(xì)節(jié)。 例如,汽車(chē)被視為車(chē)輛,而不是其零件。
數(shù)據(jù)抽象被稱(chēng)為僅指出忽略無(wú)關(guān)細(xì)節(jié)的對(duì)象必不可少的特征的過(guò)程。 對(duì)象的功能和特性使它與其他具有相似性的對(duì)象區(qū)分開(kāi)來(lái),以幫助對(duì)對(duì)象進(jìn)行分類(lèi)/分組。
以某人操作計(jì)算機(jī)為例。 他只知道按下電源按鈕可以打開(kāi)/關(guān)閉計(jì)算機(jī)。 他或她不了解打開(kāi)和關(guān)閉PC電源的PC內(nèi)部機(jī)制。 這就是抽象的全部。
在OOP編程語(yǔ)言中,抽象是通過(guò)接口和抽象類(lèi)實(shí)現(xiàn)的。 通過(guò)使用接口可以實(shí)現(xiàn)100%的抽象。
結(jié)論
對(duì)于不可變的代碼和并發(fā)而言,功能性編程盡管比面向?qū)ο蟮木幊谈芮嗖A,但離OOP的使用還有很遠(yuǎn)的距離。 如上所述,只有通過(guò)面向?qū)ο蟮木幊滩拍軐?shí)現(xiàn)代碼的可重用性,數(shù)據(jù)抽象,有效的問(wèn)題解決以及多態(tài)性的靈活性。 在系統(tǒng)安全方面,功能性編程勝過(guò)面向?qū)ο蟮木幊?,因此功能性編程才是未?lái)。 尤其是隨著越來(lái)越多的大公司在其業(yè)務(wù)應(yīng)用程序中依賴(lài)機(jī)器學(xué)習(xí)和人工智能。 函數(shù)式編程在編寫(xiě)代碼以訓(xùn)練可在大型計(jì)算機(jī)主機(jī)網(wǎng)絡(luò)上進(jìn)行訓(xùn)練的ml模型方面尤其重要。