摘要:函數式編程的準則不依賴于外部的數據,而且也不改變外部數據的值,而是返回一個新的值給你。函數式編程利用純函數的無狀態性,它的好處非常多結果可預期利于測試利于復用利于并發,但一個系統工程的代碼,是不可能全部采用純函數來寫的。
什么是函數式編程
函數式編程是一種編程范式,常見的編程范式有以下三種:
命令式編程
聲明式編程
函數式編程
函數式編程的本質是將計算描述為一種表達式求值。在函數式編程中,函數作為一等公民,可以在任何地方定義(在函數內或函數外),可以作為函數的參數和返回值,可以對函數進行組合。
函數式編程的準則:不依賴于外部的數據,而且也不改變外部數據的值,而是返回一個新的值給你。看個簡單的例子:
// 非函數式的例子 let count = 0; function increment() { count++; // 依賴于函數外部的值,并改變了它的值 } // 函數式的例子 function increment(count) { return count++; }為什么采用函數式編程
函數式編程不依賴外部的狀態也不修改外部的狀態,函數調用的結果不依賴調用的時間和位置,這些寫代碼容易進行推理,不易犯錯,而且單測和調試都更簡單。即函數編程采用純函數。
純函數是這樣一種函數,即相同的輸入,永遠會得到相同的輸出,而且沒有任何可觀察的副作用。
副作用可能包含,但不限于:
更改文件系統
往數據庫插入記錄
發送一個 http 請求
可變數據
打印/log
獲取用戶輸入
DOM 查詢
訪問系統狀態
副作用是在計算結果的過程中,系統狀態的一種變化,或者與外部世界進行的可觀察的交互。
純函數的好處:
純函數能根據輸入來做緩存(memoize技術)
const memoize = function(f) { const cache = {}; return function() { const argStr = JSON.stringify(arguments); if (!cache[argStr]) { cache[argStr] = f.apply(f, arguments); } return cache[argStr]; } }
可移植性/自文檔化
純函數的輸出只依賴與它的輸入,依賴很明確,易于理解。由于純函數不依賴它的上下文環境,因此我們可以輕易的把它移植到任何地方運行它。
可測試性
我們不必在每次測試前都去配置和構造初始環境,只需簡單給函數一個輸入,然后斷言它的輸出就好了。
合理性
由于純函數總是能夠根據相同的輸入返回相同的輸出,所以它們就能夠保證總是返回同一個結果,這也就保證了引用透明性。
并行執行
我們可以并行運行任意純函數。因為純函數根本不需要訪問共享的內存,而且根據其定義,純函數也不會因副作用而進入競爭態。
并行代碼在服務端 js 環境以及使用了 web worker 的瀏覽器那里是非常容易實現的,因為它們使用了線程(thread)。不過出于對非純函數復雜度的考慮,當前主流觀點還是避免使用這種并行。
這里我們先不展開這些技術的細節內容,本文我們先側重于對函數式編程有一個整體上的認識,具體的技術細節我們將在下一章展開。
curry(柯里化)
compose(代碼組合)
Monad(Monad就是一種設計模式,表示將一個運算過程,通過函數拆解成互相連接的多個步驟。你只要提供下一步運算所需的函數,整個運算就會自動進行下去。)
如何正確看待函數式編程我們先來看以下幾種觀點:
你這段代碼用了 for 循環,這是過程式的。為了優雅,你應該寫成函數式的。
你這段代碼有副作用,這是骯臟的。為了純凈性,你應該把 IO 包在 Monad 里。
你這段代碼用了 class,這是面向對象的。為了無狀態,你應該寫成高階函數。
我想說的是這種偏激的觀點是不正確的,我們不應該把函數式編程和命令式編程對立起來,我們更多的時候需要考慮的是技術的適用場景。函數式編程寫起代碼來,有一定的難度,如果一個團隊的整體水平達不到,那么寫代碼的質量和效率還不如采用命令式編程好。函數式編程利用純函數的無狀態性,它的好處非常多(結果可預期、利于測試、利于復用、利于并發),但一個系統工程的代碼,是不可能全部采用純函數來寫的。當我們越貼近業務,我們就離純函數與無狀態越遠。
函數式編程非常重要,學習它我們能打開我們的思維方式,使用它也有很多好處,但它也有一些局限,我們應該客觀看待。保持開放的心態,根據實際場景選擇合適的技術,是一個工程師基本的素養。
參考資料https://llh911001.gitbooks.io...
http://www.ruanyifeng.com/blo...
https://coolshell.cn/articles...
https://www.zhihu.com/questio...
https://zhuanlan.zhihu.com/p/...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/102564.html
摘要:函數式編程,一看這個詞,簡直就是學院派的典范。所以這期周刊,我們就重點引入的函數式編程,淺入淺出,一窺函數式編程的思想,可能讓你對編程語言的理解更加融會貫通一些。但從根本上來說,函數式編程就是關于如使用通用的可復用函數進行組合編程。 showImg(https://segmentfault.com/img/bVGQuc); 函數式編程(Functional Programming),一...
摘要:聲明式編程一種編程范式,與命令式編程相對立。常見的聲明式編程語言有數據庫查詢語言,正則表達式邏輯編程函數式編程組態管理系統等。函數式編程,特別是純函數式編程,嘗試最小化狀態帶來的副作用,因此被認為是聲明式的。 編程范式與函數式編程 一、編程范式的分類 常見的編程范式有:函數式編程、程序編程、面向對象編程、指令式編程等。在面向對象編程的世界,程序是一系列相互作用(方法)的對象(Class...
摘要:所以我覺得函數式編程領域更像學者的領域。函數式編程的原則是完善的,經過了深入的研究和審查,并且可以被驗證。函數式編程是編寫可讀代碼的最有效工具之一可能還有其他。我知道很多函數式編程編程者會認為形式主義本身有助于學習。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson - 《You-Dont-Know-JS》作者 關于譯者:這是一個流淌著滬江血液...
摘要:今天這篇文章主要介紹函數式編程的思想。函數式編程通過最小化變化使得代碼更易理解。在函數式編程里面,組合是一個非常非常非常重要的思想。可以看到函數式編程在開發中具有聲明模式。而函數式編程旨在盡可能的提高代碼的無狀態性和不變性。 最開始接觸函數式編程的時候是在小米工作的時候,那個時候看老大以前寫的代碼各種 compose,然后一些 ramda 的一些工具函數,看著很吃力,然后極力吐槽函數式...
摘要:函數式編程的哲學就是假定副作用是造成不正當行為的主要原因。函數組合面向對象通常被比喻為名詞,而函數式編程是動詞。尾遞歸優化函數式編程語言中因為不可變數據結構的原因,沒辦法實現循環。 零、前言 說到函數式編程,想必各位或多或少都有所耳聞,然而對于函數式的內涵和本質可能又有些說不清楚。 所以本文希望針對工程師,從應用(而非學術)的角度將函數式編程相關思想和實踐(以 JavaScript 為...
閱讀 2243·2021-09-22 15:25
閱讀 3621·2019-08-30 12:48
閱讀 2211·2019-08-30 11:25
閱讀 2343·2019-08-30 11:05
閱讀 730·2019-08-29 17:28
閱讀 3291·2019-08-26 12:16
閱讀 2614·2019-08-26 11:31
閱讀 1720·2019-08-23 17:08