Č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:
def spicy = { first, second, third -> println "I like food with $first, $second and $third." } def curry = spicy.curry("curry") def moreCurry = curry.curry("curry") def curryAndChilli = moreCurry.curry("chilli") curryAndChilli.call() // prints: // I like food with curry, curry and chilli.No a tenhle blog je o Clojure, takže jak to vypadá v Clojure?
(defn spicy [first second third] (println "I like food with" first "," second "and" third ".")) (def curry (partial spicy "curry")) (def more-curry (partial curry "curry")) (def curry-and-chilli (partial more-curry "chilli")) (curry-and-chilli) ; I like food with curry , curry and chilli .V Clojure není potřeba syslit argumenty po jednom, ale dá se jich zadat víc naráz (1-n):
(defn spicy [first second third] (println "I like food with" first "," second "and" third ".")) (def curry-and-chilli (partial spicy "curry" "curry" "chilli")) (curry-and-chilli) ; I like food with curry , curry and chilli .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.
Žádné komentáře:
Okomentovat