(ns nst1)
(deftype T1 [f1])
(println "nst1" (ns-publics 'nst1))

(ns nst2)
(defprotocol P2 (foo [this]))
(deftype T2 [f2] :as this P2 (foo [] this))
(println "nst2" (ns-publics 'nst2))

(ns nst3)
(println "nst3 using nst2" (nst2/foo (nst2/T2 1)))

(ns nst4)
(deftype T4 [f4] :as this nst2/P2 (foo [] this))
(println "nst4 implementing nst2" (nst2/foo (T4 4)))

(ns nst5)
(defprotocol P5 (foo [this]))
(ns nst6)
(deftype T6 [f6] :as this nst2/P2 nst5/P5 (foo [] this)) ; note 'collision'.
(let [t6 (T6 6)] (println "ns/P.fn collision" (nst2/foo t6) (nst5/foo t6)))

(ns nst7)
(deftype T7 [f7]) ; note no "as this".
(extend ::T7 nst2/P2 {:foo (fn [this] this)})
(println "extend 7/2" (nst2/foo (T7 7)))

(ns nst8)
(deftype T8 [f8])
(extend ::T8
	nst2/P2 {:foo (fn [this] (str "P2 f8=" (:f8 this)))}
	nst5/P5 {:foo (fn [this] (str "P5 f8=" (:f8 this)))})
(println "extend 8/2" (nst2/foo (T8 8)))
(println "extend 8/5" (nst5/foo (T8 8)))

(ns nst9)
(deftype T9 [f9])
(ns nst10)
(extend ::nst9/T9 nst2/P2 {:foo (fn [this] this)})
(println "extend 10-9/2" (nst2/foo (nst9/T9 9)))
