歷史
Lambda演算為描述函數(shù)及其評(píng)估提供了理論框架。它是一種數(shù)學(xué)抽象而不是編程語(yǔ)言 - 但它構(gòu)成了幾乎所有當(dāng)前函數(shù)式編程語(yǔ)言的基礎(chǔ)。等效的理論公式,組合邏輯,通常被認(rèn)為比lambda演算更抽象,并且在發(fā)明之前。組合邏輯和lambda演算最初都是為了更清晰地接近數(shù)學(xué)基礎(chǔ)而開發(fā)的。
一種早期功能性語(yǔ)言是Lisp,它是由John McCarthy在麻省理工學(xué)院(MIT)于20世紀(jì)50年代后期開發(fā)的IBM 700/7000系列科學(xué)計(jì)算機(jī)。 Lisp首先介紹了函數(shù)式編程的許多范式特性,盡管早期的Lisp是多范式語(yǔ)言,并且隨著新范式的發(fā)展,它包含了對(duì)眾多編程風(fēng)格的支持。后來(lái)的方言,如Scheme和Clojure,以及Dylan和Julia等分支,試圖簡(jiǎn)化和合理化Lisp圍繞一個(gè)干凈功能的核心,而Common Lisp旨在保存和更新它所取代的眾多舊方言的范式特征。
信息處理語(yǔ)言(IPL),1956,有時(shí)被認(rèn)為是第一種基于計(jì)算機(jī)的函數(shù)編程語(yǔ)言。[32]它是一種用于操縱符號(hào)列表的匯編式語(yǔ)言。它確實(shí)有一個(gè)生成器的概念,它相當(dāng)于一個(gè)接受函數(shù)作為參數(shù)的函數(shù),并且,由于它是一個(gè)匯編級(jí)語(yǔ)言,代碼可以是數(shù)據(jù),因此IPL可以被視為具有更高階函數(shù)。但是,它在很大程度上依賴于變異列表結(jié)構(gòu)和類似的命令性功能。
Kenneth E. Iverson在20世紀(jì)60年代早期開發(fā)了APL,在他1962年出版的“ A Programming Language”(ISBN 9780471430148)一書中有所描述。APL是約翰巴克斯的FP的主要影響力。在90年代初,艾弗森和羅杰·惠創(chuàng)建?。在20世紀(jì)90年代中期,以前曾與艾弗森合作過(guò)的亞瑟惠特尼創(chuàng)建了K,后者在金融行業(yè)中與其后代Q一起商業(yè)化使用。
約翰巴克斯在他的1977年圖靈獎(jiǎng)演講中展示了FP “可以從馮·諾依曼風(fēng)格中解放出來(lái)的程序設(shè)計(jì)功能風(fēng)格及其程序代數(shù)”。他將功能性程序定義為通過(guò)“組合形式”以分層方式構(gòu)建,允許“程序代數(shù)”; 在現(xiàn)代語(yǔ)言中,這意味著功能性程序遵循組合性原則。 Backus的論文推廣了函數(shù)式編程的研究,雖然它強(qiáng)調(diào)功能級(jí)編程而不是現(xiàn)在與函數(shù)式編程相關(guān)的lambda-calculus風(fēng)格。
1973年語(yǔ)言ML被創(chuàng)造羅賓·米爾納在愛丁堡大學(xué)和大衛(wèi)·特納開發(fā)的語(yǔ)言SASL在圣安德魯斯大學(xué)。同樣在20世紀(jì)70年代的愛丁堡,Burstall和Darlington開發(fā)了功能語(yǔ)言NPL。NPL基于Kleene遞推方程,并在他們的程序轉(zhuǎn)換工作中首次引入。然后Burstall,MacQueen和Sannella將ML的多態(tài)類型檢查結(jié)合起來(lái),產(chǎn)生了Hope語(yǔ)言。ML最終發(fā)展成幾種方言,其中最常見的是OCaml和Standard ML。
同時(shí),如有影響力的Lambda論文和經(jīng)典的1985年教科書“計(jì)算機(jī)程序的結(jié)構(gòu)和解釋”中所描述的,Scheme的發(fā)展,Lisp 的簡(jiǎn)單詞匯范圍和(不純)功能方言,將功能性編程的力量意識(shí)提升到更廣泛的范圍。編程語(yǔ)言社區(qū)。
在20世紀(jì)80年代,Per Martin-L?f開發(fā)了直覺型理論(也稱為建構(gòu)型理論),它將功能性程序與表達(dá)為依賴類型的建設(shè)性證據(jù)聯(lián)系起來(lái)。這導(dǎo)致了交互式定理證明的新方法,并影響了后續(xù)函數(shù)式編程語(yǔ)言的發(fā)展。 David Turner開發(fā)的懶惰功能語(yǔ)言Miranda最初出現(xiàn)于1985年,對(duì)Haskell有很強(qiáng)的影響力。由于米蘭達(dá)是專有的,Haskell于1987年開始達(dá)成共識(shí)以形成一個(gè)功能規(guī)劃研究的開放標(biāo)準(zhǔn) ; 實(shí)施版本自1990年以來(lái)一直在進(jìn)行中。
最近,它已經(jīng)在基于CSG幾何框架構(gòu)建的OpenSCAD語(yǔ)言的參數(shù)CAD中得到了應(yīng)用,盡管它無(wú)法重新分配值導(dǎo)致了通常不熟悉函數(shù)式編程作為概念的用戶之間的混淆。功能編程繼續(xù)用于商業(yè)環(huán)境。
- 函數(shù)式編程的三大特性:
- immutable data 不可變數(shù)據(jù):像Clojure一樣,默認(rèn)上變量是不可變的,如果你要改變變量,你需要把變量copy出去修改。這樣一來(lái),可以讓你的程序少很多Bug。因?yàn)?,程序中的狀態(tài)不好維護(hù),在并發(fā)的時(shí)候更不好維護(hù)。(你可以試想一下如果你的程序有個(gè)復(fù)雜的狀態(tài),當(dāng)以后別人改你代碼的時(shí)候,是很容易出bug的,在并行中這樣的問(wèn)題就更多了)
- first class functions:這個(gè)技術(shù)可以讓你的函數(shù)就像變量一樣來(lái)使用。也就是說(shuō),你的函數(shù)可以像變量一樣被創(chuàng)建,修改,并當(dāng)成變量一樣傳遞,返回或是在函數(shù)中嵌套函數(shù)。這個(gè)有點(diǎn)像Javascript的Prototype(參看Javascript的面向?qū)ο缶幊?/a>)
- 尾遞歸優(yōu)化:我們知道遞歸的害處,那就是如果遞歸很深的話,stack受不了,并會(huì)導(dǎo)致性能大幅度下降。所以,我們使用尾遞歸優(yōu)化技術(shù)——每次遞歸時(shí)都會(huì)重用stack,這樣一來(lái)能夠提升性能,當(dāng)然,這需要語(yǔ)言或編譯器的支持。Python就不支持。
- 函數(shù)式編程的幾個(gè)技術(shù)
- map & reduce :這個(gè)技術(shù)不用多說(shuō)了,函數(shù)式編程最常見的技術(shù)就是對(duì)一個(gè)集合做Map和Reduce操作。這比起過(guò)程式的語(yǔ)言來(lái)說(shuō),在代碼上要更容易閱讀。(傳統(tǒng)過(guò)程式的語(yǔ)言需要使用for/while循環(huán),然后在各種變量中把數(shù)據(jù)倒過(guò)來(lái)倒過(guò)去的)這個(gè)很像C++中的STL中的foreach,find_if,count_if之流的函數(shù)的玩法。
- pipeline:這個(gè)技術(shù)的意思是,把函數(shù)實(shí)例成一個(gè)一個(gè)的action,然后,把一組action放到一個(gè)數(shù)組或是列表中,然后把數(shù)據(jù)傳給這個(gè)action list,數(shù)據(jù)就像一個(gè)pipeline一樣順序地被各個(gè)函數(shù)所操作,最終得到我們想要的結(jié)果。
- recursing 遞歸 :遞歸最大的好處就簡(jiǎn)化代碼,他可以把一個(gè)復(fù)雜的問(wèn)題用很簡(jiǎn)單的代碼描述出來(lái)。注意:遞歸的精髓是描述問(wèn)題,而這正是函數(shù)式編程的精髓。
- currying:把一個(gè)函數(shù)的多個(gè)參數(shù)分解成多個(gè)函數(shù), 然后把函數(shù)多層封裝起來(lái),每層函數(shù)都返回一個(gè)函數(shù)去接收下一個(gè)參數(shù)這樣,可以簡(jiǎn)化函數(shù)的多個(gè)參數(shù)。在C++中,這個(gè)很像STL中的bind_1st或是bind2nd。
- higher order function 高階函數(shù):所謂高階函數(shù)就是函數(shù)當(dāng)參數(shù),把傳入的函數(shù)做一個(gè)封裝,然后返回這個(gè)封裝函數(shù)?,F(xiàn)象上就是函數(shù)傳進(jìn)傳出,就像面向?qū)ο髮?duì)象滿天飛一樣。
- 還有函數(shù)式的一些好處
- parallelization 并行:所謂并行的意思就是在并行環(huán)境下,各個(gè)線程之間不需要同步或互斥。
- lazy evaluation 惰性求值:這個(gè)需要編譯器的支持。表達(dá)式不在它被綁定到變量之后就立即求值,而是在該值被取用的時(shí)候求值,也就是說(shuō),語(yǔ)句如x:=expression; (把一個(gè)表達(dá)式的結(jié)果賦值給一個(gè)變量)明顯的調(diào)用這個(gè)表達(dá)式被計(jì)算并把結(jié)果放置到 x 中,但是先不管實(shí)際在 x 中的是什么,直到通過(guò)后面的表達(dá)式中到 x 的引用而有了對(duì)它的值的需求的時(shí)候,而后面表達(dá)式自身的求值也可以被延遲,最終為了生成讓外界看到的某個(gè)符號(hào)而計(jì)算這個(gè)快速增長(zhǎng)的依賴樹。
- determinism 確定性:所謂確定性的意思就是像數(shù)學(xué)那樣 f(x) = y ,這個(gè)函數(shù)無(wú)論在什么場(chǎng)景下,都會(huì)得到同樣的結(jié)果,這個(gè)我們稱之為函數(shù)的確定性。而不是像程序中的很多函數(shù)那樣,同一個(gè)參數(shù),卻會(huì)在不同的場(chǎng)景下計(jì)算出不同的結(jié)果。所謂不同的場(chǎng)景的意思就是我們的函數(shù)會(huì)根據(jù)一些運(yùn)行中的狀態(tài)信息的不同而發(fā)生變化。
- 參考網(wǎng)站https://en.wikipedia.org/wiki/Functional_programming
浙公網(wǎng)安備 33010602011771號(hào)