Hm, zrovna před pár dny jsem podobnou věc ukazoval ve svém blogu (na konkurenčním) serveru pro Perl 6, ale neznal jsem terminologii, tak jsem mluvil o kontextu a vynucení kontextu a uvedl jsem, že mi to připomíná polymorfismus :)
Lze např. pro number to zapsat i nějak takto
(defmethod heading Number
[value]
(heading (str value))
tedy z ní volat tu verzi pro String?
Tak to je pěkná náhoda. Já to napsal hlavně jako reakci na tu recenzi (resp. ne přímo na ni, protože v knížce se multimetody přelítnou v jedné jediné sekci), ale na diskuzi pod článkem.
Nicméně ta úprava bude fungovat podle očekávání:
(defmethod heading Number [val] (heading (str "*** " val " ***")))
Potom v REPLu:
user=> (heading nil) ----------------- nothing ----------------- user=> (heading 42) ----------------- *** 42 *** ----------------- user=> (heading "Zdravime wambu!") ----------------- Zdravime wambu! -----------------
Já jsem rád, že se tu tento článek objevil, protože jsem měl pocit, že tato v Perlu běžná věc je tak trochu v ostatních jazycích tabu. Jsou přímo v jazyce Clojure zabudované funkce, které by parametrický polymorfismus využívali, resp. jak je to běžné? (Ono vlastně jde vidět v první verzi, že funkce write automaticky číslo převede na znak pomocí ASCII, což je právě tento princip.)
Popravdě v základní knihovně je to použito minimálně a zrovna pro výstupní funkce (modul pretty-writer a instant). Tam je to asi nejvíc potřeba, protože print/println musí zvládnout vypsat hodnoty různých typů, teď se dívám, že to umí i Date, DateTime, Timestamp atd.
Osobně jsem to použil jen několikrát, ale když nad tím přemýšlím, tak bych tak mohl vyřešit dispatch handlerů HTTP požadavků. Teď tam totiž mám něco takového:
(condp = [method (get-api-command request uri)] [:get "/info"] (rest-api/info-handler request (get-hostname)) [:get "/job-list"] (rest-api/get-job-list-handler request) (rest-api/unknown-call-handler uri method)))
A přesně toto by šlo řešit deklarativně přes multimetody a ne imperativně rozeskokem :)