81 votes

Pourquoi Clojure propose-t-il 5 façons de définir une classe au lieu d'une seule ?

Clojure dispose de gen-class, reify, proxy et également deftype et defrecord pour définir de nouveaux types de données de type classe. Pour un langage qui valorise la simplicité syntaxique et abhorre la complexité inutile, cela semble être une aberration. Quelqu'un pourrait-il expliquer pourquoi il en est ainsi ? Un defclass de style Common Lisp aurait-il pu suffire ?

87voto

Rob Lachlan Points 7880

C'est un mélange de trois facteurs différents :

  1. Le système de type particulier de la jvm
  2. La nécessité d'une sémantique légèrement différente pour les différents cas d'utilisation lors de la définition des types.
  3. Le fait que certains d'entre eux ont été développés plus tôt, et d'autres plus tard, au fur et à mesure de l'évolution de la langue.

Voyons d'abord ce qu'ils font. deftype y classe générique sont similaires en ce qu'elles définissent toutes deux une classe nommée pour une compilation anticipée. Gen-class est venu en premier, suivi par deftype dans clojure 1.2. Deftype est préféré, et a de meilleures caractéristiques de performance, mais est plus restrictif. Une classe deftype peut se conformer à une interface, mais ne peut pas hériter d'une autre classe.

Réifier y proxy sont toutes deux utilisées pour créer dynamiquement une instance d'une classe anonyme au moment de l'exécution. Proxy est arrivé en premier, reify est arrivé avec deftype et defrecord dans clojure 1.2. Reify est préféré, tout comme deftype, lorsque la sémantique n'est pas trop restrictive.

Cela laisse la question de savoir pourquoi deftype et defrecord, puisqu'ils sont apparus en même temps, et ont un rôle similaire. Dans la plupart des cas, nous voudrons utiliser defrecord : il possède toutes les qualités de Clojure que nous connaissons et aimons, la séquentialité et ainsi de suite. Deftype est destiné à être utilisé comme un bloc de construction de bas niveau pour l'implémentation d'autres structures de données. Il n'inclut pas les interfaces clojure habituelles, mais il a l'option de champs mutables (bien que ce ne soit pas le cas par défaut).

Pour en savoir plus, consultez le site :

La page clojure.org datatypes

Le fil de discussion du groupe Google où deftype et reify ont été présentés.

50voto

mikera Points 63056

La réponse courte est qu'ils ont tous des objectifs différents et utiles. La complexité est due à la nécessité d'interopérer efficacement avec les différentes fonctionnalités de la JVM sous-jacente.

Si vous n'ont pas besoin d'interopérabilité avec Java alors, dans 99 % des cas, il est préférable de s'en tenir à defrecord ou à une simple carte Clojure.

  • Utilisez defrecord si vous voulez utiliser des protocoles
  • Sinon, une carte Clojure ordinaire est probablement la plus simple et la plus compréhensible.

Si vos besoins sont plus complexes, l'organigramme suivant est un excellent outil pour expliquer pourquoi vous choisissez l'une de ces options plutôt que les autres :

http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/

Flowchart for choosing the right clojure type definition form

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X