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