函數式語言 函數式編程 利用若干簡單的執行單元讓計算結果不斷漸進,逐層推導複雜的運算

 小結:php

一、程序員

不修改狀態。在函數式編程中,程序語言在使用中是會不修改變量的,它的一個特性可使得函數式編程語言區別於其餘的程序語言。在其餘類型的語言中,變量是用來保存狀態的。因爲函數式編程不修改變量,致使了這些狀態不能存在於變量中。那麼,函數式編程語言保存狀態的方法是使用參數來保存,遞歸方法是最好的例子。因爲採用了遞歸方法,函數式編程語言在運行速度上相對於其餘語言較慢,因此,速度不夠快是函數式編程語言長期不能普遍使用的主要緣由。算法

在函數式程序語言中,全部的功能的結果就是一個返回值,不存在其餘的行爲,包括對外部變量的修改。express

程序員在進行函數式編程時徹底不用考慮死鎖的問題,由於它根本就不修改變量,因此就不存在鎖線程的問題;編程

 二、數組

強調程序執行的結果而非執行的過程,倡導利用若干簡單的執行單元讓計算結果不斷漸進,逐層推導複雜的運算,而不是設計一個複雜的執行過程數據結構

 

 

 

 

https://baike.baidu.com/item/函數式編程/4035031?fr=aladdin閉包

https://baike.baidu.com/item/函數式語言/7663961?fr=aladdin併發

 

函數式語言(functional language)一類程序設計語言,是一種非馮·諾伊曼式的程序設計語言。函數式語言主要成分是原始函數、定義函數和函數型。這種語言具備較強的組織數據結構的能力,能夠把某一數據結構(如數組)做爲單一值處理;能夠把函數做爲參數,其結果也可爲函數,這種定義的函數稱爲高階函數,程序就是函數,程序做用在結構型數據上,產生結構型結果,從根本上改變了馮·諾伊曼式語言的「逐詞」工做方式。
 
中文名
函數式語言
外文名
functional language
學    科
計算機科學
定    義
非馮·諾伊曼式的程序設計語言
特    點
並行、單元測試等
優    點
代碼管理更加方便

介紹

編輯
因爲計算機技術的不斷髮展,函數式編程語言逐漸獲得人們的重視。咱們如今使用的大多數編程語言大都是以馮諾伊曼式的計算機爲設計背景,因此咱們稱這些計算機編程語言爲諾伊曼式語言。1977年,John Backus提出了函數式編程語言,這種語言以非馮諾伊曼式的計算機爲設計而背景,因此咱們又稱這樣的函數式編程語言稱爲非馮諾伊曼式語言。函數式編程,又稱泛函編程,是一種編程範型,它將電腦運算視爲數學上的函數計算,而且避免狀態以及可變數據。函數編程語言最重要的基礎是λ演算。並且λ演算的函數能夠接受函數看成輸入(引數)和輸出(傳出值)。和命令式編程相比,函數式編程強調函數的計算比指令的運行重要。和程序編程相比,函數式編程裹,函數的計算可隨時調用。
Haskell是一種於1980年代末期所發佈的函數式編程語言,Haskell函數式編程語言是在Miranda的基礎上獲得了,它對Miranda進行了標準化,因此這種語言集合了其餘相關函數式編程開發的原理,它無需花費太多的贅述就能完成一些數據結構,好比鏈表和矩陣,是當前最普遍地被用於研究的一種函數式編程語言。它的語言衍生物有不少,有擴充Haskell、並行Haskell和麪向對象的變體如Mondrian等。與此同時,它還被用做爲在新語言設計時的標準模板。
另外一種函數式編程語言是Clean,它和Haskell有不少同樣的地方。目前這門語言是用C寫成的,由尼茲梅根大學負責維護。
還有一種函數式編程語言是Meta Language, MetaLanguage是由愛丁堡大學與上個世紀七十年代末所開發的,它被歸類爲非純函數式編程語言,它之因此有這樣的歸類是由於它容許了反作用和指令式編程的使用。 目前,函數式編程語言還有F#,這是一款針對.NET平臺的開放研究的語言。  [1] 

語言的特色

