Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can someone explain the concept of 'hygiene' to me (I'm a scheme programmer)?

So... I'm new to scheme r6rs, and am learning macros. Can somebody explain to me what is meant by 'hygiene'?

Thanks in advance.

like image 711
Cam Avatar asked Jun 09 '10 22:06

Cam


4 Answers

Hygiene is often used in the context of macros. A hygienic macro doesn't use variable names that can risk interfering with the code under expansion. Here is an example. Let's say we want to define the or special form with a macro. Intuitively,

(or a b c ... d) would expand to something like (let ((tmp a)) (if tmp a (or b c ... d))). (I am omitting the empty (or) case for simplicity.)

Now, if the name tmp was actually added in the code like in the above sketched expansion, it would be not hygienic, and bad because it might interfere with another variable with the same name. Say, we wanted to evaluate

(let ((tmp 1)) (or #f tmp))

Using our intuitive expansion, this would become

(let ((tmp 1)) (let ((tmp #f)) (if tmp (or tmp)))

The tmp from the macro shadows the outer-most tmp, and so the result is #f instead of 1.

Now, if the macro was hygienic (and in Scheme, it's automatically the case when using syntax-rules), then instead of using the name tmp for the expansion, you would use a symbol that is guaranteed not to appear anywhere else in the code. You can use gensym in Common Lisp.

Paul Graham's On Lisp has advanced material on macros.

like image 130
namin Avatar answered Oct 19 '22 05:10

namin


If you imagine that a macro is simply expanded into the place where it is used, then you can also imagine that if you use a variable a in your macro, there might already be a variable a defined at the place where that macro is used.

This is not the a that you want!

A macro system in which something like this cannot happen, is called hygienic.

There are several ways to deal with this problem. One way is simply to use very long, very cryptic, very unpredictable variable names in your macros.

A slightly more refined version of this is the gensym approach used by some other macro systems: instead of you, the programmer coming up with a very long, very cryptic, very unpredictable variable name, you can call the gensym function which generates a very long, very cryptic, very unpredictable and unique variable name for you.

And like I said, in a hygienic macro system, such collisions cannot happen in the first place. How to make a macro system hygienic is an interesting question in itself, and the Scheme community has spent several decades on this question, and they keep coming up with better and better ways to do it.

like image 35
Jörg W Mittag Avatar answered Oct 19 '22 03:10

Jörg W Mittag


I'm so glad to know that this language is still being used! Hygienic code is code that when injected (via a macro) does not cause conflicts with existing variables.

There is lots of good information on Wikipedia about this: http://en.wikipedia.org/wiki/Hygienic_macro

like image 3
sholsapp Avatar answered Oct 19 '22 03:10

sholsapp


Here's what I found. Explaining what it means is another matter altogether!

http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-1.html#node_toc_node_sec_12.1

like image 2
JYelton Avatar answered Oct 19 '22 04:10

JYelton