   (:refer-clojure :exclude [type read float double long short byte bytes repeat])
   (:require [octet.buffer :as buffer]))
 
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Abstraction definition
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; --- Protocols
 
 (defprotocol ISpec
   "Basic abstraction for something that can be work like a Spec."

  "Abstraction for calculate size for dynamic specs."
  (size* [_ data] "Calculate the size in bytes of the object having a data."))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Composed Spec Types
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(deftype AssociativeSpec [data dict types]
  #?@(:clj

     (alter-meta! #'->AssociativeSpec assoc :private true)
     (alter-meta! #'->IndexedSpec assoc :private true)))

;; --- Spec Constructors

(defn- associative-spec
  [& params]
  (let [data (mapv vec (partition 2 params))
        dict (into {} data)
        types (map second data)]
    (AssociativeSpec. data dict types)))

(defn- indexed-spec
  [& types]
  (IndexedSpec. types))

(defn spec
  "Polymorphic constructor for Spec instances.

  Spec is a some kind of composition of arbitrary
