Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Clojure have 5 ways to define a class instead of just one?

Clojure has gen-class, reify, proxy and also deftype and defrecord to define new class-like datatypes. For a language that values syntactic simplicity and abhors unnecessary complexity, it seems like an aberration. Could someone explain why it is so? Could Common Lisp-style defclass have sufficed?

like image 466
Salil Avatar asked Aug 22 '11 02:08

Salil


People also ask

What does Gen class do in Clojure?

The generated class automatically defines all of the non-private methods of its superclasses/interfaces. This parameter can be used to specify the signatures of additional methods of the generated class.

Is clojure interoperable with Java?

Clojure solved this new language library problem by running on the JVM and having interoperability with Java classes. When you use Clojure, you can use Java classes and Java libraries. Clojure builds on the strength of the production-hardened and tested JVM and existing Java libraries.

What is Defrecord Clojure?

Clojure allows you to create records, which are custom, maplike data types. They're maplike in that they associate keys with values, you can look up their values the same way you can with maps, and they're immutable like maps.

How do you call a method in Clojure?

You can call a static method using (ClassName/methodName arguments) . However class is not a static method, it's a java keyword and you don't need it in clojure. To get the Class object associated with the String class, just use String . Save this answer.


1 Answers

This is a mix of three different factors:

  1. The particular type system of the jvm
  2. The need for slightly different semantics for different use cases when defining types
  3. The fact that some of these were developed earlier, and some later, as the language has evolved.

So first, let's consider what these do. deftype and gen-class are similar in that they both define a named class for ahead-of-time compilation. Gen-class came first, followed by deftype in clojure 1.2. Deftype is preferred, and has better performance characteristics, but is more restrictive. A deftype class can conform to an interface, but cannot inherit from another class.

Reify and proxy are both used to dynamically create an instance of an anonymous class at runtime. Proxy came first, reify came along with deftype and defrecord in clojure 1.2. Reify is preferred, just as deftype is, where the semantics are not too restrictive.

That leaves the question of why both deftype and defrecord, since they appeared at the same time, and have a similar role. For most purposes, we will want to use defrecord: it has all the various clojure goodness that we know and love, sequability and so forth. Deftype is intended for use as a low level building block for the implementation of other datastructures. It doesn't include the regular clojure interfaces, but it does have the option of mutable fields (though this isn't the default).

For further reading check out:

The clojure.org datatypes page

The google group thread where deftype and reify were introduced

like image 100
Rob Lachlan Avatar answered Sep 19 '22 06:09

Rob Lachlan