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.įor example, in the program-defined function redefinition example, the my-unless macro can reside in its own package, where user-defined-operator is a private symbol in that package. Such usage can be thus diagnosed by the implementation as erroneous. Furthermore the ANSI Common Lisp standard categorizes redefining standard functions and operators, globally or locally, as invoking undefined behavior. At that point, the issue of accidental lack of hygiene is moot. 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. The symbol will not accidentally occur in user code. Using packages such as in Common Lisp, the macro simply uses a private symbol from the package in which the macro is defined. 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. This is similar to obfuscation in that a single name is shared by multiple expansions of the same macro. However, gensym, macro facilities, and standard library functions are sufficient to embed hygienic macros in an unhygienic language. Similar functions (usually named gensym as well) exist in many Lisp-like languages, including the widely implemented Common Lisp standard and Elisp.Īlthough symbol creation solves the variable shadowing issue, it does not directly solve the issue of function redefinition. This method was used in MacLisp, where a function named gensym could be used to generate a new symbol name. The responsibility for choosing to use this feature within the body of a macro definition is left to the programmer. The language processing system ensures that this never clashes with another name or location in the execution environment. In some programming languages, it is possible for a new variable name, or symbol, to be generated and bound to a temporary location. Specifically, using the macro INCI on a variable INCIa is going to fail in the same way that the original macro failed on a variable a. The variables used inside the macro and those in the rest of the program have to be kept in sync by the programmer. The problem is solved for the current program, but this solution is not robust. Until a variable named INCIa is created, this solution produces the correct output: In C, this problem can be illustrated by the following fragment: In programming languages that have non-hygienic macro systems, it is possible for existing variable bindings to be hidden from a macro by variable bindings that are created during its expansion. The term "hygiene" was coined in Kohlbecker et al.'s 1986 paper that introduced hygienic macro expansion, inspired by terminology used in mathematics. Hygienic macros are a programmatic solution to the capture problem that is integrated into the macro expander. Macro writers would use language features that would generate unique identifiers (e.g., gensym) or use obfuscated identifiers to avoid the problem. The general problem of accidental capture was well known in the Lisp community before the introduction of hygienic macros. They are a feature of programming languages such as Scheme, Dylan, Rust, Nim, and Julia. In computer science, hygienic macros are macros whose expansion is guaranteed not to cause the accidental capture of identifiers. ( November 2016) ( Learn how and when to remove this template message) Please help improve it to make it understandable to non-experts, without removing the technical details. This article may be too technical for most readers to understand.
0 Comments
Leave a Reply. |