3 ms·
I don't really understand how the Clojure syntax-quote somehow prevents name-capturing any more than that of Common Lisp does(except for the foo# gensym shortcu
by ekiru 17y ago
I don't really understand how the Clojure syntax-quote somehow prevents name-capturing any more than that of Common Lisp does(except for the foo# gensym shortcut). The Common Lisp backquote automatically qualifies symbols in the current package. In fact, the Common Lisp reader does that for all symbols used without a qualified namespace. It would be terribly painful to write in any language with a mandatory package system which could not infer the package to which a symbol belongs in this way.
What makes Clojure's backquote so much more resilient against variable capture than Common Lisp's?
- apgwoz 17y agoI've often wondered this. Last week rich hickey mentioned this at clojure NYC, and they only things he mentioned were the fully qualifying namespaces (which resolves to the original package it was defined in) and the auto gensyms. I assume this is enough in most cases and the auto gensyms take care of the rest. I don't think I'd trust namespace rewriting by itself though.
- fogus 17y agoRight, and one without the other doesn't do the trick. You need both auto-gensyms and namespace resolution to ensure hygiene in Clojure macros (cleanly at least). On the other hand as lg mentioned you can intentionally capture using the pattern described. So you get the best of both worlds with the stipulation that the case of intentional capture is a bit more cumbersome.
- lg 17y agoCL-USER> (progn (defmacro foo () `(let ((bar 1)) bar)) (foo)) 1 user=> (do (defmacro foo [] `(let [bar 1] bar)) (foo)) java.lang.Exception: Can't let qualified name: clojure.core/bar EDIT: sorry if that was cryptic, see Lisp will let you say (let ((cl-user::bar 1)) cl-user::bar) but clojure won't let you do (let [clojure.core/bar 1] clojure.core/bar) You can't use fully-qualified names that way. So namespace resolution in expansions prevents capture. If you really want capture, you can do ~'bar to protect it from resolution. Well I hope that's still true, lotrepls doesn't seem to like it :(