que tienen la opción de implementar directamente un Protocolo en el cuerpo de un defrecord en lugar de utilizar extender protocolo/extensión de tipo¿Cuál es el razonamiento detrás de los registros cerrados en Clojure?
(defprotocol Fly
(fly [this]))
(defrecord Bird [name]
Fly
(fly [this] (format "%s flies" name)))
=>(fly (Bird. "crow"))
"crow flies"
Si ahora intenta reemplazar el protocolo de la mosca, me sale un error
(extend-type Bird
Fly
(fly [this] (format "%s flies away (:name this)))
class user.Bird already directly implements interface user.Fly for protocol:#'user/Fly
Por otro lado, si en lugar utilizo extender de tipo inicialmente
(defrecord Dragon [color])
(extend-type Dragon
Fly
(fly [this] (format "%s dragon flies" (:color this))))
=>(fly (Dragon. "Red"))
"Red dragon flies"
que pueda entonces el la función de marcha "override"
(extend-type Dragon
Fly
(fly [this] (format "%s dragon flies away" (:color this))))
=>(fly (Dragon. "Blue"))
"Blue dragon flies away"
Mi pregunta es, ¿por qué no permitir la extensión en ambos casos? ¿Es esto una limitación de JVM debido a la relación de Registro < -> Clase o hay un caso de uso para un protocolo no invalidable?
Excelente respuesta, Michal. Aclara una gran confusión sobre el tema. –
Gracias que tenía mucho sentido, y el hilo vinculado ayudó especialmente. – grinnbearit
@BG: ¡Gracias! Todo es mérito de Clojurebane of Confusion +5 (por ejemplo, el grupo de Clojure) y Haskellplate of Enlightenment +5 (por ejemplo, el café Haskell). ;-) @grinnbearit: ¡Feliz de escuchar eso! –