精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

什么是函數(shù)式編程?使用函數(shù)式編程為什么會(huì)有幫助呢?

中科院半導(dǎo)體所 ? 來源:悅智網(wǎng) ? 2023-03-28 10:04 ? 次閱讀

你可能認(rèn)為軟件產(chǎn)品生命周期中耗時(shí)最長、費(fèi)用最高的階段是系統(tǒng)的初期開發(fā)階段,因?yàn)樗忻烂畹墓δ芏际窃谶@一階段構(gòu)想出來的。而事實(shí)上,最困難的部分是后期的維護(hù)階段。在這個(gè)階段,程序員將為自己在開發(fā)過程中走的捷徑付出代價(jià)。那么,程序員為什么要走捷徑?可能性有很多:也許他們沒有意識(shí)到自己在“投機(jī)取巧”;只有代碼被許多用戶部署并執(zhí)行時(shí),隱藏的漏洞才會(huì)暴露出來;開發(fā)人員時(shí)間緊,也可能導(dǎo)致缺陷;此外,產(chǎn)品上市時(shí)間的壓力幾乎肯定會(huì)讓軟件包含更多的錯(cuò)誤。

大多數(shù)公司維護(hù)代碼的難題導(dǎo)致了第二個(gè)問題:脆弱性。添加到代碼中的每個(gè)新功能都會(huì)增加代碼的復(fù)雜性,從而增加程序中斷的機(jī)會(huì)。軟件變得越來越復(fù)雜,開發(fā)人員因?yàn)楹ε鲁霈F(xiàn)程序中斷,如非絕對必要,都盡量避免改動(dòng)軟件,這是很普遍的現(xiàn)象。在許多公司中,整個(gè)開發(fā)團(tuán)隊(duì)的工作不是為了做任何新的開發(fā),而只是為了保持現(xiàn)有系統(tǒng)的運(yùn)行。你可能會(huì)說,這就像是軟件版本的紅皇后效應(yīng),奮力奔跑只是為了停在原地。

這種現(xiàn)狀令人遺憾。然而,軟件行業(yè)目前的發(fā)展趨勢就是復(fù)雜度越來越高、產(chǎn)品開發(fā)時(shí)間越來越長、運(yùn)行系統(tǒng)的脆弱性越來越高。公司一般只能投入更多人力來解決這些問題:更多的開發(fā)人員、更多的測試人員、更多的技術(shù)人員在發(fā)現(xiàn)系統(tǒng)漏洞時(shí)及時(shí)干預(yù)。

當(dāng)然,一定有更好的方法。越來越多的開發(fā)人員認(rèn)為這一問題的答案可能是函數(shù)式編程。本文中,我描述了什么是函數(shù)式編程,使用函數(shù)式編程為什么會(huì)有幫助,以及我為何如此熱衷于函數(shù)式編程。

為更好地理解函數(shù)式編程的基本原理,我們先回顧半個(gè)多世紀(jì)前發(fā)生的事情。20世紀(jì)60年代后期,為了提高代碼質(zhì)量,減少所需的開發(fā)時(shí)間,一種編程范式應(yīng)運(yùn)而生,稱為結(jié)構(gòu)化編程。

各種語言的出現(xiàn)促進(jìn)了結(jié)構(gòu)化編程的發(fā)展,為了更好地支持結(jié)構(gòu)化編程,一些已有的語言被修改。結(jié)構(gòu)化編程語言最顯著的特征之一,是消除了一個(gè)長期存在的特征:GOTO語句。

GOTO語句用于程序執(zhí)行的重新定向。程序流不是按順序執(zhí)行下一條語句,而是重定向至其他某個(gè)語句,即GOTO行中指定的語句,通常需滿足某些條件。

取消GOTO語句是基于程序員在使用GOTO的過程中學(xué)到的教訓(xùn)——它讓程序非常難以理解。帶有GOTO語句的程序通常被稱為“意大利面代碼”,因?yàn)橹噶钚蛄袌?zhí)行可能就像一碗意大利面,難以單鏈跟隨。

開發(fā)人員無法理解自己的代碼是如何工作的,或者為什么代碼有時(shí)不工作,這是一個(gè)復(fù)雜的問題。那個(gè)時(shí)代的軟件專家認(rèn)為,GOTO語句造成了不必要的復(fù)雜性,因此必須消除這些GOTO語句。

