Slide 1

Slide 1 text

Abstract Thinking - 從 FP 看⾒見見程式之美

Slide 2

Slide 2 text

為什什麼我會開始學 Funtional Programming?

Slide 3

Slide 3 text

在這個時代 學習是沒有終點的

Slide 4

Slide 4 text

既然學無⽌止境,
 那重點就在如何提升學習效率

Slide 5

Slide 5 text

Roadmap B M N Y Q R X A P

Slide 6

Slide 6 text

跨領域 X A P

Slide 7

Slide 7 text

B M N Y Q R X A P

Slide 8

Slide 8 text

連結 B M N Y Q R X A P

Slide 9

Slide 9 text

重點不在於學會哪些技術, ⽽而在於建立這些技術之間連結的能⼒力力

Slide 10

Slide 10 text

Flow - Mihaly Csikszentmihalyi Boredom Anxiety Flow you should be here challenge skills high high low low

Slide 11

Slide 11 text

只要在已知的知識邊界去開拓拓

Slide 12

Slide 12 text

這套學習系統其實是不完整的

Slide 13

Slide 13 text

⼀一個⾃自⼰己熟知的概念念或觀念念 出現在⼀一個完全不相關的領域 有沒有過這樣的經驗?

Slide 14

Slide 14 text

Node.js 與 麥當勞

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

Process

Slide 17

Slide 17 text

Thread

Slide 18

Slide 18 text

Order Queue

Slide 19

Slide 19 text

Prepare Queue

Slide 20

Slide 20 text

Single Thread

Slide 21

Slide 21 text

Timer Pending Callback Idle, Prepare Pull Check Close Callback Order Prepare

Slide 22

Slide 22 text

Multiple Thread

Slide 23

Slide 23 text

缺少了了⼀一個維度 B M N Y Q R X A P

Slide 24

Slide 24 text

B M N Y Q R X A P 抽象化 Q Y Z M

Slide 25

Slide 25 text

什什麼是抽象化?

Slide 26

Slide 26 text

抽象化就是 把重複出現的模式或類似的事物 作出歸納的過程

Slide 27

Slide 27 text

⼈人類語⾔言就是 社會對真實世界抽象化後的產物

Slide 28

Slide 28 text

很多外國⼈人會覺得 華⼈人的數學普遍比較好

Slide 29

Slide 29 text

我認為有⼀一部分的原因來來⾃自於 中⽂文對於數字的抽象做得很好

Slide 30

Slide 30 text

1 2 3 4 5 6 7 8 9 10 ……….… 100 … 1000 … 10000 … 100000000 ⼀一 ⼆二 三 四 五 六 七 八 九 ⼗十 …百 …… 千 …….. 萬 ………… 億

Slide 31

Slide 31 text

1 2 3 4 5 6 7 8 9 10 11 !!<-> 20 …… 100 ……… 1000 …… 1000000 … 1000000000 one !!<-> ten eleven !!<-> twenty … hundred … thousand … million ……. billion

Slide 32

Slide 32 text

在數數上,英⽂文要比中⽂文多學 10 ~ 17 個單字

Slide 33

Slide 33 text

或許⼤大家對英⽂文熟悉度比較⾼高, 所以較難感受出差異異

Slide 34

Slide 34 text

我⾃自⼰己認識的語⾔言當中, 對數字抽象化最糟的語⾔言

Slide 35

Slide 35 text

我⾃自⼰己認識的語⾔言當中, 對數字抽象化最糟的語⾔言 法語

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

un deux trois quatre cinq six sept huit neuf dix onze douze treize quatorze quinze seize 1 - 16 是獨立的單字

Slide 38

Slide 38 text

dix-sept 10 7

Slide 39

Slide 39 text

vingt et un 20 和 1

Slide 40

Slide 40 text

vingt-deux 20 2

Slide 41

Slide 41 text

vingt et un trente et un quarante et un cinquante et un soixante et un 20 和 1 30 和 1 40 和 1 50 和 1 60 和 1

Slide 42

Slide 42 text

soixante et onze 60 和 11

Slide 43

Slide 43 text

quatre-vingt-un 4 20 1

Slide 44

Slide 44 text

通常學到這裡就會放棄了了

Slide 45

Slide 45 text

