 
 (defn ixes-of [vector values]
   (into-array (map #(ix-of vector %) values)))
+
+;; EXPRS
+
+(defn expr->fun [vars expr]
+  (apply js/Function (conj (vec vars) (str "return " expr ";"))))
 
 ;; PATTERNS
 

  ((pattern->deconstructor (->eg 'a 'a 'a)) (->eg "a" "a" "a"))
  )

;; EXPRS

(defn expr->fun [vars expr]
  (apply js/Function (conj (vec vars) (str "return " expr ";"))))

;; CLAUSES


(defn add-clause [plan nodes vars clause]
  (condp = (type clause)
    Recall (let [{:keys [memory pattern]} clause
                 [plan node-a] (add-flow plan (FilterMap. (memory->nodes memory) (ShapeFun. (.-shape pattern))))
                 [plan node-b] (add-flow plan (FilterMap. [node-a] (DeconstructorFun. pattern)))]
             [plan [node-b] (pattern->vars pattern)])
    Compute (let [{:keys [pattern]} clause]
              (condp = (.-shape pattern)
                Let (when (every? (set vars) (:vars pattern))
                      (let [funlike (if (contains? (set vars) (:name pattern))
                                      (WhenFun. vars (str "cljs.core.equals(" (:name pattern) "," (:expr pattern) ")"))
                                      (LetFun. vars (:expr pattern)))
                            [plan node] (add-flow plan (->FilterMap nodes funlike))]
                        [plan [node] (conj vars (:name pattern))]))
                When (when (every? (set vars) (:vars pattern))
                       (let [[plan node] (add-flow plan (->FilterMap nodes (WhenFun. vars (:expr pattern))))]
                         [plan [node] vars]))))
    Output (let [{:keys [memory pattern]} clause
                 _ (assert (every? (set vars) (pattern->vars pattern)))
                 [plan output-node] (add-flow plan (FilterMap. nodes (ConstructorFun. vars pattern)))
                 plan (add-output plan output-node memory)]
             [plan nodes vars])))

