Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Newby question - Hygenic macros vs. other kinds

15 views
Skip to first unread message

Martin B. Pomije

unread,
May 17, 1998, 3:00:00 AM5/17/98
to

I'm teaching myself CL and Scheme. I was reading the Scheme language
definition (Revised^4 Report on the Algorithmic Language Scheme) when I
came across the phrase "hygenic macro", somehow implying that CL is
"unclean" in this regard. What makes makes Scheme macros such pure
things?
Please cc any replies to me.
--
*********************************************
Semi-encrypted email address: m_b_p_o_m_i_j_e_ a_t_ i_n_a_v_ d_o_t_
n_e_t_
All non-solicited commercial email will be billed $1,000.

Barry Margolin

unread,
May 18, 1998, 3:00:00 AM5/18/98
to

In article <355FB5F6...@inav.net>,

Martin B. Pomije <mbpo...@inav.net> wrote:
>I'm teaching myself CL and Scheme. I was reading the Scheme language
>definition (Revised^4 Report on the Algorithmic Language Scheme) when I
>came across the phrase "hygenic macro", somehow implying that CL is
>"unclean" in this regard. What makes makes Scheme macros such pure
>things?

In CL, macros are simply source-to-source transformations. If the
expansion introduces new variables, they're visible to any code that came
from the subforms in the macro invocation, and they can hide its own
variables. Consider the following:

(let ((i 4))
(repeat 10 (print i)))

You would expect this to print 10 lines containing "4". But suppose the
definition of REPEAT were:

(defmacro repeat (n-times &body body)
`(dotimes (i ,n-times)
,@body))

The expansion of the original form then becomes:

(let ((i 4))
(dotimes (i 10)
(print i)))

Which will print the numbers from 0 to 9, not what was intended.
Basically, unhygienic macros violate lexical scoping, since some variables
used internally within the macro are apparent to the user.

In CL, it's the programmer's responsibility to work around this. Common
techniques are using GENSYM:

(defmacro repeat (n-times &body body)
(let ((var (gensym)))
`(dotimes (,var ,n-times)
,@body)))

or function-passing:

(defun repeat-helper (n-times thunk)
(dotimes (i n-times)
(funcall thunk)))

(defmacro repeat (n-times &body body)
`(repeat-helper ,n-times (lambda () ,@body)))

>Semi-encrypted email address: m_b_p_o_m_i_j_e_ a_t_ i_n_a_v_ d_o_t_
>n_e_t_

Why do you encrypt your address in the text when the correct address is in
your header? Most address harvesters look in the header.

--
Barry Margolin, bar...@bbnplanet.com
GTE Internetworking, Powered by BBN, Cambridge, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.

Erik Naggum

unread,
May 18, 1998, 3:00:00 AM5/18/98
to Martin B. Pomije

* Martin B. Pomije

| I'm teaching myself CL and Scheme. I was reading the Scheme language
| definition (Revised^4 Report on the Algorithmic Language Scheme) when I
| came across the phrase "hygenic macro", somehow implying that CL is
| "unclean" in this regard. What makes makes Scheme macros such pure
| things?

Barry Margolin has answered with the reasons why you need it, but Kent
Pitman posted an article some time ago (1998-03-20) that shed light on
why this is a serious problem in Scheme and no big deal in Common Lisp.
it's message-id is <sfwiupa...@world.std.com>¹ in reply to my
question in <30993159...@naggum.no>². (you should be able to find
them on Dejanews or other USENET search engines, too.)

in brief, Scheme has only one namespace, and the first element of an
s-expression is evaluated to obtain the function to call or the special
form. this means you run into a serious danger of using _functions_ that
have their meanings changed by the body of code into which the macro
expansion is "inserted". clearly, this is bad, but it's a design choice
in Scheme with many qualities, so they had to find a way to deal with it.
the way I see it (after reading and appreciating Kent's article) is that
Scheme allows a level of pollution that is unhealthy and then they need a
way to clean up, or things get "unhygienic" around them. Common Lisp is
hygienic _enough_ on its own since it doesn't pollute its namespaces to
begin with, and therefore need a simpler mechanism for variable capture.

#:Erik
-------
¹ src.naggum.no/lisp/news/sfwiupa...@world.std.com (http/ftp)
² src.naggum.no/lisp/news/30993159...@naggum.no (http/ftp)
--
"Where do you want to go to jail today?"
-- U.S. Justice Department's Windows 98 slogan

0 new messages