Hygenic macros 
Author Message
 Hygenic macros

Several times in comp.lang.dylan I have seen the term
"hygenic macros", most recently by Scott Fahlman. While
the name is somewhat suggestive of the intended meaning,
I have never seen it defined or explained. Any takers?

Am I correct in guessing that traditional lisp macros
are not considered hygenic?

And that traditional c "macros" are not considered macros?

Jim Goodwin



Tue, 01 Apr 1997 22:53:36 GMT  
 Hygenic macros

Quote:
(Jim W Goodwin) writes:

|> Several times in comp.lang.dylan I have seen the term
|> "hygienic macros", most recently by Scott Fahlman.
|> I have never seen it defined or explained. Any takers?

Having just read the Scheme report (R4RS) I think I know
what they are.

Hygienic macros are macros that make it impossible (or
at least hard) to introduce scoping errors.  Take the
following C macro:

#define SWAP(x, y) { int t; t = x; x = y; y = t; }

This macro will work fine until someone writes SWAP(t, u).
With hygienic macros, variables are conceptually renamed
so that these conflicts go away.

|> Am I correct in guessing that traditional lisp macros
|> are not considered hygenic?

Indeed they are not; however, a careful programmer
can avoid writing `unhygienic' macros by generating
unique variable names whenever there is potential for
conflict.

|> And that traditional c "macros" are not considered macros?

I wouldn't say that.  It's a matter of terminology.   ---Luigi



Wed, 02 Apr 1997 06:33:31 GMT  
 Hygenic macros

Quote:
>Several times in comp.lang.dylan I have seen the term
>"hygenic macros", most recently by Scott Fahlman. While
>the name is somewhat suggestive of the intended meaning,
>I have never seen it defined or explained. Any takers?

Non-hygienic macros can violate lexical scoping of identifiers.  If the
macro expansion introduces a variable binding that uses the same identifier
as one that the code already uses, it may shadow its bindings.  For
instance, the macro (OR form1 form2) might expand into:

        (let ((temp form1))
          (if temp temp
              form2))

But suppose the program already has a variable named TEMP, e.g.

(let ((temp (something)))
  ...
  (or (something-else) (+ temp 3)))

This will be rewritten as

(let ((temp (something)))
  ...
  (let ((temp (something-else)))
    (if temp temp
        (+ temp 3))))

In this case, the last line will return the wrong value, because it will be
using the inner binding of TEMP established by the macro, rather than the
outer binding that came from the original code.

Quote:
>Am I correct in guessing that traditional lisp macros
>are not considered hygenic?

Yes.  The usual work-around for macro hygiene is to use gensyms for
local variables introduced by the macro.

The problem of non-hygienic macros, and a suggested solution, is described
in the paper "Hygienic Macro Expansion" by Kohlbecker, Friedman, Felleisen,
and Duba, in the Proceedings of the 1986 ACM Conference on Lisp and
Functional Programming.

Quote:
>And that traditional c "macros" are not considered macros?

"Macro" is a very broad term, which covers a wide variety of
source-to-source transformations.  Unfortunately, this means that both Lisp
macros and C macros can validly claim that they are macros.
--

Barry Margolin
BBN Internet Services Corp.



Wed, 02 Apr 1997 07:20:41 GMT  
 Hygenic macros

Quote:

> |> Am I correct in guessing that traditional lisp macros
> |> are not considered hygenic?

> Indeed they are not; however, a careful programmer
> can avoid writing `unhygienic' macros by generating
> unique variable names whenever there is potential for
> conflict.

Howdy,
        Lisp macros are too much maligned. I mean, how "carefull"
does one really have to be??  I just use GENSYM to generate unique
symbol names and integrate them into the constructed code with
backquote syntax (usually).  Not a big deal, IMHO.  Typically,
Lisp macros do pretty fancy stuff and generating unique variable
names is the least of worries.

=============================================
Scott McLoughlin
Conscious Computing
=============================================



Wed, 02 Apr 1997 12:22:02 GMT  
 Hygenic macros

