     [expr]
     "Produce a `parsable` clojure expression from `expr`
  in optional lexical environement `env`."))
-            
+
+
+(defprotocol FreeVars
+  "A protocol for fetching the set of free variables."
+  (free-vars
+   [expr kind]
+   "Return a set of the free variables of `expr` according 
+to their kind: :product, :forall or :open."))
+
 ;;{
 ;;
 ;; ## Lambda-terms

           (parser/parse-list-check-arity expr 2)
           (let [[var etype] (second expr)
                 type (parse etype env)
                 body (parse (nth expr 2) (acons var 'lambda env))]
             (if (not (symbol? var))
               (throw (Exception. (str "Abstraction variable is not a symbol: " var))))
             (mk-abstraction var type body))))

           (parser/parse-list-check-arity expr 2)
           (let [[var etype] (second expr)
                 type (parse etype env)
                 body (parse (nth expr 2) (acons var :forall env))]
             (if (not (symbol? var))
               (throw (Exception. (str "Product variable is not a symbol: " var))))
             (mk-product var type body))))
