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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---