国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

Javascript函數(shù)式編程語言

2019-11-20 11:28:42
字體:
供稿:網(wǎng)友

函數(shù)式編程語言

函數(shù)式編程語言是那些方便于使用函數(shù)式編程范式的語言。簡(jiǎn)單來說,如果具備函數(shù)式編程所需的特征, 它就可以被稱為函數(shù)式語言。在多數(shù)情況下,編程的風(fēng)格實(shí)際上決定了一個(gè)程序是否是函數(shù)式的。

是什么讓一個(gè)語言具有函數(shù)式特征?

函數(shù)式編程無法用C語言來實(shí)現(xiàn)。函數(shù)式編程也無法用Java來實(shí)現(xiàn)(不包括那些通過大量變通手段實(shí)現(xiàn)的近似函數(shù)式編程)。 這些語言不包含支持函數(shù)式編程的結(jié)構(gòu)。他們是純面向?qū)ο蟮摹?yán)格非函數(shù)式的語言。

同時(shí),純函數(shù)語言也無法使用面向?qū)ο缶幊蹋热鏢cheme、Haskell以及Lisp。

然而有些語言兩種模式都支持。Python是個(gè)著名的例子,不過還有別的:Ruby,Julia,以及我們最感興趣的Javascript。 這些語言是如何支持這兩種差別如此之大的設(shè)計(jì)模式呢?它們包含兩種編程范式所需要的特征。 然而對(duì)于Javascript來說,函數(shù)式的特征似乎是被隱藏了。

但實(shí)際上,函數(shù)式語言所需要的比上述要多一些。到底函數(shù)式語言有什么特征呢?

特點(diǎn) 命令式 函數(shù)式
編程風(fēng)格 一步一步地執(zhí)行,并且要管理狀態(tài)的變化 描述問題和和所需的數(shù)據(jù)變化以解決問題
狀態(tài)變化 很重要 不存在
執(zhí)行順序 很重要 不太重要
主要的控制流 循環(huán)、條件、函數(shù)調(diào)用 函數(shù)調(diào)用和遞歸
主要的操作單元 結(jié)構(gòu)體和類對(duì)象 函數(shù)作為一等公民的對(duì)象和數(shù)據(jù)集

函數(shù)式語言的語法必須要顧及到特定的設(shè)計(jì)模式,比如類型推斷系統(tǒng)和匿名函數(shù)。大體上,這個(gè)語言必須實(shí)現(xiàn)lambda演算。 并且解釋器的求值策略必須是非嚴(yán)格、按需調(diào)用的(也叫做延遲執(zhí)行),它允許不變數(shù)據(jù)結(jié)構(gòu)和非嚴(yán)格、惰性求值。

譯注:這一段用了一些函數(shù)式編程的專業(yè)詞匯。lambda演算是一套函數(shù)推演的形式化系統(tǒng)(聽起來很暈), 它的先決條件是內(nèi)部函數(shù)和匿名函數(shù)。非嚴(yán)格求值和惰性求值差不多一個(gè)意思,就是并非嚴(yán)格地按照運(yùn)算規(guī)則把所有元素先計(jì)算一遍, 而是根據(jù)最終的需求只計(jì)算有用的那一部分,比如我們要取有一百個(gè)元素的數(shù)組的前三項(xiàng), 那惰性求值實(shí)際只會(huì)計(jì)算出一個(gè)具有三個(gè)元素是數(shù)組,而不會(huì)先去計(jì)算那個(gè)一百個(gè)元素的數(shù)組。 

優(yōu)點(diǎn)

當(dāng)你最終掌握了函數(shù)式編程它將給你巨大的啟迪。這樣的經(jīng)驗(yàn)會(huì)讓你后面的程序員生涯更上一個(gè)臺(tái)階, 無論你是否真的會(huì)成為一個(gè)全職的函數(shù)式程序員。

不過我們現(xiàn)在不是在討論如何去學(xué)習(xí)冥想;我們正在探討如何去學(xué)習(xí)一個(gè)非常有用的工具,它將會(huì)讓你成為一個(gè)更好的程序員。

總的來說,什么是使用函數(shù)式編程真正實(shí)際的優(yōu)點(diǎn)呢?

更加簡(jiǎn)潔的代碼

