mixing-hygienic-and-unhygienic-macros


The short answer: DON'T DO THIS.

It's perfectly reasonable to use exclusively unhygienic macros based on gensym. It's also fine to use only hygieneic macros. In either case one might have read hygiene-versus-gensym and decided to try out a few macros from the other camp, or maybe you've just run across a macro you want to use written in the opposite style and decided to use it as is. This is a recipe for disaster.

The problem is simply that defmacro strips hygienic info in order to be able to process raw sexps. As soon as you have a hygienic macro which outputs a call to an unhygienic macro, the inner body which is almost certainly referring to hygienically renamed variables will be stripped down to unhygienic symbols, and break.

Note this refers to mixing macros from the two different systems (specifically throwing a defmacro into a hygienic system). It's perfectly possible to write deliberately unhygienic macros in a hygienic system without "breaking" more than what was intended (see also when-not-to-use-auxiliary-syntax).

But in general have to choose one approach or the other and stick to it. There are a few special cases when you might be able to get around this and perform some limited mixing, as described below.

Top-level unhygienic macros

If your defmacro is restricted to the top-level, and only written directly (not intended for meta-macro expansion), the above problem of the defmacro stripping enclosing hygiene info will not occur. This does assume the macro system handles the top-level hygiene correctly (not confusing modules) - your mileage may vary.

Smart defmacro

Many people want a "smart" defmacro which doesn't lose hygiene information. Because it has to work with raw sexps this isn't really possible in general. However, some hygienic macro systems (notably explicit-renaming) work directly on normal sexps, so there is no stripping to perform. Most often this does require the defmacro to use an identifier (instead of symbol) abstraction, but it would be possible to use gensyms with attached properties to avoid adding a new identifier type.