iT邦幫忙

2022 iThome 鐵人賽

DAY 16
0

在先前的章節中,我們花了很多的篇幅來介紹純函式與副作用(Side Effects)的定義,這對我們來了解 Impure Function 會非常有幫助!

那什麼是 Impure Function 呢?

純函式不同,Impure Function 會在執行的過程中產生副作用,或是我們在函式中使用了 Mutable Data(例如帶有自己的狀態),帶來預期之外值的改變。

舉先前計算水果庫存的範例來說:

const appleAmount = 10;
const orangeAmount = 20
let appleStockAmount;
let orangeStockAmount;
function calcFruitStockAmount () {
	appleStockAmount = appleAmount * 0.9;
	orangeStockAmount = orangeAmount * 0.9;
}
calcFruitStockAmount();
// appleStockAmount -> 9
// orangeStockAmount -> 18

當我們在執行 calcFruitStockAmount 的同時,不論今天我們怎去執行這個韓式,appleStockAmountorangeStockAmount 變數一定會被同時改變,即便我們不一定同時要計算兩者的庫存量,這就是個典型的 Impure Function。

經過先前的討論,我們也會發現,如果想要避免副作用的產生,我們就必須得搭配 return 關鍵字,並且將函式看作一種「值」。

在我剛開始學習寫程式的時候,我其實搞不是很懂所謂「函式是用來解決重複性問題」的定義,
以及我要怎麼判斷何處是被重複的,哪邊又該獨立出來。

於是我常常會把一整個流程寫進同一個函式中,導致我在無意識的狀況下幫自己寫了不少 Bug,舉例來說:

async function getData() {
	const a = await fetchA();
	const b = await fetchB(); 
}
// fetchA 與 fetchB 為 HTTP request 的簡化函式

某個函式是專門處理 A API 的 fetchA() 函式,用來取得 a 資料,但因為可能某個流程中同時會用到這兩隻 API ,於是我為了偷懶,同時在 getData 這個函式中又呼叫了 B API 。

導致未來有元件要獨自呼叫 A API 時,或是獨立呼叫 B API 時,我依然要額外將 fetchA()fetchB() 各自分離出去,不然就會在不需要 B API 的狀況下呼叫它了。

在還沒有了解 Pure Function 設計理念前,我很常寫出一些 Impure 的程式碼,導致在開發的過程中,要不斷地回頭修正與翻新共用元件,這聽起來很不理想吧?

Pure 與 Impure

每當討論到 Impure Function 時,總會覺得撰寫出 Impure 的函式好像很不應該、是一種負面的意思,但其實我們可以把 Impure Function 當成一種行程( Procedure),一種被觸發後會完成指定任務的程式碼片段,這樣的程式撰寫模式所產出的 Output 並不會跟 Input 有所關聯。

還記得在聊 JavaScript 核心概念時,我們曾經特別聊過的表達式與陳述式的概念嗎?

其實 Pure 與 Impure 的差異,就如同表達式與陳述式的差異,我們很難在程式碼中完全不使用或是避開陳述式,而是在我們所需要的地方使用「適合」的工具。

因此 Impure Function 也是一種撰寫程式碼的風格,只是這樣的風格在原生的 JavaScript 並不好維護與控制其預期的產出。

那我們要將所有的函式都修正成純函式嗎?

除非我們想要將所有的程式碼、套件引入 Pure 的概念,不然依照網頁開發歷史悠久的包袱來說,很多套件都還是採用 OOP ,光是撰寫風格就很不同了,如果我們真的有必要引入這類型的套件,卻在擔心自己的程式碼不夠「Pure」,就不太必要。

雖然這系列的內容是在聊 FP ,也提倡大家可以使用 FP 及純函式,但我認為知其然而知其所以然會比「瞎用」來的重要得多。

理解程式碼為什麼要避開 Impure Function ,我們才能撰寫出好的純函式,因此我認為了解 Impure Function 的特性是非常重要的。

如果這幾章節消化下來,還是覺得 Pure 與 Impure 的概念有些空泛,這時候我們是時候來看看一些設計理論了!

在下一個章節中,我們會透過 Pure 與 Impure 的概念來看看所謂的宣告式程式設計與命令式程式設計,這些常常在程式書籍中出現,但我們卻不知道它們在幹嘛的「酷東西」,那麼我們就下一章節見啦!

參考資料:

TechPedia:What Does Procedure Mean?


上一篇
Day 15:什麼是純函式 ?(3):副作用
下一篇
Day 17:什麼是純函式 ?(5):宣告式程式設計
系列文
致 JavaScript 開發者的 Functional Programming 新手指南30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言