Это сочетание трех разных факторов:
- Система конкретных типов 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
proxy
иногда предпочтительнее, потому что он позволяет изменять методы во время выполнения. (например, The Joy of Clojure , 2-е изд. предполагает, что это может быть удобно для изменения обратных вызовов в веб-обработчике.)Короткий ответ: все они имеют разные и полезные цели. Сложность связана с необходимостью эффективного взаимодействия с различными функциями базовой JVM.
Если вам не нужно взаимодействие с Java, то в 99% случаев лучше придерживаться либо defrecord, либо простой карты Clojure.
Если ваши потребности более сложные, то следующая блок-схема - отличный инструмент для объяснения, почему вы бы предпочли один из этих вариантов другим:
http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/
источник