有顏色的函式不是壞事

閱讀時間約 2 分鐘

What Color is Your Function? 一文中

Async function 被比喻成「紅色函式」

紅色函式不能在普通的函式裡(即「藍色函式」)使用

因此紅色具有感染性

定義函式之前必須先決定是否要染成紅色

作者不喜歡這種麻煩的規則

但我認為這種麻煩是有道理的


並不是只有Async function具有這種特性

其他像是:

Java的throw catch語法

rust的unsafe function

PureScript的partial function

Haskell的IO Monad

c++的non-const function

它們都具有感染性

它們的顏色代表了它們所關注的特性

Java強化傳統的例外處理機制

使錯誤變得可預期

rust在意記憶體安全

並使用unsafe在語法上明確地說明這一點

Haskell對於pure(referential transparency)的要求很嚴格

side effect必須以Monad的形式標註於型別上

Haskell因為歷史因素在totality上有很大的問題

而PureScript用Partial class修復了這個的問題

c++的non-const function只能在non-const function裡和non-const variable呼叫

使得const保證物件不會被修改


感染性使問題得以從根源(callee)傳播到你面前(caller)

這些都是在編譯時期完成的

因此開發者得以解放部分的專注力

把精力與時間花在真正的程式邏輯上

感染性使得這個特性使用起來會比較麻煩

這是因為他把原本被忽略被隱藏的特性顯現出來

rust的unsafe揭示了原本在c++習以為常但危險的操作

PureScript的partial也是如此

它們同時也建議使用者盡量把紅色函式抽離出來

而不是全部攪和在一起

rust本身的設計就是希望安全的程式碼應該好寫

不安全的程式碼仍然可能但不容易寫

Haskell的IO雖然是因為純函數式設計的問題才出現的

但同時也提供了「分離輸入輸出與計算邏輯」的思考方式


總結來說感染性使用的好是會給開發者帶來好處的

但像是c++的const就是使用的很差的例子

具有感染性的其實是non-const

但開發者常常在宣告函式時沒有正確的使用const

這使得const用起來很不方便

常常需要手動const_cast

相較之下rust的mut就非常地完美

更糟的例子是當有兩套一樣的函式但有兩種顏色時

我們就必須選邊站

Async function就是這種情況

另外類似的還有OOP的encapsulation

OOP把封裝限定在資料型別上

要使用封裝的函式只能繼承自該類別

這使得「少用繼承多用組合」變得難以實現

物件導向因此變得具有感染性(在壞的意義上)

3會員
23內容數
這不是教你如何從物件導向到函數式編程的入門教程。我會深入探討物件導向與函數式編程的差異,並討論為什麼你應該使用函數式編程並徹底放棄物件導向。
留言0
查看全部
發表第一個留言支持創作者!