        (println ~msg)
        result#)))
 
-(t/ann log-io (t/All [x y ...] [String [y ... y -> x] -> [y ... y -> x]]))
+(t/ann log-io (t/All [a x y ...]
+                [String [a y ... y -> x] -> [a (t/U nil (t/I (t/CountRange 1) (t/HSeq (y ... y)))) -> x]]))
 (defn log-io
   "Log function inputs and outputs by wrapping an function f."
   [msg f]
-  (fn [& args]
-    (let [result (apply f args)]
+    (fn [a & args]
+    (let [result (apply f a args)]
       (println (format "(%s %s)=>%s" msg (str args) (str result)))
       result)))
 

    [arg [sym] condition form else-form]
    (arg-if- 'clojure.core/-> arg sym condition form else-form)))

(t/ann vec-match? [(t/Vec t/Any) (t/Vec t/Any) -> Boolean])
(defn vec-match?
  [test-expr expr]
  (let [arg-match? (t/fn [[test-term term] :- (t/I (t/Vec t/Any) (t/ExactCount 2))] :- Boolean

    (if (empty? coll)
          coll
          (let [x  (first coll)
                xs (next coll)
                y  (first vcoll)
                ys (next vcoll)]
                  (if (pred x)
                            (cons (f x y) (if (empty? xs) [] (fill-missing pred f ys xs)))
                            (cons x (if (empty? xs) [] (fill-missing pred f vcoll xs)))))))

(t/ann fn-in (t/All[x y]
               [[t/Any x -> t/Any] (t/Vec t/Any) x -> y]))
(defn fn-in
  "Applies a function to a value in a nested associative structure and an input value.
   ks sequence of keys and v is the second arguement to f. The nested value will be