這在當(dāng)時(shí)是頗為激進(jìn)的想法,許多程序員拒絕消除自己一直依賴的語句。相關(guān)爭論持續(xù)了十多年,最終,GOTO不存在了,今天也沒人主張它再次回歸。這是因?yàn)樵诟呒壘幊陶Z言中消除GOTO語句大大降低了復(fù)雜度,提高了生產(chǎn)軟件的可靠性。這是通過對程序員的限制實(shí)現(xiàn)的,其結(jié)果是程序員更容易推理自己編寫的代碼。

盡管軟件行業(yè)已經(jīng)從現(xiàn)代高級語言中消除了GOTO語句,但軟件的復(fù)雜度和脆弱性仍在繼續(xù)上升。如果想看看還能修改哪些編程語言以避開一些常見的陷阱,你會(huì)很奇怪地發(fā)現(xiàn),軟件設(shè)計(jì)師往往能在硬件同行那里找到靈感。

在設(shè)計(jì)計(jì)算機(jī)硬件時(shí),電阻不能共用,比如鍵盤和顯示器電路就不能共用電阻。但程序員在軟件中卻一直在做這種共用,也就是全局狀態(tài)共享:變量不由某一個(gè)進(jìn)程所有,而可由任意數(shù)量的進(jìn)程進(jìn)行更改,甚至可以同時(shí)更改。

現(xiàn)在,想象一下,你每次使用微波爐時(shí),洗碗機(jī)的循環(huán)設(shè)置會(huì)從一般程序變?yōu)槠抗耷逑闯绦颉.?dāng)然,這在現(xiàn)實(shí)世界中并不會(huì)發(fā)生,但在軟件中,這樣的情況卻一直出現(xiàn)。程序員編寫調(diào)用一個(gè)函數(shù)的代碼,期望執(zhí)行單個(gè)任務(wù)。但是許多函數(shù)都有副作用,會(huì)改變共享的全局狀態(tài),從而導(dǎo)致意想不到的后果。

在硬件中,這種情況不會(huì)發(fā)生,因?yàn)槲锢矶上拗屏诉@種可能性。當(dāng)然,硬件工程師也可能會(huì)搞砸,但不像軟件那樣有太多的可能,且有好有壞。

另一個(gè)潛藏在軟件“沼澤”中的復(fù)雜怪物被稱為空引用,即引用內(nèi)存中某個(gè)位置根本不指向任何內(nèi)容。一旦嘗試使用此引用,就會(huì)出現(xiàn)錯(cuò)誤。因此,程序員必須牢記,在嘗試讀取或更改引用的內(nèi)容前,需檢查該引用是否為空。

當(dāng)今幾乎所有流行的語言都存在這一缺陷。先驅(qū)計(jì)算機(jī)科學(xué)家托尼?霍爾(Tony Hoare)早在1965年就在ALGOL語言中引入了空引用,空引用后來被納入許多其他語言。霍爾解釋說,自己這樣做“僅僅是因?yàn)樗苋菀讓?shí)施”,但今天他認(rèn)為這是一個(gè)“數(shù)十億美元的錯(cuò)誤”。因?yàn)楫?dāng)程序員期望的是有效引用而實(shí)際上是空引用時(shí),便會(huì)導(dǎo)致無數(shù)錯(cuò)誤。

軟件開發(fā)人員需要非常自律,才能避免此類陷阱,但有時(shí)他們沒有采取足夠的預(yù)防措施。結(jié)構(gòu)化編程的架構(gòu)師知道GOTO語句確實(shí)是陷阱,未給開發(fā)人員留下任何逃避的借口。為保證無GOTO語句的代碼獲得預(yù)期的清晰度改善,他們知道必須在結(jié)構(gòu)化編程語言中完全消除GOTO語句。

歷史證明,刪除危險(xiǎn)特征可大大提高代碼的質(zhì)量。今天,許多危險(xiǎn)的習(xí)慣做法損害了軟件的魯棒性和可維護(hù)性。幾乎所有現(xiàn)代編程語言均有某種形式的空引用、全局狀態(tài)共享和帶有副作用的函數(shù),這些要比GOTO語句糟糕得多。

如何消除這些缺陷?事實(shí)證明,答案已經(jīng)存在幾十年:純函數(shù)式編程語言。

