21.2 Macro hygiene

Displaying the code fragments inserted by the macro in underlined italics both helps to show exactly what the macro has done to our code, and draws attention to an important feature of Dylan macros — they are hygienic macros. A hygienic or referentially transparent macro system is one that prevents accidental collisions of macro variables with program variables of the same name. Consider the following macro, which is used to exchange the values of two variables:

define macro swap!
  { swap! (?place1:expression, ?place2:expression) }
 => { let value = ?place1;
      ?place1 := ?place2;
      ?place2 := value
     }
end macro swap!;

The local variable value is created by the macro. There is a possibility that this variable could conflict with another variable in the surrounding code. Consider what might happen if we were to expand swap!(value, x):

let value = value;
value := x;
x := value

With simple textual substitutions, swap! would have no effect in this case. Dylan's hygienic macros solve this problem by differentiating between the value introduced by the macro and any other value that might appear in the original code.

Comparison with C: Because C (and C++) macros are simply text substitutions performed by a preprocessor that has no understanding of the C language, they are inherently unhygienic. C macro writers reduce this problem by choosing unusual or unlikely names for local variables in their macros (such as _swap_temp_value), but even this workaround can be insufficient in complex macros. Dylan macros in effect automatically rename macro variables on each expansion to guarantee unique names.