conceptos-multiple-dispatch-multimethods-en-clojure-lisp
MultiMethods en un lenguaje funcional (clojure)
Primero definimos la “herencia”:
(derive ::artesano ::trabajador)
(derive ::zapatero ::trabajador)
(derive ::cuero ::material)
(derive ::goma ::material)
Declaramos ahora el multimethod usando la función especial defmulti y luego definimos cada implementación según los parámetros
(defmulti trabajar (fn [x y] [x y]))
(defmethod trabajar [::artesano ::cuero] [t m] "Hice un llaverito!")
(defmethod trabajar [::artesano ::goma] [t m] (str "Trabajo con: " m))
(defmethod trabajar [::zapatero ::cuero] [t m] "Hice un mocasin!")
(defmethod trabajar [::zapatero ::goma] [t m] "Hice una sandalia!")
(defmethod trabajar [::trabajador ::material] [t m] "Trabajador no sabe que hacer con material!")
Y ahora ya podemos invocar esta función a ver qué pasa:
user=> (trabajar ::artesano ::cuero)
"Hice un llaverito!"
user=> (trabajar ::zapatero ::cuero)
"Hice un mocasin!"
Ahora invoquémoslo con una variable, en lugar de usar directamente los objetos (symbols).
user=> (def trabajador ::artesano) // definimos la variable 'trabajador' como el symbol 'artesano'
#'user/trabajador`
user=> trabajador // a ver qué tiene trabajador ?....
:user/artesano` // bien.. tiene artesano
user=> (**trabajar** trabajador ::goma) // invocamos ahora trabajar con la variable
"Trabajo con: :user/goma"` // bien, se ejecutó el método de artesano + goma.