第一個(gè)流行的純函數(shù)式語言稱為Haskell,創(chuàng)建于1990年。因此,軟件開發(fā)領(lǐng)域如今依舊面臨的棘手問題早在20世紀(jì)90年代中期便已有了解決方案。遺憾的是,當(dāng)時(shí)的硬件通常不夠強(qiáng)大,無法使用該解決方案。但今天的處理器已經(jīng)能夠輕松管理Haskell和其他純函數(shù)式語言的需求。

事實(shí)上,基于純函數(shù)的軟件特別適合現(xiàn)代多核CPU。這是因?yàn)榧兒瘮?shù)僅靠輸入參數(shù)運(yùn)行,因而不同函數(shù)間不可能存在交互。這使我們可以對編譯器進(jìn)行優(yōu)化,生成在多個(gè)內(nèi)核上高效、輕松運(yùn)行的代碼。

顧名思義,純函數(shù)式編程意味著開發(fā)人員只能編寫純函數(shù),既然是純函數(shù),便不會(huì)產(chǎn)生副作用。這種限制提高了穩(wěn)定性,打開了編譯器優(yōu)化的大門,最終生成的代碼更容易推理。

但若是函數(shù)需要知道或操作某個(gè)系統(tǒng)的狀態(tài),又該如何?這種情況下,狀態(tài)會(huì)由一長串“組合函數(shù)”進(jìn)行傳遞——一個(gè)函數(shù)將其輸出傳遞給下一個(gè)函數(shù)作為輸入。將狀態(tài)自一個(gè)函數(shù)傳遞至另一個(gè)函數(shù),每個(gè)函數(shù)都可以訪問該狀態(tài),且不會(huì)出現(xiàn)另一個(gè)并發(fā)程序線程對該狀態(tài)進(jìn)行修改——這是在太多程序中發(fā)現(xiàn)的常見且代價(jià)高昂的脆弱性。

函數(shù)式編程亦可解決霍爾的“十億美元錯(cuò)誤”:空引用。解決的方法是不允許值為空。另外,有一種結(jié)構(gòu)通常稱為Maybe(或某些語言中的Option)。Maybe的值可以是Nothing或Just。使用Maybe結(jié)構(gòu),開發(fā)人員不得不始終考慮這兩種情況。在這件事上他們別無選擇,每一次遇到Maybe時(shí)都必須處理Nothing的情況。這樣做可以消除空引用可能造成的許多錯(cuò)誤。

7d264e62-ccae-11ed-bfe3-dac502259ad0.jpg

函數(shù)式編程還要求數(shù)據(jù)不可變,這意味著一旦將變量設(shè)置為某個(gè)值,該值就永遠(yuǎn)不變。變量更像是數(shù)學(xué)中的變量。

例如,要計(jì)算方程y= x2+ 2x - 11,需要為x選擇一個(gè)值,并且在計(jì)算y的過程中,x都不會(huì)取不同的值。因此,計(jì)算x2時(shí)使用的x值與計(jì)算2 x時(shí)所用的x值是相同的。在大多數(shù)編程語言中沒有這樣的限制。可以使用一個(gè)值計(jì)算x2,然后在計(jì)算2 x之前更改x的值。不允許開發(fā)人員將賦值更改(變異),他們可以使用與中學(xué)代數(shù)課相同的推理過程。

與大多數(shù)語言不同,函數(shù)式編程語言深深植根于數(shù)學(xué)。這種邏輯極為嚴(yán)密的數(shù)學(xué)血統(tǒng)正是函數(shù)式語言最大的優(yōu)勢。

為何是這樣?因?yàn)槿藗冄芯繑?shù)學(xué)的歷史已有數(shù)千年之久。它牢不可破。而大多數(shù)編程范式(如面向?qū)ο蟮木幊蹋┍澈蟮臍v史最多只有60年,相比之下顯得粗糙且不成熟。

不妨通過一個(gè)例子來說明編程與數(shù)學(xué)相比有多“草率”。通常情況下,我們會(huì)告訴編程新手在第一次遇到語句x = x + 1時(shí)忘記自己在數(shù)學(xué)課上學(xué)的東西。在數(shù)學(xué)中,這個(gè)方程為零解。但在當(dāng)今的大多數(shù)編程語言中,x = x + 1不是一個(gè)等式。它是一個(gè)語句,命令計(jì)算機(jī)讀取x的值,將其加1后,放回名為x的變量中。

