Если вы еще не пробовали мультиметоды , они могут быть ближе к тому, что вы ищете.
Определение:
(defrecord Person [first middle last])
(defmulti get-name class)
(defmethod get-name Person [person] (:first person))
Использование:
(def captain (Person. "James" "T" "Kirk"))
(get-name captain)
Выбранная реализация мультиметода основана на функции диспетчеризации в defmulti (функция, которая принимает аргументы, переданные функции и возвращает значение диспетчеризации). Обычно «класс» - это функция отправки, как здесь, для отправки по типу. Мультиметоды поддерживают несколько независимых иерархий типа ad-hoc или на основе Java, реализации по умолчанию и т. Д.
В общем, я думаю, что, возможно, вы захотите сделать шаг назад и подумать, действительно ли вам нужны протоколы или мультиметоды. Вы, кажется, пытаетесь "сделать OO" в Clojure. Хотя аспекты ОО (такие как полиморфизм) велики, возможно, вам следует попробовать по-другому взглянуть на вашу проблему. Например, в только что приведенном примере нет убедительной причины (пока) для полиморфной реализации get-name. Почему бы просто не сказать:
(defn get-name [x] (:first x))
Вам вообще нужна запись о человеке? Будет ли достаточно простой карты? Иногда ответы да, иногда нет.
Обычно Clojure не обеспечивает наследование классов. Вы, конечно, можете создать эквивалент (даже с протоколами), если вы действительно этого хотите, но в целом я считаю, что есть другие, более эффективные способы решения этой проблемы в Clojure.