Macros often have associated auxiliary identifiers (sometimes called
keywords or reserved words, although both terms are
problematic in Racket). For example, cond has else;
class has public, private, etc;
unit has import and export.
The fundamental question is what constitutes a use of an auxiliary
identifier, and there are two reasonable answers: symbolic
equality and referential equality. By symbolic equality I
mean, for example, that any identifier written with exactly the
letters else is accepted as an else auxiliary form. By
referential equality I mean any identifier that refers to
(using the standard notions of binding, environments, etc) the binding
identified as the else binding.
Danny Yoo had an interesting question on the plt-scheme mailing list
recently. At first it seemed like your standard non-hygienic, “I want
this to mean something in here” macro question. I used to group
macros into three levels of “hygienicness”: the hygienic ones, the
ones that are morally hygienic in that the names they introduce are
based on their input, and the totally non-hygienic ones that have a
fixed name that they stick into the program. An example of the middle
set is define-struct, and an example of the third set is a
loop construct that binds the name yield in its body.
The third class used to offend me from a purist’s (semi-purist?)
perspective. But it’s a very reasonable thing to want to do. Consider
the class macro and the names it uses to do interesting
things: super, public, field,
init, and so on. It depends on those particular names.