函數語言程式設計初探(總集篇)

SaltAir發表於2018-12-29

函數語言程式設計,應該是非典型的面嚮物件語言裡面都曾經探討過的一種程式設計正規化吧,大約今年4月份因為工作需要去看react文件時瞭解到react本身的函數語言程式設計的思想,再到redux使用的建議“不可變資料”時,覺得react真的是JavaScript函數語言程式設計的一種典型實現:不可變資料、純函式、使用高階函式、必要時使用柯里化(currying)來優化效能等等都是在踐行函數語言程式設計的精髓。

一、概述

函數語言程式設計在維基百科裡面的定義是:

In computer science, functional programming is a programming paradigm—a style of building the structure and elements of computer programs—that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. It is a declarative programming paradigm, which means programming is done with expressions or declarations instead of statements.

提煉出重點來就是:更多的使用表示式或宣告而不是語句來完成程式設計;涉及到計算的都按照數學上的思想來:避免狀態和資料的可變性。 解釋略微枯燥,用通俗一點的話來說就是,按照函數語言程式設計的思想來說,我們應該寫的函式叫做:純函式,這個函式只要是接收一個確切的引數就永遠返回一個確切的結果,所有的答案都是一對一的;儘量避免使用語句來實現所有功能,儘量使用變數、函式或其他內建方法來實現需求(也就是例用柯里化的方式來程式設計)。

1. 避免狀態和資料可變性(純函式)

舉個例子來說明會更好一些 首先是非函數語言程式設計的例子

let number = 2
let sum = function(){
  number++
}
sum(number)
sum()    //3
sum()    //4
//每次呼叫都會得到不同的結果,造成很大不確定性
複製程式碼

下一個是函數語言程式設計的例子

let sum = function(x){
  return x+1
}
//不依賴於外部的資料,而且也不改變外部資料的值,而是返回一個新的值給你。
複製程式碼
2. 函式柯里化

柯里化指的就是傳遞給函式一部分引數來呼叫它,讓它返回一個函式去處理剩下的引數。

function cal(x){
  return function(y){
    return x * y
  }
}
//呼叫時
let num1 = cal(2)      //此變數返回的是一個函式
num1(3)    //6
//如果使用箭頭函式直接寫的話會更加簡潔
複製程式碼

這樣,在呼叫時就可以更加方便地根據業務需求來進行呼叫,也就是我們提到的延遲呼叫。 事實上柯里化是一種“預載入”函式的方法,通過傳遞較少的引數,得到一個已經記住了這些引數的新函式,某種意義上講,這是一種對引數的“快取”,是一種非常高效的編寫函式的方法;像是lodash這種很出名的庫也有專門對於柯里化的處理方式(即curry,引入即可)

3. 宣告式程式設計
//命令式
var CEOs = [];
var compainies = [{},{},{}]    //裡面包含一些已有的物件,此處不舉例
for(var i = 0; i < companies.length; i++){
    CEOs.push(companies[i].CEO)
}

//宣告式
var CEOs = companies.map(c => c.CEO);
複製程式碼

函數語言程式設計主要的正規化大約就是以上已有的,主要是三個方面,後續我會堅持把這一系列都寫完,主要會從這三個特徵裡的每一個方面進行一定程度的深入。 最後一句,其實這些文章是用來激勵自己的,哈哈哈立下過FLAG要每個周出一篇對我來說有質量的文章,只要是我覺得我為了寫這篇文章學到了有用的東西,這就值了~

相關文章