函數式編程那些事兒

函數式編程是一種編程範式,在其中它試圖將每個函數都綁定到純數學函數中。這是一種聲明式的編程風格,著重於解決什麼而不是如何解決。


函數式編程那些事兒


Clojure,Common Lisp,Erlang,Haskell和Scala是遵循函數式編程方法的一些著名編程語言。編程範例基於lambda演算,下面簡要說明:

Lambda演算

它使用表達式來代替語句。與執行語句以分配變量的語句不同,表達式的求值產生一個值。Lambda演算構成了幾乎所有使用的功能編程語言的基礎。

Lambda Calculus由Alonzo Church開發,是用於研究具有函數的計算的框架。使用lambda演算認為任何事物都是可計算的。它可以被標記為所有語言中最簡潔的編程語言。

就計算能力而言,lambda演算類似於圖靈機,後者為命令式編程奠定了基礎。簡單來說,lambda演算是一個描述函數及其評價的理論框架。


函數式編程那些事兒


純函數

純函數具有兩個重要屬性,它們是:

  • 無論其他因素如何,始終使用相同的參數產生相同的輸出,此屬性也稱為不變性
  • 純函數要麼提供一些輸出,要麼修改任何參數或全局變量,即它們沒有副作用,次屬性叫做確定性

由於純函數沒有副作用或隱藏的I / O,因此使用函數範式構建的程序易於調試。此外,純函數使編寫併發應用程序更加容易。

使用函數式編程風格編寫代碼時,有能力的編譯器將能夠:

  • 記住結果
  • 並行運算
  • 等待評估結果

遞歸

在函數式編程範例中,沒有for和while循環。相反,函數式編程語言依賴於遞歸進行迭代。遞歸是使用遞歸函數實現的,遞歸函數會重複調用自己,直到達到基本情況為止。

引用透明性

一旦在函數式編程語言中定義了變量,就不允許在程序執行期間更改它們持有的值。這稱為引用透明性。它確保相同的語言表達式給出相同的輸出。

功能程序沒有任何賦值語句。為了在使用功能編程開發的程序中存儲其他值,必須定義新變量。在這樣的程序中,變量的狀態在任何時候都是恆定的。

引用透明性幾乎消除了任何不良影響的可能性,這是因為在程序執行的任何時候都可以用其實際值替換任何變量。

函數是一流的,可以是高階的

函數式編程風格的函數被視為變量。因此,它們是一流的功能。這些一流的函數被允許作為參數傳遞給其他函數,或者從函數返回或存儲在數據結構中。

高階函數是將其他函數用作參數和/或返回函數的函數。在函數式編程語言中,一等函數可以是高階函數。


函數式編程那些事兒


變量是不可變的

變量是不可變的,即變量一旦初始化就無法修改。儘管我們可以創建一個新變量,但不允許修改現有變量。

函數式編程語言中變量的不變性質以在整個程序執行過程中保持狀態的形式受益。

優點

  • 由於純函數不會更改任何狀態,並且完全取決於輸入,因此它們很容易理解。這些函數給定的返回值與它們產生的輸出相同。純函數的參數和返回類型由其函數簽名給出。
  • 由於純函數具有避免更改變量或變量之外的任何數據的性質,因此實現併發變得有效
  • 它支持延遲評估的概念,這意味著僅在需要時才評估和存儲該值。
  • 純函數僅接受一次參數併產生不變的輸出。因此,它們不會產生任何隱藏的輸出。它們使用不可變的值,從而使調試和測試更加容易。
  • 它的樣式將函數視為值,並將其作為參數傳遞給其他函數。它增強了代碼的理解性和可讀性。

缺點

  • 不變的值與遞歸結合可能會導致性能下降
  • 在某些情況下,編寫純函數會導致代碼的可讀性下降
  • 儘管編寫純函數很容易,但是將其與應用程序的其餘部分以及I / O操作結合起來很困難
  • 以遞歸方式編寫程序來代替使用循環,這可能是一項艱鉅的任務

應用領域

通常,函數式編程語言通常首選用於學術目的,而不是用於商業軟件開發。

但是,遵循功能性編程範例的幾種傑出的編程語言,例如Clojure,Erlang,F#,Haskell和Racket,被廣泛用於開發各種商業和工業應用。

WhatsApp利用Erlang(一種遵循功能性編程範例的編程語言)讓100多名員工即可管理超過15億人的數據。

函數式編程風格的另一個重要語言是Haskell。Facebook在其反垃圾郵件系統中使用了它。甚至JavaScript(使用最廣泛的編程語言之一)也喜歡使用函數式編程。

函數式編程風格對於各種編程語言引領不同領域至關重要。例如,統計中的R和財務分析中的J,K和Q。

領域特定的聲明性語言(例如Lex / Yacc和SQL)甚至使用這種編程範例的某些元素來避開可變值。

通常,此範例廣泛用於:

  • 針對併發或並行的應用
  • 進行數學計算

總結

除了純函數式編程語言外,還可以在非函數式編程語言中建立函數式編程方法。

C ++ 11,C#3.0和Java 8都添加了用於簡化書寫風格的函數式編程。

儘管通常以功能樣式編寫,但是Scala具有副作用和易變狀態的存在。因此,可以將編程語言置於命令式和功能性編程樣式之間的中間狀態。


分享到:


相關文章: