函数式编程笔记 01
Cousera 上 Functional Programming Prinples in Scala 的筆記。
編程范式
范式描述了某些科學學科中獨特的概念或者思考模式。
主要的編程范式:
- 命令式編程
- 函數式編程
- 邏輯式編程
與它正交:
- 面向對象編程
命令式編程
- 修改可變變量
- 賦值
- 諸如if-then-else、loops、break、continue、return等的控制結構
簡單來理解,命令式編程就是Von Neumann計算機上的指令序列。
命令式的程序和計算機
- 可變變量 ≈ 內存單元
- 變量解引用 ≈ load指令
- 變量賦值 ≈ store指令
- 控制結構 ≈ jump指令
這在程序規模變大時會出現問題。怎樣才能避免逐字的翻譯式的編程?
John Backus 1978年在Turing Award上的講稿:Can Programming be Liberated from the von. Neumann Style?
Jone Backus是第一個高級語言Fortran的發明者。
規模增大
純命令式編程被Von Neumann所限制:
“One tends to conceptualize data structures word-by-word”
需要其他的方式來定義類似于集合、多項式、幾何圖形、串、文檔等這些高級的抽象。
理想的方法是提出集合、形狀、串等的定理。
什么是定理
定理包括
- 一個或多個數據類型
- 這些類型上的運算符
- 值和運算符之間關系的規則
定理并不描述變化!
定理不包括變化
一個定義兩個多項式的和的例子:
(a * x + b) + (c * x + d) = (x + c) * x + (b + d) 復制代碼它并沒有定義一個在改變系數的同時保持多項式相等的運算符!
但是在命令式編程中卻可以這樣寫:
class Polynomial { double[] coefficient; } Polynomial p = …; p.coefficient[0] = 42; 復制代碼(系數coefficient[0]變了但多項式p沒變)
另外一個例子是字符串中的++運算符:
(a ++ b) ++ c = a ++ (b ++ c) 復制代碼它并沒有定義一個在改變序列元素的同時保持序列相等的運算符!
Java在這兒做的不錯……它的String是不可變的。
對編程的影響
如果想根據它們的數學定理來實現高級概念,那就沒有變化的地方。
- 數學不承認它
- 變化會毀掉定理中有用的規律
因此
- 用函數來表達運算符的定理
- 避免變化
- 有了一個強大的方法來抽象和構造函數
函數式編程
- 在狹義上,函數式編程意味著沒有可變變量,賦值,循環和其他的命令式控制結構
- 在廣義上,函數式編程意味著專注于函數
- 特別是,函數可以是能被產生、消耗和構造的值
- 這在函數式語言中都特別簡單
函數式編程語言
函數是一等公民。
- 在任何地方都可以被定義,包括在另一個函數內部
- 像其他值一樣,可以作為參數傳遞給其他函數,也可以作為值返回
- 像其他值一樣,有一套構造函數的運算符
狹義上的函數式編程語言:
- Pure Lisp, XSLT, XPath, XQuery, FP
- Haskell (without I/O Monad or UnsafPerformIO)
廣義上的函數式編程語言:
- Lisp, Scheme, Racket, Clojure
- SML, Ocaml, F#
- Haskell (full language)
- Scala
- Smalltalk, Ruby
函數式編程語言歷史
- 1959 - Lisp
- 1975-77 - ML, FP, Scheme
- 1978 - Smalltalk
- 1986 - Standard ML
- 1990 - Haskell, Erlang
- 1999 - XSLT
- 2000 - OCaml
- 2003 - scala, XQuery
- 2005 - F#
- 2007 - Clojure
資源
Leaning Resources
總結
以上是生活随笔為你收集整理的函数式编程笔记 01的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 亚马逊《辐射》剧集片场照流出,最早今年上
- 下一篇: 形似“飞碟”的无人机你见过吗?它还可以灭