Frage Warum hat Clojure 5 Möglichkeiten, eine Klasse statt nur einer zu definieren?


Clojure hat gen-class, reify, proxy und auch deftype und defrecord, um neue klassenähnliche Datentypen zu definieren. Für eine Sprache, die syntaktische Einfachheit schätzt und unnötige Komplexität verabscheut, erscheint sie als eine Abweichung. Könnte jemand erklären, warum es so ist? Konnte Common Lisp-Stil defclass ausgereicht haben?


75
2017-08-22 02:03


Ursprung


Antworten:


Dies ist eine Mischung aus drei verschiedenen Faktoren:

  1. Das besondere Typsystem des jvm
  2. Die Notwendigkeit einer leicht unterschiedlichen Semantik für verschiedene Anwendungsfälle beim Definieren von Typen
  3. Die Tatsache, dass einige von ihnen früher entwickelt wurden, und einige später, als sich die Sprache weiterentwickelt hat.

Betrachten wir zunächst einmal, was diese tun. Ableittyp und Gen-Klasse sind insofern ähnlich, als sie beide eine benannte Klasse für die Kompilierung vor dem Zeitpunkt definieren. Gen-Klasse kam zuerst, gefolgt von DefType in Clojure 1.2. DefType ist bevorzugt und hat bessere Leistungsmerkmale, ist aber restriktiver. Eine deftype-Klasse kann einer Schnittstelle entsprechen, aber nicht von einer anderen Klasse erben.

Verdinglichen und Proxy werden beide zur dynamischen Erstellung einer Instanz einer anonymen Klasse zur Laufzeit verwendet. Proxy kam zuerst, und in clojure 1.2 kam defify mit deftype und defrecord zusammen. Bevorzugt ist, wie im Deftype, die Semantik nicht zu restriktiv.

Das wirft die Frage auf, warum sowohl DefText als auch Defrecord, da sie zur gleichen Zeit erschienen, eine ähnliche Rolle spielen. Für die meisten Zwecke werden wir Defrecord verwenden wollen: Es hat all die verschiedenen clojure Güte, die wir kennen und lieben, Folgerichtigkeit und so weiter. Deftype ist als Baustein auf niedriger Ebene für die Implementierung anderer Datenstrukturen vorgesehen. Es enthält nicht die regulären Clojure-Interfaces, aber es hat die Option von veränderbaren Feldern (obwohl dies nicht der Standard ist).

Für weitere Informationen lesen Sie:

Die clojure.org Datatypes Seite

Der Google-Gruppen-Thread, in dem deftype und retify eingeführt wurden


82
2017-08-22 03:20



Die kurze Antwort ist, dass sie alle unterschiedliche und nützliche Zwecke haben. Die Komplexität ist auf die Notwendigkeit zurückzuführen, effektiv mit verschiedenen Funktionen der zugrunde liegenden JVM zusammenzuarbeiten.

Wenn du brauche kein Java Interop dann sind 99% der Zeit am besten, wenn Sie entweder mit der Defrecord oder einer einfachen Clojure Map bleiben.

  • Verwenden Sie defrecord, wenn Sie Protokolle verwenden möchten
  • Ansonsten ist eine normale Clojure-Map wahrscheinlich die einfachste und verständlichste

Wenn Ihre Anforderungen komplexer sind, ist das folgende Flussdiagramm ein gutes Werkzeug, um zu erklären, warum Sie eine dieser Optionen für die anderen auswählen sollten:

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

Flowchart for choosing the right clojure type definition form


44
2017-08-22 09:34