Using clojure-contrib Generic Interfaces

Generic interfaces in clojure-contrib provides multimethods that you can implement for your custom data structures, which allows you to define various operations such as arithmetic, comparison etc.

( ns vector2d ( :use [clojure.contrib.types :only ( deftype )] [clojure.contrib.generic :only (root-type)]) ( :require [clojure.contrib.generic.arithmetic :as ga])) ( defstruct vector2d-struct :x :y ) ( deftype ::vector2d vector2d ( fn [x y] (struct vector2d-struct x y)) ( fn [v] (vals v))) (derive ::vector2d root-type) ( defmethod ga/+ [ ::vector2d ::vector2d ] [u v] ( let [[ux uy] (vals u) [vx vy] (vals v)] (vector2d ( ga /+ ux vx) ( ga /+ uy vy))))

The only problem is when you want to use it, you need to tell Clojure to not load the function from core but instead use multimethods from the generic interface.

( ns core ( :refer-clojure :exclude [+]) ( :use (clojure.contrib.generic [arithmetic :only [+]])) ( :refer vector2d)) (+ (vector2d 2 3) (vector2d 2 3))

Generic interface also contains collection operations as multimethods which allows you to implement operations such as assoc, conj, seq etc.