newsence

反對柯里化的理由

Hacker News·14 天前

我認為雖然柯里化在函數式編程中顯得優雅,但它往往會導致性能開銷、笨拙的函數組合以及類型統一問題,而這些問題其實可以透過元組式參數和語法糖得到更好的解決。

背景

本文探討了函數式編程中常見的「柯里化」(Currying)設計,質疑其作為預設函數定義方式的必要性。作者比較了命令式語言的參數列表、元組(Tuple)風格以及柯里化風格,指出柯里化雖然在偏函數應用上顯得優雅,但其帶來的語法模糊性與調試困難,或許可以透過更明確的「佔位符」語法來替代。

社群觀點

Hacker News 的討論呈現出理論美感與工程實踐之間的拉鋸。支持柯里化的開發者認為,這不單是語法糖,而是函數式編程中「等式推理」與「無點風格」(Point-free style)的基石。他們指出,柯里化允許開發者在偏函數應用的中間步驟進行運算,例如在日誌框架中,可以根據配置層層過濾,若某一層級已停用日誌,後續步驟可直接回傳空操作(noop),這種效能優化在傳統參數列表下難以達成。此外,F# 的使用者強調,柯里化配合管道運算子(|>)能創造出極其流暢的代碼流,若改用顯式的佔位符語法,反而會破壞這種簡潔感。

然而,反對意見則聚焦於工程維護的痛點。許多評論者認為隱式柯里化是一種「反宣告式」的黑客手段,會導致嚴重的類型錯誤定位問題。在具有強大類型推導的語言中,若調用函數時漏掉一個參數,編譯器不會報錯,而是靜默地產生一個偏函數,這往往導致錯誤在代碼下游才爆發,增加調試成本。部分開發者直言,在商業軟體開發中,具名參數(Named Parameters)遠比位置參數或柯里化更具優勢,因為它消除了記憶參數順序的心理負擔。

有趣的是,討論中出現了一種折衷的共識:顯式的偏函數應用語法(如 Scala 的底線或作者建議的錢字號佔位符)可能比隱式柯里化更優越。這種方式保留了鏈式調用的靈活性,同時讓代碼意圖更加明確,讀者能一眼看出這是一個函數調用還是偏函數定義。此外,佔位符語法還解決了柯里化只能從第一個參數開始應用的限制,允許開發者自由固定中間或末尾的參數。一些新興語言如 Roc 或 Coalton 選擇放棄或限制柯里化,反映出函數式語言社群正逐漸從學術上的純粹性轉向更具防禦性的工程實踐。

延伸閱讀

在討論中,參與者提到了幾個值得關注的資源與語言實踐。Coalton 語言在其 0.2 版本中移除了柯里化,其官方部落格詳細說明了固定元數(Fixed Arity)對提升錯誤訊息品質的幫助。Roc 語言的常見問題集(FAQ)也針對為何不採用柯里化給出了設計考量。此外,Jonathan Warden 撰寫的《隱式柯里化與折疊應用》一文,提出了一種讓參數列表與柯里化風格在語義上等價的假設性語言特性。對於偏好佔位符語法的讀者,Scala 與 Virgil 語言中對底線符號的使用提供了現成的實踐參考。

https://emi-h.com/articles/a-case-against-currying.html