什麼是高階函式? 使用高階函式有什麼好處?
## 什麼是高階函式。舉一些例子好了。
Clojure 的 constantly, partial, apply 是比 map, filter, reduce 相對少見的高階函式。
constantlly 會傳回一個可以接受任何引數、但是傳回固定值的函式。
```
(map (constantly 9) [1 2 3])
user=> (9 9 9)
````
partial 可以偏特化函式,即它可以接受一個函式做為引數,並且將該函式之引數固定為特定的值之後,再加以傳回。在下方的例子裡,partial 接受 + 做為引數,將 1 做為值來偏特化 + 。
user=> (def add-one (partial + 1))
#'user/add-one
user=> (add-one 2)
;=> 3
apply 可以接受一個函式做為第一引數、一個陣列做為第二引數,而 apply 可以將第一引數的函式『套用』(apply) 到陣列上,即陣列裡的每一個元素都會依序成為第一引數的函式的引數。
(apply max [1 2 3])
;;=> 3
;; which is the same as
(max 1 2 3)
## 使用高階函式有什麼好處?
一個關鍵的好處在於它讓 what/how 分離了。當你使用高階函式時,你的語意停留在指定了 what,而你把實作細節的 how 留給了高階函式處理。而這個 what/how 分離是軟體設計之中一個關鍵的技巧。
很多時候,軟體 layer 與 layer 之間往往很難做到乾淨的切分。比方說,即使表面上看起來 A module 只依賴於 B module 的 3 個函式。然而,一旦仔細去看 A module 的實作時,往往又發現,不只是這樣子,A module 依賴的除了 B module 的 3 個函式之外,還有 B module 的 傳回的 XX 值,值必定是 OO 型態之類的。
上述的現象很常見,而一旦有了這種現象,往往 B module 也無法做成 library 日後繼續使用。
而如果要讓軟體可以有複用性,就要考慮設計時讓 what/how 分離。如果 A module 只處理 what,而 B module 只處理 how ,這種設計方式,就很有機會讓 B module 有複用性。
what/how 分離的技巧非常地抽象。
你天天用高階函式,反複地去體會何謂 what/how 分離,直到有一天,許許多多的 what/how 分離都再也難逃你的法眼,最後,你也終於進入了信手捻來都會寫出了 what/how 分離的設計的境界。
參考:https://replware.substack.com/p/e48
感謝補充~
## 什麼是高階函式。舉一些例子好了。
Clojure 的 constantly, partial, apply 是比 map, filter, reduce 相對少見的高階函式。
constantlly 會傳回一個可以接受任何引數、但是傳回固定值的函式。
```
(map (constantly 9) [1 2 3])
user=> (9 9 9)
````
partial 可以偏特化函式,即它可以接受一個函式做為引數,並且將該函式之引數固定為特定的值之後,再加以傳回。在下方的例子裡,partial 接受 + 做為引數,將 1 做為值來偏特化 + 。
```
user=> (def add-one (partial + 1))
#'user/add-one
user=> (add-one 2)
;=> 3
```
apply 可以接受一個函式做為第一引數、一個陣列做為第二引數,而 apply 可以將第一引數的函式『套用』(apply) 到陣列上,即陣列裡的每一個元素都會依序成為第一引數的函式的引數。
```
(apply max [1 2 3])
;;=> 3
;; which is the same as
(max 1 2 3)
;;=> 3
```
## 使用高階函式有什麼好處?
一個關鍵的好處在於它讓 what/how 分離了。當你使用高階函式時,你的語意停留在指定了 what,而你把實作細節的 how 留給了高階函式處理。而這個 what/how 分離是軟體設計之中一個關鍵的技巧。
很多時候,軟體 layer 與 layer 之間往往很難做到乾淨的切分。比方說,即使表面上看起來 A module 只依賴於 B module 的 3 個函式。然而,一旦仔細去看 A module 的實作時,往往又發現,不只是這樣子,A module 依賴的除了 B module 的 3 個函式之外,還有 B module 的 傳回的 XX 值,值必定是 OO 型態之類的。
上述的現象很常見,而一旦有了這種現象,往往 B module 也無法做成 library 日後繼續使用。
而如果要讓軟體可以有複用性,就要考慮設計時讓 what/how 分離。如果 A module 只處理 what,而 B module 只處理 how ,這種設計方式,就很有機會讓 B module 有複用性。
what/how 分離的技巧非常地抽象。
你天天用高階函式,反複地去體會何謂 what/how 分離,直到有一天,許許多多的 what/how 分離都再也難逃你的法眼,最後,你也終於進入了信手捻來都會寫出了 what/how 分離的設計的境界。
參考:https://replware.substack.com/p/e48
感謝補充~