編輯
函數式編程常用遞歸。純函數式的程序沒有變量和反作用(Side effect)。由於純函數式程序設計語言沒有變量,函數沒有反作用,編寫出的程序能夠利用記憶化、公共子表達式消除和併發計算在運行時和編譯時獲得大量優化。咱們常見的編程語言有數十種之多。編程語言種類有不少,若是按照程序設計的方法,可分爲如下幾種程序語言:
(1)結構化編程語言,好比C語言等。
(2)函數式編程語言,好比OCaml, Lisp等。
(3)邏輯式編程語言,好比Prolog等。
(4)面向對象程序語言,好比Java等。
經過比較能夠發現,函數式編程語言有如下幾個特色:
一、並行。在函數式編程中,程序員無需對程序修改,程序就能夠併發運行。程序運行期間,不會產生死鎖現象。緣由是經過函數式編程所獲得的程序,在程序中不會出現某一數據被同時修改兩次及以上的狀況,一樣的,兩個不一樣的線程就更不用說了。因爲函數式編程有這樣的優勢,致使了程序員徹底不用花費精力去考慮增長某個線程帶來的併發問題。
在函數編程語言中,編譯器會分析代碼,辨認出潛在耗時的建立字符串s1和s2的函數,而後將他們並行的運行。這樣的作法,是程序員在使用普通的命令式程序語言時不可能作到的。而使用函數式程序語言能夠自動的找出那些能夠併發執行的函數。
二、單元測試。在函數式編程中,因爲程序中的每個符號都是final後的,因此這樣的函數不會產生反作用。這就致使了在某個地方產生修改,同時不會有函數修改過在自身範圍以外的變量或者狀態被另外的函數所使用。這就致使了函數的返回結果只是返回值。只有函數自身的參數纔會影響函數的返回值,因此在編程的時候,對程序中的每一個函數而言,程序員只需在控制它們的參數,而不用在乎函數本身點順序以及函數外部變量和狀態就能正確的編程。與函數式編程相比,命令式編程就沒有這樣的優點了,在檢查函數的返回值的同時程序員還必須檢查函數是否影響到了函數的外部狀態和變量。
三、沒有額外做用。反作用是指的是函數內部與外部互動。好比,函數在自身內部能夠對函數之外的其餘變量進行修改,這樣就會產生其餘結果。在函數式編程中,想要達到這樣的目的就必須讓函數自身要保持獨立。在函數式程序語言中,全部的功能的結果就是一個返回值,不存在其餘的行爲,包括對外部變量的修改。
四、不修改狀態。在函數式編程中,程序語言在使用中是會不修改變量的,它的一個特性可使得函數式編程語言區別於其餘的程序語言。在其餘類型的語言中,變量是用來保存狀態的。因爲函數式編程不修改變量,致使了這些狀態不能存在於變量中。那麼,函數式編程語言保存狀態的方法是使用參數來保存,遞歸方法是最好的例子。因爲採用了遞歸方法,函數式編程語言在運行速度上相對於其餘語言較慢,因此,速度不夠快是函數式編程語言長期不能普遍使用的主要緣由。
五、引用透明。在函數式編程中,引用透明指的是運行函數的時候,函數的沒一個步驟都不會不牽連到函數的外部變量或狀態,而是隻依賴於函數輸入的參數,相同的參數輸入總會獲得相同的函數返回值。而在其餘類型的語言中,函數的返回值不只僅與函數的參數傳入有關,也與當前的系統狀態有關。在不一樣的系統狀態的狀況下,函數的返回值不一樣。
六、代碼部署熱。在之前,假如想在Windows上安裝更新,安裝以後重啓計算機是必須進行的步驟,可能還不僅一次的重啓。即便是僅僅安裝了一個小的軟件也不能免於重啓的步驟。一些特殊的系統,好比電信系統,這樣的系統必須保證任什麼時候間都在運行。由於若是在系統更新時緊急撥號失效,就可能形成很大的損失。最理想的狀況是在徹底不中止系統任何組件的狀況下,達到更新相關的代碼的目的。這樣的想法在命令式編程中是不可能的。對函數式的程序,全部的狀態即傳遞給函數的參數都被保存在了堆棧上,這使的熱部署垂手可得。實際上,全部咱們須要作的就是對工做中的代碼和新版本的代碼作一個差別比較,而後部署新代碼。其餘的工做將由一個語言工具自動完成。

使用意義

編輯
函數式編程語言相對於其餘編程語言具備如下意義:首先,函數式編程語言的代碼十分簡單,加快了開發的速度。而且因爲在使用函數式編程語言時,程序員會大量使用到函數,從而減小了重複的代碼,於是程序比較短。其次,函數式編程語言更加接近咱們使用的天然語言,程序員在學習和使用它的時候更加快捷容易。函數式編程語言的自由度很高,十分接近天然語言寫出的代碼。另外,函數式編程語言的代碼管理更加方便。函數式編程不會對外部產生依賴,也不會修改外界的狀態。程序員只需把指定的參數給函數,相同的參數其返回的結果一定是相同的。另外,函數式編程語言還支持併發編程,這就使得程序員在進行函數式編程時徹底不用考慮死鎖的問題,由於它根本就不修改變量,因此就不存在鎖線程的問題。最後,函數式編程語言的代碼支持代碼熱升級。  [2] 
 
 
 
 
函數式編程是種編程方式,它將電腦運算視爲函數的計算。函數編程語言最重要的基礎是λ演算(lambda calculus),並且λ演算的函數能夠接受函數看成輸入(參數)和輸出(返回值)。  [1] 
和指令式編程相比,函數式編程強調函數的計算比指令的執行重要。
和過程化編程相比,函數式編程裏函數的計算可隨時調用。
 
