Hi Rock, Am 20.11.2008 um 20:58 schrieb Rock:
Peter Seibel's Practical Common Lisp:
You might want to look at Stuart Halloway's "PCL->Clojure" series: http://blog.thinkrelevance.com/2008/09/16/pcl-clojure
(defmacro with-gensyms [[& names] form]
`(let ~(apply vector (loop [n names result []]
(if (nil? n)
result
(recur (rest n)
(conj result (first n) `(gensym))))))
~form))
- [[& names]] is actually the same as [names]. The only differenceis that the former will give an error when you don't pass a collection.
However that, you will get anyway later on...
- (apply vector ...) can also be done via (vec ...).
- The loop can also be done with reduce or mapcat.
(defmacro with-gensyms
[names form]
`(let ~(vec (mapcat (fn [n] [n `(gensym)]) names))
~form))
or with reduce
(defmacro with-gensyms
[names form]
`(let ~(vec (reduce #(conj %1 %2 `(gensym)) [] names))
~form))
or just like that...
(defmacro with-gensyms
[names form]
`(let ~(vec (interleave names (repeat `(gensym))))
~form))
So, many ways lead to Rome. :) I think the last one is maybe
the most elegant.
I think for Clojure, this is not really interesting, because
you have the # notation to create automatic gen-syms on the
fly. This already gets you very far. gensym is only in special
cases necessary.
(defmacro foo [x] (with-gensyms [xx] `(let [~xx ~x] ~xx)))
vs.
(defmacro foo [x] `(let [x# ~x] x#))
Sincerely
Meikel
smime.p7s
Description: S/MIME cryptographic signature
