Search code examples
haskellclojureadt

What is required to implement an ADT in Clojure?


Assumption: I'm aware of the ADT libraries here. They're cool. Maybe they could be better.

There is a really interesting example of ADT's in Clojure here:

We define an ADT generator like this:

(defmacro data
  [adt-name equals-sign & constructors]
  `(do
     (defn ~(symbol (str adt-name "?")) [~'obj]
       (= ~(str adt-name) (adt-name ~'obj)))
     ~@(for [[type-name & fields]
             (filter (partial not= '(|))
                     (partition-by (partial = '|) constructors))]
         (apply (partial emit-constructor adt-name type-name)
                 fields))))

Given the Haskell example:

data Tree a = Empty
        | Leaf a
        | Node Tree Tree

Then we write the Clojure

(data Tree = Empty | Leaf value | Node left right)

Which is pretty cool.

Now I feel like there is something missing from matching up to the Haskell equivalent, but I can't quite put my finger on what it is.

My question is: What is required to implement an ADT in Clojure?


Solution

  • To implement ADT in clojure you're required to be brave and insistent.

    For the missing parts - I don't know what are you missing, but I know what I am missing usually.

    1) I want to authomatically get some foldX-function to perform conversion to Boehm encoding - a natural fold for this datatype.

    This, however, will require you to have user to specify which fields must refer to object of same type (left and right in your case).

    For instance, that function, written for your example type in haskell (God save the laziness!) will look like:

    foldTree :: a -> (v -> a) -> (a -> a -> a) -> Tree v -> a
    foldTree empty value node = go 
      where
        go tree =
          case tree of
            Empty    -> empty
            Value v  -> value v
            Node l r -> node (go l) (go r)
    

    This is done in Coq, as I know, and called "induction".

    2) I want to see predicates like isEmpty for all the branches. Seriously. The only language providing them is Pyret.

    3) For bonus points, I also want to have some ability to derive structural Equality, Ordering, to- and from-string conversion.

    ∞-1) To own my soul, you can also automatically generate lenses and prisms into all fields and branches accordingly.

    ∞) To prove your own strength, you can also generate ana-, para- and apomorphisms, since foldX is a already a catamorphism.