On 07/15/2011 05:40 AM, Mark Engelberg wrote:
I would like to better understand how Clojure's mitigation strategy is
insufficient.  Since Eli's document is all about the while macro,
let's look at Clojure's while macro.

(defmacro while [test&  body]
   `(loop []
      (when ~test
        ~@body
        (recur))))


This doesn't work at the REPL as such since clojure.core/while cannot be
redefined (unlike in Racket) but let's assume you typed my-while or
went through the namespace magic to have while refer to something you can 
change.

What is broken about this?  I tried breaking it in a way comparable to
what Eli did in his document, e.g., binding every keyword/variable in
the macro to something non-sensical, but it didn't break.  Here's the
comparable Clojure code to what Eli did:
(def x (atom 2))
(let [loop 5 when 2 test 4 body 3 recur 4]
            (while (<  @x 10)
              (println @x)
              (reset! x (inc @x))))

Quasi-quote is magical in Clojure and replaces symbols in the pattern by
their equivalents in the global namespace.
Compare:

user=> `while
clojure.core/while
user=> 'while
while

So the macro is probably fine as-is, but this relies
on you having stayed within the confines of the quasi-quote sublanguage.

As soon as you start manipulating code using quote and cons you run back
in all the usual issues.

BTW, this "feature" appears to be quite undocumented, I found it
out by experimentation.
So it is anybody's guess what happens if you have macro-expanders calling
functions in different namespaces which use quasiquote, or even macros
which expand into macros with multiple levels of quasi-quote.

Stephan
_________________________________________________
 For list-related administrative tasks:
 http://lists.racket-lang.org/listinfo/users

Reply via email to