Cover by Brian Carper, Christophe Grand, Chas Emerick

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

O'Reilly logo

Hygiene

Traditionally, one of the biggest potential problems in writing macros is generating code that interacts with other code improperly. Clojure has safeguards in place that other Lisps lack, but there is still potential for error.

Code generated by a macro will often be embedded in other code, and often will have user-defined code embedded within it. In either case, some set of symbols is likely already bound to values by the user of the macro. It’s possible for a macro to set up its own bindings that collide with those of the outer or inner context of the macro-users code, which can create bugs that are very difficult to identify. Macros that avoid these sorts of issues are called hygienic macros.

Consider a macro with an implementation that requires a let-bound value. The name we choose is irrelevant to the user of our macro and should be invisible to him, but we do have to choose some name. Naively, we might try x:

(defmacro unhygienic
      [& body]
      `(let [x :oops]
         ~@body))
;= #'user/unhygenic
(unhygienic (println "x:" x))
;= #<CompilerException java.lang.RuntimeException:
;=   Can't let qualified name: user/x, compiling:(NO_SOURCE_PATH:1)>

Clojure is smart enough not to let this code compile. As we explored in quote Versus syntax-quote, all bare symbols are namespace-qualified within a syntax-quoted form. We can see the impact in this case if we check the expansion of our macro:

(macroexpand-1 `(unhygienic (println "x:" x))) ;= (clojure.core/let [user/x :oops] ;= (clojure.core/println ...

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required