 
 (defn keyword->symbol [k] (-> k name symbol))
 
-(defn collect-dependencies
+#_(defn collect-dependencies
   "Collect all the dependencies of an environment"
   [tree]
   (walk/postwalk

        :else node))
    tree))

(defn compile-eval-expr
  "Compile the expression in optimal code"
  [tree symbol-env]
  (walk/postwalk
    (fn [node]
      (cond
        (keyword? node) `(~node ~symbol-env)
        (vector? node) `(~(first node) ~@(rest node))
        :else node))
    tree))

(defprotocol IEvalExpr
  (eval-expr [this] "Evaluate the expression")



;; --------------------------------------------------------
;; Example 7: Macros can be used at the requirement level:
;; - Expression your business
;; - Get powerful code for it
;;
;; Phase 1: Factorize some common used patterns
;; - tree transformation of collect dependencies
;; - tree transformation of evaluate with env
;; => Factorize into tree morphism
;;
;; Phase 2: Generating some code based on data structure
;;
;; Here we define a computation in terms of variables
;; - We produce a record for this computation (type)
