How about compiling a closure tree ?

;; very basic example follows

(defn make+ [param1 param2]
  (fn [environement]
    (+ (param1 environement) (param2 environement))))

(defn make* [param1 param2]
  (fn [environement]
    (* (param1 environement) (param2 environement))))

(defn make-variable [variable-name]
  (fn [environement]
    (environement variable-name)))

(defn make-number [number]
  (fn [environement]
    number))

(def *mappings* {'+ make+
         '* make*})

(defn my-compile [expression]
  (cond
   (seq? expression) ((*mappings* (first expression))
              (my-compile (nth expression 1))
              (my-compile (nth expression 2)))
   (number? expression) (make-number expression)
   (symbol? expression) (make-variable expression)))

(defn test-it []
  (let [compiled (my-compile '(+ (* a 2) (+ b a)))]
    (map compiled (list {'a 0 'b 0}
            {'a 1 'b 2}
            {'a 2 'b 1}
            {'a 4 'b 5}))))

cara.data.expressions=> (time (dotimes [a 1000000] (test-it)))
"Elapsed time: 3160.461437 msecs"   

That's for 1 million compilations and 4 times as many executions.
There's no problem with garbage collection.

I beleive this "compiler pattern" is pretty common.

Sacha


--~--~---------~--~----~------------~-------~--~----~
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
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to