Esta é uma mistura de três fatores diferentes:
- O sistema de tipo específico do jvm
- A necessidade de semânticas ligeiramente diferentes para diferentes casos de uso ao definir tipos
- O fato de que alguns deles foram desenvolvidos mais cedo, e alguns mais tarde, conforme a linguagem evoluiu.
Então, primeiro, vamos considerar o que eles fazem. deftype e gen-class são semelhantes no sentido de que ambos definem uma classe nomeada para compilação antecipada. A classe Gen veio primeiro, seguida por deftype no clojure 1.2. Deftype é o preferido e tem melhores características de desempenho, mas é mais restritivo. Uma classe deftype pode estar em conformidade com uma interface, mas não pode herdar de outra classe.
Reify e proxy são usados para criar dinamicamente uma instância de uma classe anônima em tempo de execução. Proxy veio primeiro, reify veio junto com deftype e defrecord no clojure 1.2. Reify é preferido, assim como deftype, onde a semântica não é muito restritiva.
Isso deixa a questão de por que tanto deftype quanto defrecord, uma vez que apareceram ao mesmo tempo e têm uma função semelhante. Para a maioria dos propósitos, queremos usar defrecord: ele tem todas as várias qualidades de clojure que conhecemos e amamos, sequibilidade e assim por diante. Deftype deve ser usado como um bloco de construção de baixo nível para a implementação de outras estruturas de dados. Não inclui as interfaces regulares de clojure, mas tem a opção de campos mutáveis (embora este não seja o padrão).
Para ler mais, confira:
A página de tipos de dados clojure.org
O tópico do grupo do Google em que deftype e reify foram introduzidos
proxy
às vezes é preferível porque permite a modificação de métodos em tempo de execução. (por exemplo, The Joy of Clojure , 2ª ed. sugere que isso pode ser útil para modificar callbacks em um gerenciador da web.)A resposta curta é que todos eles têm finalidades diferentes e úteis. A complexidade se deve à necessidade de interoperar efetivamente com diferentes recursos da JVM subjacente.
Se você não precisa de nenhuma interoperabilidade Java , em 99% do tempo é melhor usar o defrecord ou um mapa Clojure simples.
Se suas necessidades são mais complexas, o fluxograma a seguir é uma ótima ferramenta para explicar por que você escolheria uma dessas opções em vez das outras:
http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/
fonte