函數(shù)式編程更簡(jiǎn)潔、更簡(jiǎn)單、更小。它簡(jiǎn)化了調(diào)試、測(cè)試和維護(hù)。

例如,我們需要這樣一個(gè)函數(shù),它能將二維數(shù)組轉(zhuǎn)化為一維數(shù)組。如果只用命令式的技術(shù),我們會(huì)寫成這樣:

function merge2dArrayIntoOne(arrays) {  var count = arrays.length;  var merged = new Array(count);  var c = 0;  for (var i = 0; i < count; ++i) {   for (var j = 0, jlen = arrays[i].length; j < jlen; ++j) {    merged[c++] = arrays[i][j];   }  }  return merged}

現(xiàn)在使用函數(shù)式技術(shù),可以寫成這樣:

merge2dArrayIntoOne2 = (arrays) -> arrays.reduce (memo, item) ->  memo.concat item , []
var merge2dArrayIntoOne2 = function(arrays) { return arrays.reduce( function(p,n){  return p.concat(n); }, []);};
譯注:原著中代碼有誤,調(diào)用reduce函數(shù)時(shí)少了第二個(gè)參數(shù)空數(shù)組,這里已經(jīng)補(bǔ)上。

這兩個(gè)函數(shù)具有同樣的輸入并返回相同的輸出,但是函數(shù)式的例子更簡(jiǎn)潔。

模塊化

函數(shù)式編程強(qiáng)制把大型問題拆分成解決同樣問題的更小的情形,這就意味著代碼會(huì)更加模塊化。 模塊化的程序具有更清晰的描述,更易調(diào)試,維護(hù)起來也更簡(jiǎn)單。測(cè)試也會(huì)變得更加容易, 這是由于每一個(gè)模塊的代碼都可以單獨(dú)檢測(cè)正確性。

復(fù)用性

由于其模塊化的特性,函數(shù)式編程會(huì)有許多通用的輔助函數(shù)。你將會(huì)發(fā)現(xiàn)這里面的許多函數(shù)可以在大量不同的應(yīng)用里重用。

在后面的章節(jié)里,許多最通用的函數(shù)將會(huì)被覆蓋到。然而,作為一個(gè)函數(shù)式程序員,你將會(huì)不可避免地編寫自己的函數(shù)庫, 這些函數(shù)會(huì)被一次又一次地使用。例如一個(gè)用于在行間查找配置文件的函數(shù),如果設(shè)計(jì)好了也可以用于查找Hash表。

減少耦合

耦合是程序里模塊間的大量依賴。由于函數(shù)式編程遵循編寫一等公民的、高階的純函數(shù), 這使得它們對(duì)全局變量沒有副作用而彼此完全獨(dú)立,耦合極大程度上的減小了。 當(dāng)然,函數(shù)會(huì)不可避免地相互依賴,但是改變一個(gè)函數(shù)不會(huì)影響其他的,只要輸入和輸出的一對(duì)一映射保持正確。

數(shù)學(xué)正確性

最后一點(diǎn)更理論一些。由于根植于lambda演算,函數(shù)式編程可以在數(shù)學(xué)上證明正確性。 這對(duì)于一些研究者來說是一個(gè)巨大的優(yōu)點(diǎn),他們需要用程序來證明增長(zhǎng)率、時(shí)間復(fù)雜度以及數(shù)學(xué)正確性。

我們來看看斐波那契數(shù)列。盡管它很少用于概念性證明以外的問題,但是用它來解釋這個(gè)概念非常好。 對(duì)一個(gè)斐波那契數(shù)列求值標(biāo)準(zhǔn)的辦法是建立一個(gè)遞歸函數(shù),像這樣:

fibonnaci(n) = fibonnaci(n-2) + fibonnaci(n

主站蜘蛛池模板:
上饶县|
汶川县|
左权县|
合肥市|
左云县|
夹江县|
新竹市|
平泉县|
汉源县|
栖霞市|
芦溪县|
柘城县|
台州市|
惠东县|
台中市|
墨竹工卡县|
宜兰市|
丘北县|
五寨县|
界首市|
慈溪市|
深泽县|
正安县|
衡山县|
厦门市|
赞皇县|
林西县|
水城县|
永嘉县|
奈曼旗|
万荣县|
金山区|
洪湖市|
昭苏县|
赤城县|
麦盖提县|
康定县|
石家庄市|
南投县|
龙岩市|
云梦县|