Currying

Čtu teď knížku Groovy for Domain-Specific Languages a zaujala mě tam technika, kterou jsem doposud neznal — currying. V krátkosti jde o transformaci funkce, která má více argumentů (nebo pole argumentů) tak, že může být zavolána jako řetěz funkcí s jedním argumentem. Zapsáno matematicky: g(y) = (y -> f(x,y)). Funkce g je “(z)kariovaná” (curried) verze funkce f.

Pojem currying je spojován hlavně se jménem matematika Haskella Curryho. Ano, je to ten Haskell, po kterém je pojmenován (čistě) funkcionální jazyk Haskell. Currying je vlastní v podstatě všem funkcionálním jazykům, za zmínku stojí speciálně Haskell a ML, kde všechny funkce mají přesně jeden argument, tj. jsou “kariované”. “Kariované” funkce by také měly jít použít/vytvořit ve všech jazycích, které podporují closures, namátkou:

No a jak vypadá currying konkrétně? V Groovy:

No a tenhle blog je o Clojure, takže jak to vypadá v Clojure?

V Clojure není potřeba syslit argumenty po jednom, ale dá se jich zadat víc naráz (1-n):

Závěrem, k čemu je vlastně currying dobrý? Kromě toho, že může zpřehlednit/zjednodušit funkce s mnoha argumenty (lambda kalkul v matematice), je hlavní výhoda použití v doplňování argumentů on-the-fly — doplním argumenty, které aktuálně znám a ostatní doplním, až budou k dispozici. Vzhledem k tomu, že Clojure je lazy-init, může být currying konvenující metoda.