 
   "
   [term & {:as env}]
-  (ev term env))
+  (ev term #{} env))
 
 (defn ?
   "funcall, the counit of product-exponential adjunction"
   ([& terms]
-   (as-> (ev (Beta. terms) {}) term
-     (if (beta? term)
-       (ev (Form. term (apply clojure.set/union (map fv terms))) {})
-       term)))
+   (let [terms (for [t terms] (if (var? t) (Form. t #{t}) t))
+         vars (apply clojure.set/union (map :vars (filter form? terms)))]
+     (ev (Beta. terms) vars {})))
   ([]))
 
 (defn %
   "forall"
   ([term & args] ; currently args can only be vars
-   (-> (Forall. term (vec args))
-       (ev {})
-       (Form. (reduce disj (if (form? term) (:vars term) #{}) args))
-       (ev {})))
+   (ev (Forall. term (vec args))
+       (reduce disj (if (form? term) (:vars term) #{}) args)
+       {}))
   ([term] term))
 
 (defn !

              num (count body)]
          (case (compare (count args) num)
            ;; curry
            1 (-> (ev term env)
                  (Forall. (subvec args num))
                  (Form. (reduce disj vars (keys env))))
            ;; beta-reduce
            0 (as-> (ev term env) term
                (if (expr? term)
                  (Form. term (reduce disj vars (keys env)))
                  term))
            (throw (ex-info "arity error" {:args args :vals body}))))
        (Beta. sexp))))

  Forall
  (ev [{:keys [term args]} env]
    (let [env  (reduce dissoc env args) ; evalutes term if necessary
          term (cond-> term (seq env) (ev env))]
      (if (and (form? term) (forall? (:expr term)))
        (as-> (:expr term) expr ; uncurries
          (assoc expr :args (into args (:args expr))))
        (Forall. term args))))

  Object
  (fv [this] #{})
  (ev [this env] this)

  nil
  (fv [this] #{})
  (ev [this env] this))

(defn ?%
  "takes a term and interleaving var-terms and values, (partially)

  )

;; todo
;; - fix (keys env)
;; - test how to replace var using env
