[plt-scheme] Best practices when writing macros; avoid name shadowing?

From: Chongkai Zhu (czhu at cs.utah.edu)
Date: Sun Feb 3 23:09:11 EST 2008

Have you ever heard "hygienic macro" before? If not, google.


Grant Rettke wrote:
> Tonight I was working on a problem from
> _The_Scheme_Programming_Language_3rd_Edition,
> in particular Exercise 3.2.5 in
> http://www.scheme.com/tspl3/further.html#./further:h2.
> In this problem you goal is to augment a given version of `let` to
> handle `named let` using letrec.
> I worked on the problem and came up with solution that made sense and
> according to my rudimentary
> testing worked. The expanded code was what I expected to see, and that
> code did what I expected. When I checked
> the answer, it was wrong, but only by a bit, and I didn't understand
> why since it worked. The error was later demonstrated
> to me.
> Here is the source:
> (custom-let ([fun '(a b c)])
>              (custom-let fun ([ls fun])
>                         (unless (null? ls)
>                           (printf "~s\n" (car ls))
>                           (fun (cdr ls)))))
> My wrong version of expanded code:
> ((lambda (fun)
>      (letrec ([fun (lambda (ls)
>                      (unless (null? ls)
>                        (printf "~s\n" (car ls))
>                        (fun (cdr ls))))])
>        (fun fun))) '(a b c))
> The correct way to expand the code:
> ((lambda (fun)
>      ((letrec ((fun (lambda (ls)
>                       (unless (null? ls)
>                         (printf "~s\n" (car ls))
>                         (fun (cdr ls)))))) fun)
>       fun)) '(a b c))
> I see the error, the function name in the letrec block shadows the
> name of the list in the enclosing lambda block.
> Is this a lesson that you learn writing macros, to be sure not to
> shadow variables in your expansion?
> There must be tons of hairy situations that folks who heavily utilize
> the macro system have to avoid!
> All thoughts appreciated on this one.
> _________________________________________________
>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme

Posted on the users mailing list.