Это смесь трех разных факторов:
- Особая система типов jvm
- Потребность в немного другой семантике для разных случаев использования при определении типов
- Тот факт, что некоторые из них были разработаны ранее, а некоторые позже, по мере развития языка.
Итак, давайте сначала рассмотрим, что они делают. deftype и gen-class похожи в том, что они оба определяют именованный класс для досрочной компиляции. На первом месте был Gen-класс, за которым последовал deftype в версии 1.2. Deftype является предпочтительным и имеет лучшие рабочие характеристики, но является более ограничительным. Класс deftype может соответствовать интерфейсу, но не может наследоваться от другого класса.
Reify и proxy используются для динамического создания экземпляра анонимного класса во время выполнения. Прокси появился первым, reify вышел вместе с deftype и defrecord в версии 1.2. Reify предпочтителен, как и deftype, где семантика не слишком ограничительна.
Это оставляет вопрос о том, почему и deftype, и defrecord, поскольку они появились в одно и то же время, и играют сходную роль. Для большинства целей мы захотим использовать defrecord: он обладает всеми различными добродетелями clojure, которые мы знаем и любим, sequability и так далее. Deftype предназначен для использования в качестве низкоуровневого стандартного блока для реализации других структур данных. Он не включает в себя обычные интерфейсы clojure, но у него есть опция изменяемых полей (хотя это не значение по умолчанию).
Для дальнейшего чтения ознакомьтесь:
Страница типов данных clojure.org
Тема группы Google, где были введены deftype и reify