iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 1
4

本篇重點

  • Functional Programming 是一種 編程範式(programming paradigm) ,就像 OOP ,但會不互相衝突,在多種的語言裡都可以實作:如 JavaScript 、 Python 、 Java8 ,只要 Function 是 First Class 即可。
  • Functional Programming 的邏輯強調抽象概念,與 範疇論 (Category Theory) 有些相關。
  • 本系列將以 JavaScript 實作,但你無須是 JavaScript 大師,只需要有 Imperative programming 的經驗,並會殺死一些 bug 即可。
  • 如果文章有任何錯誤的地方,或是你有任何疑問想找我討論,儘管留言就對了!
  • 歡迎加入 PureScript.tw,裡面很多高手喔~

前言

我看了 去年鐵人賽 Modern Web 組冠軍:30 天精通 RxJS ,心中不禁充滿熱血、感動,在今年 JSDC ,聽了講者 CT 的 The Way to Fantasyland,下定決心今年來整理自己在 Functional Programming 的學習經歷,做個大合集跟大家分享。

目標

  • 以淺顯易懂的方式解釋 Functional Programming 的核心概念 。
  • 試著重構 Imperative programming 的程式。
  • 講點 fantasy-land 與範疇學。
  • 最後來點 PureScript

為什麼寫這個主題?

現在不管你寫什麼語言,你都會聽到 Functional Programming 這一詞(以下簡稱為 FP)。
大約在三年前,我第一次接觸 FP,那時我的印象是這是一種讓迴圈變簡單的寫法,可讀性較高,也比較好維護。
就像第一次看到 foreach 迴圈,而且可以像 jquery 那樣玩串串樂,有種「這是某種 Syntax 嗎?」的感覺。

// javascript
// inc everything and sum

let array = [1, 2, 3, 4, 5]

// foreach
let sum = 0
for (let el of array) {
	sum += el + 1
}

// functional way
let sum = array
    .map(x => x + 1)
    .reduce((acc, el) => acc + el, 0)

不久後我開始接觸 redux , redux 以完美且優雅的方式管理 react 元件的 state (在 react 中 state 是非同步行為,而且有可能會互相影響,簡單來說,初學者很容易弄得一團糟),我開始探索「 redux 是怎麼辦到的,這是某種設計模式嗎?」,而它帶我來到 FP。

在今年 JSDC 後,我開始接觸 fantasy-land ,開始發現自己寫的程式屬於範疇學的某些規則,思緒開始變得比以往來的清楚。

學習 FP,就像學完 OOP 後,再學 Design Pattern,
感覺像是真正懂了某種抽象化的邏輯,
即使你不寫 FP,我也非常推薦你讀一讀,
就像微波爐,沒有它你可以過得很好,
但用過之後,就離不開它了。

編程回憶史

在很久很久以前,

  • 組合語言
    你在最低階層詳盡地告訴電腦要做什麼,例如:從記憶體拿出這個、把它放進暫存器,它是一個 指令式編程 (Imperative programming)
  • C
    雖然用組合語言寫程式行的通,但這不容易拓展,所以我們發明了更高級的 C ,它是 程序式編程 (Procedural programming) ,特徵就是把一個大問題分成很多小問題,給一些參數、回傳某個值。
  • Java
    下個世代則是 物件導向 (Object-oriented programming) ,現在可以在物件內封裝東西,然後就可以忘了實作,只需要在意物件的介面,並組合它們。

我們發現某些特定的概念:

  1. Divide and Conquer
    • 把大問題分割成小問題,分別解決之後再組合起來。
  2. Encapsulates and Abstract
    • 這是一種「簡化」的概念,隱藏某些細節,你不必知道這些封裝是怎麼被實作的。

但物件導向似乎有些不太對勁的地方,尤其我們開始撰寫非同步程式時,痛苦變得愈來愈明顯,因為物件導向隱藏了實作,而它剛好隱藏了某種錯誤的東西,使它們不能被組合。

它隱藏了兩件事:

  1. 它改寫了某些內部狀態,而我們不知道。
  2. 它們在彼此之間分享記憶體位置,而導致 競態條件 (Race Condition) ,也因此出現了數據鎖。

函數式編程 (functional programming) 擷取 範疇論 (Category Theory) 的概念,以數學抽象思考、解決問題,這並不意味著 FP 會取代 OOP ,兩者是不衝突、可以並存的,當你從 FP 的概念獲得某些起發,你可以把它實作在任何地方,因為範疇論就是一種抽象概念。

JavaScript?

既然要寫 FP ,那為什麼不是選擇 Haskell 這種專門的語言呢?
我的考量很單純,Haskell 並不是 c-like language,如此文章可能需要花費大部分的篇幅在介紹 Syntax ,這並不是我想寫的,當對 FP 有基本的了解之後,再研究 Syntax 也會比較順利。
若選用 JavaScript,你可以在瀏覽器的 Console 直接測試程式碼,按下 F12 快速簡單方便!
本次鐵人賽也有相當多組的 JavaScript 教學,推薦各位搭配著看,
我特別推薦 重新認識 JavaScript(我也是讀者喔)。

後記

今天大多都是文字概述,沒有程式碼,可能比較難以感同身受。
Hmm...,我保證這會是本系列最多字的文章,明天來講點特別常用到的 JS 語法,然後來寫點程式吧,有什麼問題歡迎留言給我喔。

參考資料


下一篇
JavaScript (ES6) Syntax 大集合
系列文
30天快樂學習 Functional Programming14

2 則留言

2
Kuro Hsu
iT邦新手 4 級 ‧ 2017-12-14 10:21:10

感謝推薦 /images/emoticon/emoticon25.gif

阿志 iT邦新手 5 級‧ 2017-12-15 12:11:05 檢舉

今天也有引用到大大你的文章,你的文章的都很清楚,推推。

poligen iT邦新手 5 級‧ 2017-12-22 22:46:14 檢舉

functional programming rocks!

0
jackwu2606ithome
iT邦新手 5 級 ‧ 2018-09-12 11:54:06

Very Good Sharing

我要留言

立即登入留言