在函數(shù)式編程中,沒有語句,只有表達(dá)式。我們在用函數(shù)式語言編寫代碼時(shí)可以使用在中學(xué)學(xué)到的數(shù)學(xué)思維。

由于函數(shù)的純粹性,我們可以使用代數(shù)替換來推理代碼,從而幫助降低代碼復(fù)雜性,就像回到代數(shù)課上,降低方程復(fù)雜性一樣。在非函數(shù)式語言(命令式語言)中,則并無同等機(jī)制來推理代碼是如何工作的。

純函數(shù)式編程刪除了編程語言中的危險(xiǎn)特征,解決了我們行業(yè)中的許多大問題,開發(fā)人員也不容易出現(xiàn)“搬起石頭砸自己的腳”的問題。這些限制起初可能看來很極端,我可以肯定地說,20世紀(jì)60年代開發(fā)人員對消除GOTO也有相同感。但事實(shí)是,使用函數(shù)式語言既不失自由,功能又強(qiáng)大,以至于當(dāng)今幾乎所有最流行的語言都包含了函數(shù)功能,盡管它們本質(zhì)上仍然是命令式語言。

這種混和編程方法的最大問題在于它仍然允許開發(fā)人員忽略語言的函數(shù)性質(zhì)。如果50年前保留GOTO作為一個(gè)選項(xiàng),我們可能至今仍面臨著“意大利面代碼”的困境。

要獲得純函數(shù)式編程語言的全部好處,就不能妥協(xié)。需要使用從一開始就符合這些原則設(shè)計(jì)的語言。只有這樣,才能獲得本文闡述的許多益處。

7d684fce-ccae-11ed-bfe3-dac502259ad0.jpg

但函數(shù)式編程并非易事,要有所付出。學(xué)習(xí)使用此類函數(shù)范式編程幾乎就像從頭再學(xué)編程一樣。許多情況下,開發(fā)人員必須學(xué)習(xí)那些學(xué)校里不曾教過的數(shù)學(xué)知識(shí)。所需的數(shù)學(xué)并不難,但是新知識(shí),而且對于數(shù)學(xué)恐懼癥人群來說很可怕。

更重要的是,開發(fā)人員需要學(xué)習(xí)一種新的思維方式。因?yàn)椴皇煜ぃ鸪踹@會(huì)讓人感到有負(fù)擔(dān)。但隨著時(shí)間的推移,新的思維方式習(xí)慣成自然,與舊的思維方式相比,最終減少了認(rèn)知成本,效率也就會(huì)大幅提升。






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 處理器
    +關(guān)注

    關(guān)注

    68

    文章

    19170

    瀏覽量

    229178
  • 編程語言
    +關(guān)注

    關(guān)注

    10

    文章

    1939

    瀏覽量

    34604
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1618

    瀏覽量

    49055
  • 函數(shù)式編程
    +關(guān)注

    關(guān)注

    0

    文章

    11

    瀏覽量

    2061

原文標(biāo)題:函數(shù)式編程減少漏洞的新方法

