Hygienic macro

Of course, the problem can occur for program-defined functions in a similar way: The use site redefines user-defined-operator and hence changes the behavior of the macro.

Similar functions (usually named gensym as well) exist in many Lisp-like languages, including the widely implemented Common Lisp standard[4] and Elisp.

Unlike an unusual name, however, a read time uninterned symbol is used (denoted by the #: notation), for which it is impossible to occur outside of the macro, similar to gensym.

User code would have to reach inside the package using the double colon (::) notation to give itself permission to use the private symbol, for instance cool-macros::secret-sym.

Thus the Lisp package system provide a viable, complete solution to the macro hygiene problem, which can be regarded as an instance of name clashing.

For example, Scheme's let-syntax and define-syntax macro creation systems are hygienic, so the following Scheme implementation of my-unless will have the desired behavior: The hygienic macro processor responsible for transforming the patterns of the input form into an output form detects symbol clashes and resolves them by temporarily changing the names of symbols.

[8] Unlike the KFFD algorithm, syntactic closures require the programmer to explicitly specify the resolution of the scope of an identifier.

In 1993, Dybvig et al. introduced the syntax-case macro system, which uses an alternative representation of syntax and maintains hygiene automatically.

The term macro system can be ambiguous because, in the context of Scheme, it can refer to both a pattern-matching construct (e.g., syntax-rules) and a framework for representing and manipulating syntax (e.g., syntax-case, syntactic closures).

Syntax-rules is a high-level pattern matching facility that attempts to make macros easier to write.

For example, syntax-case macros can specify side-conditions on its pattern matching rules via arbitrary Scheme functions.

Alternatively, a macro writer can choose not to use the pattern matching frontend and manipulate the syntax directly.

Using the datum->syntax function, syntax-case macros can also intentionally capture identifiers, thus breaking hygiene.

The swap examples from above are shown here using a syntactic closure and explicit renaming implementation respectively: Hygienic macros offer safety and referential transparency at the expense of making intentional variable capture less straight-forward.