У меня есть возможность непосредственного внедрения протокола в тело defrecord вместо использования ext-protocol/extend-type
(defprotocol Fly
(fly [this]))
(defrecord Bird [name]
Fly
(fly [this] (format "%s flies" name)))
=>(fly (Bird. "crow"))
"crow flies"
Если я сейчас попытаюсь переопределить протокол Fly, я получаю сообщение об ошибке
(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
С другой стороны, если вместо этого я использую начальный тип
(defrecord Dragon [color])
(extend-type Dragon
Fly
(fly [this] (format "%s dragon flies" (:color this))))
=>(fly (Dragon. "Red"))
"Red dragon flies"
Затем я могу "переопределить" функцию fly
(extend-type Dragon
Fly
(fly [this] (format "%s dragon flies away" (:color this))))
=>(fly (Dragon. "Blue"))
"Blue dragon flies away"
Мой вопрос: почему бы не разрешить расширение в обоих случаях? Является ли это ограничением JVM из-за отношения Record ↔ Class или существует прецедент для неперехвачиваемого протокола?