      nil (sorted-set)
 
      (['quote val] :seq) (sorted-set)
-
-     (['quasiquote val] :seq) (quasiquote-free-vars val)
 
      (['lambda params & body] :seq)
      (apply disj (free-vars body) (cons *lambda-name* (remove special-token? params)))

   :else
   form))

(declare free-vars)
(defn quasiquote-free-vars
  [form]
  (if (list-like? form)
    (loop [f form
           frees (sorted-set)]
      (if (seq f)
        (if (#{'unquote 'unquote-splicing} (first f))
          (reduce into frees (map free-vars (rest f)))
          (recur (next f) (into frees (quasiquote-free-vars (first f)))))
        frees))
    (sorted-set)))

(defn free-vars
  "Returns a sorted-set of free symbols in the given form. Sorting is
  arbitrary, but consistent."

      #{'define 'define-macro} :>> (partial sanitize-define env)

      #{'define-class*} form

      #{:jvm} :>> (fn [[_ & insns]]
                    (list* :jvm (map (partial sanitize-jvm env) insns)))