中文名
函數式編程
外文名
Functional Programming
類    型
編程範式
原    理
將電腦運算視爲函數的計算
基    礎
λ演算
主要思想
把運算過程寫成嵌套函數調用

目錄

  1. 歷史
  2. 定義
  1. 例子
  2. 特性
  1. 優勢
  2. 顧慮

歷史

編輯
雖然 λ 演算並不是設計來於計算機上執行,但可視爲第一個函數式編程語言。1980年代末期,Haskell發佈企圖集合不少函數式編程研究裏的想法。  [2] 

定義

編輯
簡單說,"函數式編程"是一種"編程範式"(programming paradigm),也就是如何編寫程序的方法論。
它屬於"結構化編程"的一種,主要思想是把運算過程儘可能寫成一系列嵌套的函數調用。  [2] 

例子

編輯
函數式編程中最古老的例子莫過於1958年被創造出來的LISP了,透過 LISP,能夠用精簡的人力。較現代的例子包括Haskell、Clean、Erlang和Miranda等。  [3] 

特性

編輯
閉包和高階函數
函數編程支持函數做爲第一類對象,有時稱爲閉包或者 仿函數(functor)對象。實質上,閉包是起函數的做用並能夠像對象同樣操做的對象。與此相似,FP 語言支持高階函數。高階函數能夠用另外一個函數(間接地,用一個 表達式) 做爲其輸入參數,在某些狀況下,它甚至返回一個函數做爲其輸出參數。這兩種結構結合在一塊兒使得能夠用優雅的方式進行模塊化編程,這是使用 FP 的最大好處。  [4] 
惰性計算
除了高階函數和 仿函數(或閉包)的概念,FP 還引入了 惰性計算的概念。在惰性計算中, 表達式不是在綁定到變量時當即計算,而是在求值程序須要產生表達式的值時進行計算。延遲的計算使您能夠編寫可能潛在地生成無窮輸出的函數。由於不會計算多於程序的其他部分所須要的值,因此不須要擔憂由無窮計算所致使的 out-of-memory 錯誤。一個惰性計算的例子是生成無窮 Fibonacci 列表的函數,可是對第n個Fibonacci 數的計算至關於只是從可能的無窮列表中提取一項。
遞歸
FP 還有一個特色是用 遞歸作爲控制流程的機制。例如,Lisp 處理的列表定義爲在頭元素後面有子列表,這種表示法使得它本身天然地對更小的子列表不斷遞歸。
函數式編程具備五個鮮明的特色。
函數是"第一等公民"
所謂"第一等公民"(first class),指的是函數與其餘數據類型同樣,處於平等地位,能夠賦值給其餘變量,也能夠做爲參數,傳入另外一個函數,或者做爲別的函數的返回值。
舉例來講,下面代碼中的print變量就是一個函數,能夠做爲另外一個函數的參數。
var print = function(i){ console.log(i);};
  [1,2,3].forEach(print);
只用"表達式",不用"語句"
"表達式"(expression)是一個單純的運算過程,老是有返回值;"語句"(statement)是執行某種操做,沒有返回值。函數式編程要求,只使用表達式,不使用語句。也就是說,每一步都是單純的運算,並且都有返回值。
緣由是函數式編程的開發動機,一開始就是爲了處理運算(computation),不考慮系統的讀寫(I/O)。"語句"屬於對系統的讀寫操做,因此就被排斥在外。
固然,實際應用中,不作I/O是不可能的。所以,編程過程當中,函數式編程只要求把I/O限制到最小,不要有沒必要要的讀寫行爲,保持計算過程的單純性。
沒有"反作用"
所謂"反作用"(side effect),指的是函數內部與外部互動(最典型的狀況,就是修改全局變量的值),產生運算之外的其餘結果。
函數式編程強調沒有"反作用",意味着函數要保持獨立,全部功能就是返回一個新的值,沒有其餘行爲,尤爲是不得修改外部變量的值。
不修改狀態
上一點已經提到,函數式編程只是返回新的值,不修改系統變量。所以,不修改變量,也是它的一個重要特色。
在其餘類型的語言中,變量每每用來保存"狀態"(state)。不修改變量,意味着狀態不能保存在變量中。函數式編程使用參數保存狀態,最好的例子就是遞歸。下面的代碼是一個將字符串逆序排列的函數,它演示了不一樣的參數如何決定了運算所處的"狀態"。
引用透明性
函數程序一般還增強 引用透明性,即若是提供一樣的輸入,那麼函數老是返回一樣的結果。就是說,表達式的值不依賴於能夠改變值的全局狀態。這使您能夠從形式上推斷程序行爲,由於表達式的意義只取決於其子表達式而不是計算順序或者其餘表達式的反作用。這有助於驗證正確性、簡化算法,甚至有助於找出優化它的方法。
反作用
反作用是修改系統狀態的語言結構。由於 FP 語言不包含任何 賦值語句,變量值一旦被指派就永遠不會改變。並且,調用函數只會計算出結果 ── 不會出現其餘效果。所以,FP 語言沒有反作用。  [5] 

