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 difference
is 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


Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to