                                   inner-value-2
                                   (let [inner-value-1 (gensym "inner-value-1_")]
                                     `(let [~inner-value-1 (get ~value-1 ~index)]
-                                       ~(diff* inner-schema inner-value-1 inner-value-2))))]))
+                                       ~(diff inner-schema inner-value-1 inner-value-2))))]))
                   (into {})))
          (decorate-constructor constructor)
          (decorate-common schema value-1 value-2))))
 
-(defmethod diff* :optional [[_ _ inner-schema] value-1 value-2]
+(defmethod diff :optional [[_ _ inner-schema] value-1 value-2]
   `(if (and ~value-1 ~value-2)
-     ~(diff* inner-schema value-1 value-2)
+     ~(diff inner-schema value-1 value-2)
      ~value-2))
 
-(defmethod diff* :multi [[_ {:keys [diff]} selector multi-cases] value-1 value-2]
+(defmethod diff :multi [[_ {:keys [diff]} selector multi-cases] value-1 value-2]
   (let [selector-fn (gensym "selector-fn_")
         case-1      (gensym "case-1_")
         case-2      (gensym "case-2_")]

                       inner-value-2
                       (let [inner-value-1 (gensym "inner-value-1_")]
                         `(let [~inner-value-1 (get ~value-1 ~index)]
                            ~(diff* inner-schema inner-value-1 inner-value-2)))))
                   disjoined-2))
         (decorate-common schema value-1 value-2))))

(defmethod diff* :record [schema value-1 value-2]
  (let [[_ {:keys [constructor diff]} :as schema] (expand-record schema (:schemas *config*))
        disjoined-2 (disj-indexed schema value-2)]
    (->> `(let [~@(mapcat (juxt :symbol :inner-value) disjoined-2)]

    (custom? schema)   :custom
    :else              :non-diffable))

(defmulti diff diff-dispatch)

(defmethod diff :vector [[_ _ inner-schema :as schema] value-1 value-2]
  (let [index         (gensym "index_")
        inner-value-1 (gensym "inner-value-1_")
        inner-value-2 (gensym "inner-value-2_")]
    (->> `(vec (map-indexed (fn [~index ~inner-value-2]
                              (if-let [~inner-value-1 (get ~value-1 ~index)]
                                ~(diff inner-schema inner-value-1 inner-value-2)
                                ~inner-value-2))
                            ~value-2))
         (decorate-common schema value-1 value-2))))

(defmethod diff :map [[_ {:keys [sorted-by]} _ val-schema :as schema] value-1 value-2]
  (let [key    (gensym "key_")
        val-1  (gensym "val-1_")
        val-2  (gensym "val-2_")]
    (->> `(map (fn [[~key ~val-2]]
                 [~key (if-let [~val-1 (get ~value-1 ~key)]
                         ~(diff val-schema val-1 val-2)
                         ~val-2)])
               ~value-2)
         (decorate-map sorted-by)
         (decorate-common schema value-1 value-2))))

(defmethod diff :tuple [[_ {:keys [diff]} :as schema] value-1 value-2]
  (let [disjoined-2 (disj-indexed schema value-2)]
    (->> `(let [~@(mapcat (juxt :symbol :inner-value) disjoined-2)]
            ~(mapv (fn [{index :index inner-schema :inner-schema inner-value-2 :symbol}]
