     (when (< i (-count prim))
       (cons (-nth prim i) (prim-seq prim (inc i))))))
 
-(extend-protocol ISeqable
-  string
-  (-seq [string] (prim-seq string 0))
-  
-  array
-  (-seq [array] (array-seq array 0)))
-
-(deftype List [meta first rest count]
-  IWithMeta
-  (-with-meta [coll meta] (List. meta first rest count))
-
-  IMeta
-  (-meta [coll] meta)
-
-  ISeq
-  (-first [coll] first)
-  (-rest [coll] (if (nil? rest) (EmptyList. meta) rest))
-
-  IStack
-  (-peek [coll] first)
-  (-pop [coll] (-rest coll))
-
-  ICollection
-  (-conj [coll o] (List. meta o coll (inc count)))
-
-  IEmptyableCollection
-  (-iempty [coll] coll)
-
-  ISequential
-  IEquiv
-  (-equiv [coll other] (equiv-sequential coll other))
-
-  IHash
-  (-hash [coll] (hash-coll coll))
-
-  ISeqable
-  (-seq [coll] coll)
-
-  ICounted
-  (-count [coll] count)
-
-  IPrintable
-  (-pr-seq [coll opts] (pr-sequential pr-seq "(" " " ")" opts coll)))
-
-(deftype EmptyList [meta]
-  IWithMeta
-  (-with-meta [coll meta] (EmptyList. meta))
-
-  IMeta
-  (-meta [coll] meta)
-
-  ISeq
-  (-first [coll] nil)
-  (-rest [coll] nil)
-
-  IStack
-  (-peek [coll] nil)
-  (-pop [coll] #_(throw "Can't pop empty list"))
-
-  ICollection
-  (-conj [coll o] (List. meta o nil 1))
-
-  IEmptyableCollection
-  (-iempty [coll] coll)
-
-  ISequential
-  IEquiv
-  (-equiv [coll other] (equiv-sequential coll other))
-
-  IHash
-  (-hash [coll] (hash-coll coll))
-
-  ISeqable
-  (-seq [coll] nil)
-
-  ICounted
-  (-count [coll] 0)
-
-  IPrintable
-  (-pr-seq [coll opts] (list "()")))
-
-(set! cljs.core.List/EMPTY (EmptyList. nil))
-
-(defn list [& items]
-  (reduce conj () (reverse items)))
-
-(deftype Cons [meta first rest]
-  IWithMeta
-  (-with-meta [coll meta] (Cons. meta first rest))
-
-  IMeta
-  (-meta [coll] meta)
-
-  ISeq
-  (-first [coll] first)
-  (-rest [coll] (if (nil? rest) () rest))
-
-  ICollection
-  (-conj [coll o] (Cons. nil o coll))
-
-  IEmptyableCollection
-  (-iempty [coll] (EmptyList. nil))
-
-  ISequential
-  IEquiv
-  (-equiv [coll other] (equiv-sequential coll other))
-
-  IHash
-  (-hash [coll] (hash-coll coll))
-
-  ISeqable
-  (-seq [coll] coll)
-
-  IPrintable
-  (-pr-seq [coll opts] (pr-sequential pr-seq "(" " " ")" opts coll)))
-
-(extend-protocol ICounted
-  string
-  (-count [s] (.length s))
-
-  array
-  (-count [a] (.length a)))
-
-(extend-protocol IIndexed
-  string
-  (-nth
-    ([string n]
-       (if (< n (-count string)) (.charAt string n)))
-    ([string n not-found]
-       (if (< n (-count string)) (.charAt string n)
-           not-found)))
-
-  array
-  (-nth
-    ([array n]
-       (if (< n (-count array)) (aget array n)))
-    ([array n not_found]
-       (if (< n (-count array)) (aget array n)
-           not_found))))
-
-(extend-protocol ILookup
-  string
-  (-lookup
-    ([string k]
-       (-nth string k))
-    ([string k not_found]
-       (-nth string k not_found)))
-  
-  array
-  (-lookup
-    ([array k]
-       (-nth array k))
-    ([array k not-found]
-       (-nth array k not-found))))
-
 (defn- ci-reduce
   "Accepts any collection which satisfies the ICount and IIndexed protocols and
 reduces them without incurring seq initialization"

  (assert (= (hash-map :foo 5)
             (assoc (cljs.core.ObjMap. nil (array) (js-obj)) :foo 5)))

  (assert (= "[1 {:a 2, :b 42} #<Array [3, 4]>]"
             (pr-str [1 {:a 2 :b 42} (array 3 4)])))
  (assert (= "symbol\"'string"
             (pr-str (str 'symbol \" \' "string"))))
  (assert (not (= "one" "two")))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; equality ;;;;;;;;;;;;;;


(defn = [x y]
  (if (satisfies? IEquiv x)