: > |> Am I correct in guessing that traditional lisp macros
: > |> are not considered hygenic?
: >
: > Indeed they are not; however, a careful programmer
: > can avoid writing `unhygienic' macros by generating
: > unique variable names whenever there is potential for
: > conflict.
: >

: Howdy,
:         Lisp macros are too much maligned. I mean, how "carefull"
: does one really have to be??  I just use GENSYM to generate unique
: symbol names and integrate them into the constructed code with
: backquote syntax (usually).  Not a big deal, IMHO.  Typically,
: Lisp macros do pretty fancy stuff and generating unique variable
: names is the least of worries.

"Unhygenic" macros hardly ever become a problem in most cases.  But
when you introduce a module system, it can become problematic.  Suddenly
every module that uses the macro must be importing all of the symbols
used in the macro in a compatable way.  This defeats much of the purpose
of having a module system to begin with.

  mike



Wed, 02 Apr 1997 16:04:22 GMT  
 Hygenic macros

Quote:

>Typically,
>Lisp macros do pretty fancy stuff and generating unique variable
>names is the least of worries.

There are probably lots of C programmers who would say the same thing about
free store management.  When using Lisp-family languages, we generally
expect these kinds of details to be handled automatically.

As simple as it is to work around this problem with gensyms or thunks, it's
still the case that many programmers don't use those techniques.  Not all
macros are complicated, and for a simple one (like the "swap" example
someone posted), the gensym code can be equal to the main code.

Symbolics had some of the best Lisp programmers around, yet their software
is riddled with macros that use local variables with names like ".TEMP.".
In fact, I think the Symbolics documentation even mentioned that end users
should avoid using variables beginning and ending with ".", to avoid
conflicts.  To their credit, in more recent times they started using the
thunk technique for the &BODY section of macros (the macro expands into a
call to an ordinary function, with the body of the macro turned into a
lambda expression that is passed as a parameter).
--

Barry Margolin
BBN Internet Services Corp.



Thu, 03 Apr 1997 06:20:20 GMT  
 Hygenic macros
OK, given the consensus that "hygenic" means "avoids the
traditional problem of unintended variable capture",
can someone tell us what the preferred approach or approaches
are to designing hygenic macros is among the Dylan implementors,
and what their main tradeoffs are?

Offhand I would guess that The Right Thing requires hacking the
compiler's scope-tracking mechanism. On the other hand, I would
try pretty hard to find a way to impose acceptable restrictions on
the form of macros (e.g. substitution permitted only expression-
to-expression) that would enable a preprocessing, macro-expansion
time solution.

Jim Goodwin



Thu, 03 Apr 1997 09:57:46 GMT  
 Hygenic macros
I personally just use the Common Lisp Package system to avoid these
problems.  If packages are kept fairly small, about one per file of
functions, it is unlikely that there will be conflicts within the
package unless macros introduce meaningless identifiers such as TEMP.

The traditional problems arise when someone other than the author
accidently clashes with a macro variable.  But if such variables are
not exported, this cannot occur.

In other words a well defined module system makes problems of hygene
less important.

What IS IMPORTANT is macros that have side affects.  IMHO CL's
handling of the compile time evaluation of top level forms is a
disaster.  How does/will Dylan hanle them?

--
Anthony Berglas
Rm 312a, Computer Science, Uni of Qld, 4072, Australia.
Uni Ph +61 7 365 4184,  Home 391 7727,  Fax 365 1999



Fri, 04 Apr 1997 09:59:19 GMT  
 Hygenic macros

   [...interesting Symbolics stuff deleted...]
   To their credit, in more recent times they started using the
   thunk technique for the &BODY section of macros (the macro expands into a
   call to an ordinary function, with the body of the macro turned into a
   lambda expression that is passed as a parameter).

But this technique has its disadvantage, too: The client programmer
must take care not to shade the function name. In the following Scheme
example, let's say (foo <exp>) expands to (foo* (lambda () <exp>)).
Now, mind the trap:

(let ((foo* 1))
  (foo something))

Hygienic macros avoid this, too. Other postings have mentioned that
free variables inserted by the client are not shaded, but vice versa
the client cannot shade variables that occur free in the macro
definition. This might be hard to do with normal gensym-style macros.
--

"If I have not seen as far as others, then that's |  Axel Wienberg
 because giants were standing on my shoulders"    |  Hinzeweg 9
                        Hal Abelson               |  21075 Hamburg



Fri, 04 Apr 1997 18:36:47 GMT  
 Hygenic macros


Quote:
>Offhand I would guess that The Right Thing requires hacking the
>compiler's scope-tracking mechanism. On the other hand, I would
>try pretty hard to find a way [...] that would enable a preprocessing,
>macro-expansion time solution.   (e.g. substitution permitted only
>expression-to-expression)

I'm not exactly sure what you mean by "a preprocessing macroexpand-time
solution", or "expression to expression".  

The general implementation idea is that the surface syntax of the source
program is parsed into an internal representation containing sufficient lexical
environment info to preserve hygiene.  This parse data structure is transformed
onto itself via syntactic pattern matching.  

Actually inverting this expanded representation into a properly renamed source
text would probably require the sort of scope analysis done by the compiler.
In practice the compiler will directly compile from the expanded program
representation.

Macros operate at the level of surface syntax, not source text (as in C) or on
token streams.  New statements can be defined, but only as long as they obey
the "surface syntax".  The surface syntax basically determines where statements
and expressions start and end.  The surface syntax plays a role similar to the
Lisp reader.

  Rob



Sat, 05 Apr 1997 01:29:12 GMT  
 
 [ 10 post ] 

 Relevant Pages 

1. lame hygenic macros...

2. Hygenic macros in MIT Scheme?

3. Newby question - Hygenic macros vs. other kinds

4. A macro involving two sub-macros - where the 2nd macro needs results from the first

5. macro -vs- macro/codeblock

6. Help with macros writing macros in Bigloo

7. syntax-rules macros with sub-macros

8. Scheme macro source: rewriter-widget, a widely applicable macro interface

9. Macros defining macros with define-syntax

10. symbol-macros and regular macros

11. Question about a macro-defining macro

12. Macro-Defining Macros

 

 
Powered by phpBB® Forum Software