有好的抽象化, 有不好的抽象化

Slide 46

Slide 46 text

抽象化很難?

Slide 47

Slide 47 text

抽象化 是⼈人類⼤大腦運作的⽅方式

Slide 48

Slide 48 text

我們⼩小時候如何學顏⾊色的?

Slide 49

Slide 49 text

⼩小時候爸爸或媽媽會跟你說 香蕉是黃⾊色的

Slide 50

Slide 50 text

但事實上 你不知道什什麼是香蕉什什麼是黃⾊色 你可能會認為黃⾊色就是指香蕉

Slide 51

Slide 51 text

但這都不重要,只要等到...

Slide 52

Slide 52 text

下次你看到計程⾞車車時,媽媽會跟你說 計程⾞車車是黃⾊色的

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

抽象化 是⼈人類與⽣生俱來來的能⼒力力

Slide 55

Slide 55 text

我們要學的是 如何做好抽象化

Slide 56

Slide 56 text

講了了這麼久的抽象化跟程式 有什什麼關係?!

Slide 57

Slide 57 text

很多⼈人都學程式很多年年了了

Slide 58

Slide 58 text

99% 的需求⼤大概都能完成

Slide 59

Slide 59 text

剩下的 1% 可能靠 google 也能做出來來

Slide 60

Slide 60 text

為什什麼我們還持續的在學程式?

Slide 61

Slide 61 text

其實我們在學的是 如何封裝程式或者說如何做好抽象化

Slide 62

Slide 62 text

⾝身為⼯工程師最痛苦的⼀一件事就是 接⼿手別⼈人的爛 code

Slide 63

Slide 63 text

所謂的爛 code 就是 程式碼錯誤的封裝、不好的抽象

Slide 64

Slide 64 text

我們可以列列出很多
 錯誤封裝的例例⼦子

Slide 65

Slide 65 text

但從反⾯面的例例⼦子中學習 進步速度是很慢的

Slide 66

Slide 66 text

有沒有⼀一個系統性的⽅方式 來來學習抽象化

Slide 67

Slide 67 text

Functional Programming λ

Slide 68

Slide 68 text

Why Functional Programming?

Slide 69

Slide 69 text

Why Functional Programming? FP 來來⾃自數學

Slide 70

Slide 70 text

Why Functional Programming? 數學是⼈人類抽象化最好的科學 FP 來來⾃自數學

Slide 71

Slide 71 text

數學很難?

Slide 72

Slide 72 text

我們要學的是數學的抽象化⽅方式

Slide 73

Slide 73 text

1 + 1 = 2

Slide 74

Slide 74 text

2 * 10 = 20

Slide 75

Slide 75 text

2 * 10 = 20 2 + 2 + … + 2 = 20

Slide 76

Slide 76 text

不會考你 23 * 567 是多少 也不會問你 庭院深深深幾許

Slide 77

Slide 77 text

今天我們只講 FP 當中的兩兩個觀念念

Slide 78

Slide 78 text

1. Function Composition 2. 怎麼到處都是 map?

Slide 79

Slide 79 text

Function Composition

Slide 80

Slide 80 text

想像⼀一下,某⼀一天...

Slide 81

Slide 81 text

你在新北郊區⼀一家廉價的旅館醒來來

Slide 82

Slide 82 text

頭暈暈暈暈的 看著灰灰髒髒的天花板

Slide 83

Slide 83 text

有幾隻⼤大蟑螂緩慢地爬過

Slide 84

Slide 84 text

你突然想起... 今天下午三點在台北市有個約會

Slide 85

Slide 85 text

只剩下半個⼩小時的時間

Slide 86

Slide 86 text

你只依稀記得⾃自⼰己是⼀一位魔法師

Slide 87

Slide 87 text

你掌握了了三個咒語,分別是...

Slide 88

Slide 88 text

嘰嘰烏拉拉 波波⼒力力那 ⾙貝⾙貝魯魯多

Slide 89

Slide 89 text

嘰嘰烏拉拉!!

Slide 90

Slide 90 text

No content

Slide 91

Slide 91 text

你想了了⼀一下, 騎⾺馬其實來來不及趕到臺北市了了

Slide 92

Slide 92 text

⾙貝⾙貝魯魯多!!