優勢

編輯
1. 代碼簡潔,開發快速
函數式編程大量使用函數,減小了代碼的重複,所以程序比較短,開發速度較快。
Paul Graham在《黑客與畫家》一書中寫道:一樣功能的程序,極端狀況下,Lisp代碼的長度多是C代碼的二十分之一。
若是程序員天天所寫的代碼行數基本相同,這就意味着,"C語言須要一年時間完成開發某個功能,Lisp語言只須要不到三星期。反過來講,若是某個新功能,Lisp語言完成開發須要三個月,C語言須要寫五年。"固然,這樣的對比故意誇大了差別,可是"在一個高度競爭的市場中,即便開發速度只相差兩三倍,也足以使得你永遠處在落後的位置。"
2. 接近天然語言,易於理解
函數式編程的自由度很高,能夠寫出很接近天然語言的代碼。
前文曾經將表達式(1 + 2) * 3 - 4,寫成函數式語言:
subtract(multiply(add(1,2), 3), 4)
對它進行變形,不可貴到另外一種寫法:
add(1,2).multiply(3).subtract(4)
這基本就是天然語言的表達了。再看下面的代碼,你們應該一眼就能明白它的意思吧:
merge([1,2],[3,4]).sort().search("2")
所以,函數式編程的代碼更容易理解。
3. 更方便的代碼管理
函數式編程不依賴、也不會改變外界的狀態,只要給定輸入參數,返回的結果一定相同。所以,每個函數均可以被看作獨立單元,頗有利於進行單元測試(unit testing)和除錯(debugging),以及模塊化組合。
4. 易於"併發編程"
函數式編程不須要考慮"死鎖"(deadlock),由於它不修改變量,因此根本不存在"鎖"線程的問題。沒必要擔憂一個線程的數據,被另外一個線程修改,因此能夠很放心地把工做分攤到多個線程,部署"併發編程"(concurrency)。
請看下面的代碼:
var s1 = Op1();
var s2 = Op2();
var s3 = concat(s1, s2);
因爲s1和s2互不干擾,不會修改變量,誰先執行是無所謂的,因此能夠放心地增長線程,把它們分配在兩個線程上完成。其餘類型的語言就作不到這一點,由於s1可能會修改系統狀態,而s2可能會用到這些狀態,因此必須保證s2在s1以後運行,天然也就不能部署到其餘線程上了。
多核CPU是未來的潮流,因此函數式編程的這個特性很是重要。
5. 代碼的熱升級
函數式編程沒有反作用,只要保證接口不變,內部實現是外部無關的。因此,能夠在運行狀態下直接升級代碼,不須要重啓,也不須要停機。 Erlang語言早就證實了這一點,它是瑞典愛立信公司爲了管理電話系統而開發的,電話系統的升級固然是不能停機的。

顧慮

編輯
函數式編程常被認爲嚴重耗費在CPU和存儲器資源。主因有二:
  • 早期的函數式編程語言實現時並沒有考慮過效率問題。
  • 有些非函數式編程語言爲求提高速度,不提供自動邊界檢查或自動垃圾回收等功能。
惰性求值亦爲語言如 Haskell增長了額外的管理工做。
 
 
 
 
https://zh.wikipedia.org/wiki/函數式編程

函數式編程英語:functional programming)或稱函數程序設計泛函編程,是一種編程範式,它將計算機運算視爲函數運算,而且避免使用程序狀態以及易變對象。其中,λ演算(lambda calculus)爲該語言最重要的基礎。並且,λ演算的函數能夠接受函數看成輸入(引數)和輸出(傳出值)。編程語言

比起指令式編程,函數式編程更增強調程序執行的結果而非執行的過程,倡導利用若干簡單的執行單元讓計算結果不斷漸進,逐層推導複雜的運算,而不是設計一個複雜的執行過程。

相關文章
相關標籤/搜索