Hi, I'm not sure it nicer, but anyway...
It follows a similar approach as Cedric: pass down unbox info and collect up constants info. However I use the form itself to carry additional information. YMMV. One could also put info into meta. (derive ::let ::recursive) (derive ::fn ::recursive) (def call #(%2 %1)) (defn maybe [pred f form & args] (if (pred form) (apply f form args) form)) (defn update-children [form f & args] (update-in form [:children] (partial map #(apply f % args)))) (defn recursive? [form] (isa? (:op form) ::recursive)) (defn processor [pre-fns post-fns] (fn this [form] (let [form (reduce call form pre-fns) form (maybe recursive? update-children form this)] (reduce call form post-fns)))) (defmulti set-unbox :op) (defmethod set-unbox :default [form] form) (defmethod set-unbox ::recursive [{:as form :keys [unbox op]}] (update-in form [:children] (partial map #(assoc % :unbox (or unbox (= op ::let)))))) (defmulti collect-constants :op) (defmethod collect-constants :default [form] (assoc form :constants #{})) (defmethod collect-constants ::constant [form] (assoc form :constants #{(:form form)})) (defmethod collect-constants ::recursive [{:as form :keys [children]}] (assoc form :constants (reduce into #{} (map :constants children)))) ((processor [set-unbox] [collect-constants]) {:op ::fn :children [{:op ::let :children [{:op ::constant :form 1}]}]}) ; => {:constants #{1}, :op :user/fn, :children ({:constants #{1}, :unbox false, :op :user/let, :children ({:constants #{1}, :unbox true, :op :user/constant, :form 1})})} Otherwise untested. Sincerely Meikel -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en