Slide 93

Slide 93 text

蹦!

Slide 94

Slide 94 text

⾺馬消失在了了空氣之中...

Slide 95

Slide 95 text

嘰嘰烏拉拉 波波⼒力力那 ⾙貝⾙貝魯魯多

Slide 96

Slide 96 text

波波⼒力力那,⾙貝⾙貝魯魯多

Slide 97

Slide 97 text

No content

Slide 98

Slide 98 text

最終,你開著跑⾞車車去台北市赴約了了

Slide 99

Slide 99 text

像魔法師⼀一樣解決問題

Slide 100

Slide 100 text

const sum = arr !=> arr.reduce((x, y) !=> x + y, 0); const map = fn !=> arr !=> arr.map(fn); function onClick (value) { console.log(value); !// ['290', '123', '234']; } 計算使⽤用者輸入數字的總額

Slide 101

Slide 101 text

const sum = arr !=> arr.reduce((x, y) !=> x + y, 0); const map = fn !=> arr !=> arr.map(fn); function onClick (value) { console.log(value); !// ['290', '123', '234']; const numArr = map(Number)(value); const result = sum(numArr); console.log(result); } 計算使⽤用者輸入數字的總額

Slide 102

Slide 102 text

把咒語(Function)組合起來來

Slide 103

Slide 103 text

const sum = arr !=> arr.reduce((x, y) !=> x + y, 0); const map = fn !=> arr !=> arr.map(fn); function onClick (value) { console.log(value); !// ['290', '123', '234']; const numArr = map(Number)(value); const result = sum(numArr); console.log(result); } 計算使⽤用者輸入數字的總額

Slide 104

Slide 104 text

const sum = arr !=> arr.reduce((x, y) !=> x + y, 0); const map = fn !=> arr !=> arr.map(fn); const compose = (!!...fns) !=> (args) !=> fns.reduceRight((args, f) !=> f.call(null, args), args) function onClick (value) { console.log(value); !// ['290', '123', '234']; const numArr = map(Number)(value); const result = sum(numArr); console.log(result); } 把 function 組合起來來

Slide 105

Slide 105 text

const sum = arr !=> arr.reduce((x, y) !=> x + y, 0); const map = fn !=> arr !=> arr.map(fn); const compose = (!!...fns) !=> (args) !=> fns.reduceRight((args, f) !=> f.call(null, args), args) function onClick (value) { console.log(value); !// ['290', '123', '234']; const result = compose(sum, map(Number))(value); console.log(result); } 把 function 組合起來來

Slide 106

Slide 106 text

const sum = arr !=> arr.reduce((x, y) !=> x + y, 0); const map = fn !=> arr !=> arr.map(fn) const compose = (!!...fns) !=> (args) !=> fns.reduceRight((args, f) !=> f.call(null, args), args) const sumArrayString = compose(sum, map(Number)); function onClick (value) { console.log(value) !// ['290', '123', '234']; const result = sumArrayString(value); console.log(result); } 把 function 組合起來來

Slide 107

Slide 107 text

import * as R from 'ramda'; const sumArrayString = R.compose(R.sum, R.map(Number)); function onClick (value) { console.log(value) !// ['290', '123', '234']; const result = sumArrayString(value); console.log(result); } 改⽤用 Ramda

Slide 108

Slide 108 text

有沒有覺得⾃自⼰己像魔法師了了?

Slide 109

Slide 109 text

讓我們抽象的來來看 Function Composition

Slide 110

Slide 110 text

f g

Slide 111

Slide 111 text

f g h

Slide 112

Slide 112 text

f g h = g 。 f

Slide 113

Slide 113 text

f g h = g 。 f X Y Z

Slide 114

Slide 114 text

怎麼到處都有 map?

Slide 115

Slide 115 text

Haskell - Type signature

Slide 116

Slide 116 text

const add = (x: number) !=> (y: number): number !=> x + y TypeScript

Slide 117

Slide 117 text

Haskell add !:: Number !-> Number !-> Number add x y = x + y 回傳值 參參數

Slide 118

Slide 118 text

那些年年我們⼀一直看到的 map

Slide 119

Slide 119 text

⼤大家最常⾒見見的 Array map

Slide 120

Slide 120 text

R.map(String)([1, 2, 3]) !// ['1', '2', '3']

Slide 121

Slide 121 text

!// map !:: (a !-> b) !-> Array a !-> Array b R.map(String)([1, 2, 3]) !// ['1', '2', '3']

Slide 122

Slide 122 text

有些⼈人看過的 Observable map

Slide 123

Slide 123 text

!// map !:: (a !-> b) !-> Observable a !-> Observable b map(String)(Observable.of(1)) !// Observable.of('1')

Slide 124

Slide 124 text

其實還有很多的 map

Slide 125

Slide 125 text

data Maybe a = Nothing | Just a

Slide 126

Slide 126 text

import * as R from "ramda"; import * as Maybe from 'folktale/maybe' R.map(String)(Maybe.Just(1)); !// Just('1') R.map(String)(Maybe.Nothing()); !// Nothing data Maybe a = Nothing | Just a map !:: (a !-> b) !-> Maybe a !-> Maybe b map _ Nothing = Nothing map f Just a = Just f a add x y = x + y add1 = add 1 map add1 (Just 1) !-- Just 2 map add1 (Nothing) !-- Nothing JavaScript Haskell

Slide 127

Slide 127 text

map(String)([1]) !// ['1'] map(String)(Observable.of(1)) !// Observable.of('1') map(String)(Maybe.Just(1)); !// Just('1') Functor

Slide 128

Slide 128 text

這些型別都具有 map

Slide 129

Slide 129 text

他們是什什麼關係?

Slide 130

Slide 130 text

他們都是 Functor

Slide 131

Slide 131 text

class Functor f where fmap !:: (a !-> b) !-> f a !-> f b Functor

Slide 132

Slide 132 text

fmap id = id fmap (f . g) = fmap f . fmap g fmap 須滿⾜足

Slide 133

Slide 133 text

const id = x !=> x; const arr = [1, 2, 3]; !// fmap id = id R.map(id)(arr) !// [1, 2, 3] id(arr) !// [1, 2, 3] !// fmap (f . g) = fmap f . fmap g R.map( R.compose( R.add(1), R.add(2) ) )(arr); !// [4, 5, 6] R.compose( R.map(R.add(1)), R.map(R.add(2)) )(arr); !// [4, 5, 6]

Slide 134

Slide 134 text

抽象化來來看 fmap

Slide 135

Slide 135 text

fmap f fmap g M x M y M z

Slide 136

Slide 136 text

fmap f fmap g h = fmap g 。fmap f M x M y M z

Slide 137

Slide 137 text

回想⼀一下 還有哪些型別也是 Functor

Slide 138

Slide 138 text

Promise.resolve(1) .then(String) !// Promise.resolve('1')

Slide 139

Slide 139 text

還有嗎?

Slide 140

Slide 140 text

Function 其實也是 Functor

Slide 141

Slide 141 text

那 Function 的 fmap 是什什麼?!

Slide 142

Slide 142 text

fmap f add1 add3

Slide 143

Slide 143 text

compose add2 add1 add3

Slide 144

Slide 144 text

Function 的 map 就是 compose

Slide 145

Slide 145 text

當我們學會了了這些抽象化

Slide 146

Slide 146 text

再回過頭去學各個程式語⾔言 會發現簡單很多

Slide 147

Slide 147 text

比如說 Swift 跟 Scala

Slide 148

Slide 148 text

Swift Optional Scala Optional

Slide 149

Slide 149 text

學習好的抽象化可以幫助 我們學習⼀一個完全不同領域的知識

Slide 150

Slide 150 text

Learn How To Learn

Slide 151

Slide 151 text

Think How To Think

Slide 152

Slide 152 text

Reference • Learn How To Learn ❤ • 知識地圖 • 教你成為 IT 界的德魯魯伊 • Developer Roadmap • Flow: The Psychology of Optimal Experience ❤ • The 3 Zone Everyone Should Know About • 法語吐槽影片 • Haskell Book • Mostly Adequate Guide • 中⽂文版 • Why Functional Programming Matter • 抽象: 設計的藝術 • 封⾯面圖

Slide 153

Slide 153 text

Jerry Hong Tech Leader | Website: blog.jerry-hong.com Facebook: J.H.MingChen