文章出處:【微信號:bdtdsj,微信公眾號:中科院半導(dǎo)體所】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Golang函數(shù)編程簡述

    函數(shù)編程(Functional Programming / FP)作為一種編程范式,具有無狀態(tài)、無副作用、并發(fā)友好、抽象程度高等優(yōu)點(diǎn)。目前流行的
    發(fā)表于 08-09 12:32 ?478次閱讀

    前端開發(fā)之函數(shù)編程實(shí)踐

    函數(shù)編程是一種編程范式,它將程序抽象為函數(shù)和數(shù)據(jù)結(jié)構(gòu),通過函數(shù)調(diào)用來實(shí)現(xiàn)程序的功能,并且
    發(fā)表于 06-05 10:19 ?443次閱讀
    前端開發(fā)之<b class='flag-5'>函數(shù)</b><b class='flag-5'>式</b><b class='flag-5'>編程</b>實(shí)踐

    在Java中應(yīng)用函數(shù)編程請小心!

    a這并不是要對令人畏懼的函數(shù)編程進(jìn)行譴責(zé),而是對編程中很容易發(fā)生的一些錯(cuò)誤進(jìn)行警醒。高階函數(shù)函數(shù)
    發(fā)表于 01-13 15:39

    函數(shù)編程有什么優(yōu)勢

    為什么要函數(shù)編程
    發(fā)表于 04-22 08:44

    函數(shù)編程思維

    函數(shù)編程思維
    發(fā)表于 09-07 14:57 ?7次下載
    <b class='flag-5'>函數(shù)</b><b class='flag-5'>式</b><b class='flag-5'>編程</b>思維

    現(xiàn)代C函數(shù)編程

    導(dǎo)讀:本文作者從介紹函數(shù)編程的概念入手,分析了函數(shù)編程的表現(xiàn)形式和特性,最終通過現(xiàn)代C++的
    發(fā)表于 09-30 16:43 ?2次下載

    函數(shù)編程的基本特性

    本文簡單介紹了一下函數(shù)編程的各種基本特性,希望能夠?qū)τ跍?zhǔn)備使用函數(shù)編程的人起到一定入門作用。
    發(fā)表于 10-10 10:23 ?0次下載

    函數(shù)編程,性能,測試,編碼規(guī)范談Python

    個(gè)程序員能將這四個(gè)方面的內(nèi)容知識(shí)都吸收消化,那他/她不管怎樣都會(huì)有巨大的收獲。 函數(shù)編程 命令編程
    發(fā)表于 10-12 17:27 ?0次下載

    函數(shù)編程語言、編程和程序驗(yàn)證

    函數(shù)編程是一種編程范型,它把計(jì)算看作是對數(shù)學(xué)函數(shù)的求值,避免了狀態(tài)和易變數(shù)據(jù)結(jié)構(gòu),函數(shù)是構(gòu)造程
    發(fā)表于 04-03 11:01 ?3次下載

    正在使用的區(qū)塊鏈函數(shù)編程語言協(xié)議有哪些?

    在區(qū)塊鏈平臺(tái)開發(fā)中使用的一些最著名的編程語言是面向?qū)ο蟮恼Z言。到目前為止,像C++、Python和Ruby這樣的語言已經(jīng)主導(dǎo)了區(qū)塊鏈的發(fā)展場景。 如果最近的發(fā)展有什么可說的,那么非函數(shù)編程
    發(fā)表于 10-15 11:18 ?1430次閱讀

    為什么函數(shù)編程正在上升函數(shù)編程語言有哪些

    編程范例是一個(gè)術(shù)語,用于描述編寫命令的方法。 語言的真正思想是建立在其編程范例之上的。 最著名的三種范例是面向?qū)ο蟮某绦蛟O(shè)計(jì),命令程序設(shè)計(jì)和函數(shù)
    的頭像 發(fā)表于 02-24 15:06 ?3748次閱讀

    基于標(biāo)準(zhǔn)庫函數(shù)與基于HAL庫函數(shù)的stm32編程方式對比

    以實(shí)例程序(串口通信),分析基于標(biāo)準(zhǔn)庫函數(shù)與基于HAL庫函數(shù)的stm32編程方式的差異一、基于標(biāo)準(zhǔn)庫函數(shù)的stm32編程方式二、基于HAL庫
    發(fā)表于 12-28 19:09 ?30次下載
    基于標(biāo)準(zhǔn)庫<b class='flag-5'>函數(shù)</b>與基于HAL庫<b class='flag-5'>函數(shù)</b>的stm32<b class='flag-5'>編程</b>方式對比

    深入理解函數(shù)編程(上)

    函數(shù)編程是一種歷史悠久的編程范式。作為演算法,它的歷史可以追溯到現(xiàn)代計(jì)算機(jī)誕生之前的λ演算,本文希望帶大家快速了解函數(shù)
    的頭像 發(fā)表于 11-02 11:48 ?703次閱讀

    深入理解函數(shù)編程(下)

    函數(shù)編程是一種歷史悠久的編程范式。作為演算法,它的歷史可以追溯到現(xiàn)代計(jì)算機(jī)誕生之前的λ演算,本文希望帶大家快速了解函數(shù)
    的頭像 發(fā)表于 11-02 11:49 ?774次閱讀

    Python的函數(shù)編程介紹

    代碼的時(shí)候,拆成不同的函數(shù),可以大大的提高代碼易讀性。 函數(shù)編程 函數(shù)
    的頭像 發(fā)表于 09-27 16:54 ?1080次閱讀