blushing in the sky

everyone is uptight / so come on, night

Is syntax-rules unhygienic?

The following code doesn’t look like it should be possible:

(define break 'undefined)

(let ((i 0))
  (loop (set! i (+ i 1))
           (display i)
           (when (>= i 5)
                      (break #f))))

> 12345#f

Loop is a regular syntax-rules macro, which means it’s required to be “hygienic” and “referentially transparent”—writing (break #f) should expand and evaluate to ('undefined #f), and cause an error!

What’s happened is that loop takes advantage of a very clever trick described by Al Petrofsky and Oleg Kiselyov, where it uses an auxiliary macro to search for occurrences of an identifier (e.g., break), for which it provides an arbitrary binding (e.g., to an escape continuation).

Of course, while this result probably isn’t expected, there isn’t anything actually unhygienic about syntax-rules macros. Knowing that the loop macro is possible, though, shows that it’s important to think about what this notion of macro “hygiene” really is (Herman and Wand, 2008), and to think about how we can use hygienic macros safely and effectively (Herman and Van Horn, 2008).

I think the work that these guys are doing in this area is exciting, and am looking forward to reading and experimenting and hopefully learning a lot more about all of it, especially as this semester goes on.

— 1 month ago
#macros