歷史

  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)的方言,如SchemeClojure,以及DylanJulia等分支,試圖簡(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. Iverson20世紀(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ǔ)言NPLNPL基于Kleene遞推方程,并在他們的程序轉(zhuǎn)換工作中首次引入。然后Burstall,MacQueen和Sannella將ML的多態(tài)類型檢查結(jié)合起來(lái),產(chǎn)生了Hope語(yǔ)言。ML最終發(fā)展成幾種方言,其中最常見的是OCamlStandard 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ù)式編程的幾個(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