   (sequence-lexicoder (lexicoder (second config))))
 
 
+(extend-type SequenceLexicoder
+
+  Lexicoder
+
+  (lexicoder-config
+    [this]
+    [:seq (lexicoder-config (.element-coder this))])
+
+  (encode*
+    [this value]
+    (->> value
+         (map #(escape-bytes (encode* (.element-coder this) %)))
+         (join-bytes)))
+
+  (decode*
+    [this data offset len]
+    (->> (split-bytes data offset len)
+         (mapv #(let [udata (unescape-bytes %)]
+                  (decode* (.element-coder this) udata 0 (alength udata)))))))
+
+
 
 ;; ## Tuple Lexicoder
 
-(defrecord TupleLexicoder
-  [coders]
-
-  Lexicoder
-
-  (lexicoder-config
-    [_]
-    (vec (cons :tuple (map lexicoder-config coders))))
-
-  (encode*
-    [_ value]
-    (when (not= (count value) (count coders))
-      (throw (IllegalArgumentException.
-               (format "Cannot encode tuple which does not match lexicoder count %d: %s"
-                       (count coders) (pr-str value)))))
-    (join-bytes (mapv #(escape-bytes (encode* %1 %2)) coders value)))
-
-  (decode*
-    [_ data offset len]
-    (let [elements (split-bytes data offset len)]
-      (when (not= (count coders) (count elements))
-        (throw (IllegalArgumentException.
-                 (format "Cannot decode tuple which does not match lexicoder count %d: %s"
-                         (count coders) (pr-str elements)))))
-      (mapv #(let [udata (unescape-bytes %2)]
-               (decode* %1 udata 0 (alength udata)))
-            coders elements))))
-
-
-(alter-meta! #'->TupleLexicoder assoc :private true)
-(alter-meta! #'map->TupleLexicoder assoc :private true)
+(deftype TupleLexicoder [coders])
 
 
 (defn tuple-lexicoder

    (Instant/ofEpochMilli (decode* long-lexicoder data offset len))))


(alter-meta! #'->InstantLexicoder assoc :private true)
(alter-meta! #'map->InstantLexicoder assoc :private true)


(def instant-lexicoder
  "Lexicoder for instants in time."
  (->InstantLexicoder))


(defmethod lexicoder :instant
  [config]
  (when (config-params config)
    (throw (ex-info
             (str "Instant lexicoder config takes no parameters: " (pr-str config))
             {:config config})))
  instant-lexicoder)



;; ## Sequence Lexicoder

(defrecord SequenceLexicoder
  [element-coder]

  Lexicoder

  (lexicoder-config
    [_]
    [:seq (lexicoder-config element-coder)])

  (encode*
    [_ value]
    (->> value
         (map #(escape-bytes (encode* element-coder %)))
         (join-bytes)))

  (decode*
    [_ data offset len]
    (->> (split-bytes data offset len)
         (mapv #(let [udata (unescape-bytes %)]
                  (decode* element-coder udata 0 (alength udata)))))))


(alter-meta! #'->SequenceLexicoder assoc :private true)
(alter-meta! #'map->SequenceLexicoder assoc :private true)


(defn sequence-lexicoder

  (apply tuple-lexicoder (map lexicoder (rest config))))


(extend-type TupleLexicoder

  Lexicoder

  (lexicoder-config
    [this]
    (vec (cons :tuple (map lexicoder-config (.coders this)))))

  (encode*
    [this value]
    (when (not= (count (.coders this)) (count value))
      (throw (IllegalArgumentException.
               (format "Cannot encode tuple which does not match lexicoder count %d: %s"
                       (count (.coders this)) (pr-str value)))))
    (join-bytes (mapv #(escape-bytes (encode* %1 %2)) (.coders this) value)))

  (decode*
    [this data offset len]
    (let [elements (split-bytes data offset len)]
      (when (not= (count (.coders this)) (count elements))
        (throw (IllegalArgumentException.
                 (format "Cannot decode tuple which does not match lexicoder count %d: %s"
                         (count (.coders this)) (pr-str elements)))))
      (mapv #(let [udata (unescape-bytes %2)]
               (decode* %1 udata 0 (alength udata)))
            (.coders this) elements))))



;; ## Reverse Lexicoder

(deftype ReverseLexicoder [coder])


(defn reverse-lexicoder
  "Wraps the given lexicoder to reverse the ordering of keys encoded with it."
  [coder]
  (->ReverseLexicoder coder))


(ns-unmap *ns* '->ReverseLexicoder)


(defmethod lexicoder :reverse
  [config]
  (when (not= 1 (count (config-params config)))
    (throw (ex-info
             (str "Reverse lexicoder config takes exactly one parameter: " (pr-str config))
             {:config config})))
  (reverse-lexicoder (lexicoder (second config))))


(defn- flip-byte
  "Returns the inverse of a byte value, accounting for the sign bit."
