   Object
   (^String toString [_] (str name)))
 
-(defrecord ABC [name ^int version b-data c-data]
+(defrecord ABC [name version b-data c-data]
   Object
   (^String toString [_] (str name)))
 

;; a really clever impl might start lazy and become agressive during serialisation..
(defn- ^ABC join-abc [^A a ^B b ^C c]
  (->ABC
   (keyword (apply str (interpose "-" (list (name (:name a)) (name (:name b)) (name (:name c))))))
   (+ (* 1000 (:version a)) (* 100 (:version b)) (* 10 (:version c)))
   (:data b)
   (:data c)))

(deftest test-join-abc
  (is (= (->ABC :a1-b1-c1 0 "b-data" "c-data") 
	 (join-abc (->A :a1 0 :b :c)(->B :b1 0 :b "b-data")(->C :c1 0 :c "c-data")))))

(deftest test-permute

  (let [as (versioned-optimistic-map-model (str :as) :name :version >)
	bs (versioned-optimistic-map-model (str :bs) :name :version >)
	cs (versioned-optimistic-map-model (str :cs) :name :version >)
	joined-model (versioned-optimistic-map-model (str :joined) :name :version abc-more-recent-than?)
	join (join-model "join-model" [[as [:fk-b :fk-c] joined-model][bs :b][cs :c]] join-abc)
	view (test-view "test")
	a1 (->A :a1 0 :b :c)
