Questo è un mix di tre diversi fattori:
- Il particolare sistema di tipi di jvm
- La necessità di una semantica leggermente diversa per diversi casi d'uso durante la definizione dei tipi
- Il fatto che alcuni di questi siano stati sviluppati prima e altri in seguito, man mano che il linguaggio si è evoluto.
Quindi prima, consideriamo cosa fanno. deftype e gen-class sono simili in quanto entrambi definiscono una classe denominata per la compilazione anticipata. La classe Gen è arrivata prima, seguita da deftype in clojure 1.2. Deftype è preferito e ha caratteristiche di prestazione migliori, ma è più restrittivo. Una classe deftype può essere conforme a un'interfaccia, ma non può ereditare da un'altra classe.
Reify e proxy vengono entrambi utilizzati per creare dinamicamente un'istanza di una classe anonima in fase di esecuzione. Il proxy è arrivato prima, reify è arrivato con deftype e defrecord in clojure 1.2. Reify è preferito, proprio come deftype, dove la semantica non è troppo restrittiva.
Ciò lascia la domanda sul perché sia deftype che defrecord, poiché sono apparsi contemporaneamente e hanno un ruolo simile. Per la maggior parte degli scopi, vorremo utilizzare defrecord: ha tutte le varie bontà di clojure che conosciamo e amiamo, sequability e così via. Deftype è concepito per essere utilizzato come blocco predefinito di basso livello per l'implementazione di altre strutture di dati. Non include le normali interfacce clojure, ma ha l'opzione di campi modificabili (sebbene questa non sia l'impostazione predefinita).
Per ulteriori letture controlla:
La pagina dei tipi di dati di clojure.org
Il thread del gruppo Google in cui sono stati introdotti deftype e reify