 (defmacro assoc-if
   "Create mapping from keys to values in map if test returns true."
   [map test & kvs]
-  (let [assoc (cons 'assoc (cons map kvs))]
-    `(if ~test
-       ~assoc
-       ~map)))
+  `(if ~test
+     (assoc ~map ~@kvs)
+     ~map))
 
 (defn assoc-or
   "Create mapping from each key to val in map only if existing val is nil."

    (mapcat #(deref %)
            (map #(future (map f %)) (slice n coll)))))

(defn assoc-in!
  "Associates a value in a nested associative structure, where ks is a sequence of keys
  and v is the new value and returns a new nested structure. The associative structure
  can have transients in it, but if any levels do not exist, non-transient hash-maps will
  be created."
  [m [k & ks] v]
  (let [assoc (if (instance? clojure.lang.ITransientCollection m) assoc! assoc)]
    (if ks
      (assoc m k (assoc-in! (get m k) ks v))
      (assoc m k v))))

(defn update-in!
  "'Updates' a value in a nested associative structure, where ks is a sequence of keys and
  f is a function that will take the old value and any supplied args and return the new
  value, and returns a new nested structure. The associative structure can have transients
  in it, but if any levels do not exist, non-transient hash-maps will be created."
  [m [k & ks] f & args]
  (let [assoc (if (instance? clojure.lang.ITransientCollection m) assoc! assoc)]
    (if ks
      (assoc m k (apply update-in! (get m k) ks f args))
      (assoc m k (apply f (get m k) args)))))

(defn thrush
  "Takes the first argument and applies the remaining arguments to it as functions from left to right.

  [f]
  (.addShutdownHook
   (Runtime/getRuntime)
   (Thread. f)))

(defn- parse-opt [default opts arg]
  (let [m re-matches, key (comp keyword str)]
