跳轉到內容

程式語言/函數語言程式設計

來自華夏公益教科書,開放的書籍,為一個開放的世界


函數語言程式設計語言

[編輯 | 編輯原始碼]

宣告式程式設計的理念是定義環境工作規則,然後讓語言找出其他所有內容。這與過程式語言形成對比,在過程式語言中,人們會精確地告訴機器該做什麼。函數語言程式設計可以是實現宣告式程式設計風格的一種方式。一個經典的例子是階乘函式。定義新函式的第一步是首先處理平凡情況。那麼,0 的階乘將被定義為 1。下一步是透過一種最終會解析為簡單情況的方式來定義非平凡情況。那麼,n 的階乘將被定義為 n 乘以小於 n 的階乘

fac 0 = 1

fac n = (fac (n-1)) * n

像這樣天真的實現比“for”迴圈使用更多的記憶體和處理時間(它使用 O(n) 棧空間),但這可以透過簡單的更改來解決,使用累加器引數使編譯器或直譯器能夠消除函式呼叫成本

facb 0 acc = acc

facb n acc = facb (n-1) (n*acc)

fac n = facb n 1

函數語言程式設計有很大的用途。人們可以將函式式語言用作程式碼原型——在許多情況下,編寫函式式程式碼並證明它會產生預期結果比使用過程式語言更容易——然後使用過程式技術對其進行最佳化。函式式技術在遍歷二叉樹方面非常有效。

  • 待辦事項:只需描述流行的函式式語言與 lambda 演算的不同之處,重要的是副作用(但要提到 Haskell)
    • Scheme 和 ML 都具有內建型別,例如整數、浮點數、列表和字串
    • Scheme 具有尾呼叫最佳化
    • Scheme 具有多引數函式,而不是柯里化
    • Scheme 對所有結構使用函式式表示法,需要括號
    • Scheme 具有衛生宏
    • ML 是靜態型別,帶有型別推斷
    • ML 具有模式匹配結構
    • ML 只有單引數函式,但透過柯里化和元組模擬了多個引數
    • ML 對函式呼叫使用 lambda 演算表示法(即,不需要括號),但對內建結構使用關鍵字(即,它沒有對 if 使用函式式表示法)

由於 lambda 保留對外部範圍中引用的變數的引用,而這些函式可以在呼叫函式已經返回很久之後被儲存和呼叫,因此使用 lambda 的語言具有垃圾回收。函數語言程式設計是宣告式程式設計的一個子集,它專注於編寫“純函式”。函數語言程式設計正規化是為了明確地支援對問題解決的純函式方法而建立的。函數語言程式設計是一種宣告式程式設計形式。相比之下,大多數主流語言(包括面向物件程式設計 (OOP) 語言,如 C#、Visual Basic、C++ 和 Java)主要是為了支援命令式(過程式)程式設計而設計的。在計算機科學中,函數語言程式設計是一種程式設計正規化——一種構建計算機程式結構和元素的風格——它將計算視為對數學函式的求值,並避免改變狀態和可變資料。它是一種宣告式程式設計正規化,這意味著程式設計是透過表示式或宣告而不是語句完成的。在函式式程式碼中,函式的輸出值僅取決於傳遞給函式的引數,因此每次使用相同的值為引數 x 呼叫函式 f 兩次都會產生相同的結果 f(x);這與過程依賴於區域性或全域性狀態形成對比,區域性或全域性狀態可能會在不同時間使用相同引數但不同程式狀態呼叫時產生不同的結果。消除副作用,即不依賴於函式輸入的狀態更改,可以使理解和預測程式行為變得容易得多,這是開發函數語言程式設計的關鍵動機之一。

組合邏輯是由 Moses Schönfinkel 和 Haskell Curry 開發的等效理論基礎。它最初是為了實現一種更清晰的數學基礎方法而開發的。組合邏輯通常被認為比 lambda 更抽象,並且先於其發明。

  • 詞法範圍與動態範圍
華夏公益教科書