[plt-scheme] Macro rule selection

From: Ryan Culpepper (ryanc at ccs.neu.edu)
Date: Fri Jan 30 13:14:48 EST 2009

James Coglan wrote:
> Hi all,
> 
> Just ran into some puzzling macro behaviour that I was hoping someone could
> explain. I have the following code:
> 
> ; Modifies a variable by applying a function to said variable
> 
> (define-syntax ! (syntax-rules ()
>   [(! x (fn arg ...))
>     (set! x (fn x arg ...))]
>   [(! x fn)
>     (set! x (fn x))]))
> 
> ; for example...
> 
> (define-syntax square! (syntax-rules ()
>   [(square! x)
>     (! x (* x))]))
> 
> (define a 6)
> (square! a)
> 
> Turns out that when I run this, 'a' turns out as 1296, or 36 squared. My
> understanding of macro rule selection was that the first matching rule is
> chosen and expanded, and subsequent rules are ignored. In this case, the
> more specific (! x (fn arg ...)) rule appears first so I would assume that
> would be used to match (! x (* x)) in the (square!) macro. It seems the (! x
> fn) rule (which would also match but has lower priority) is interfering,
> since if I remove this rule all is well. I want the second rule so you can
> simply pass a single argument function without surrounding it in parens.
> 
> Any ideas what's going on here?

I'm not seeing the behavior you describe. When I run the macro stepper 
on your program, I see this:

   (square! a) => (! a (* a)) => (set! a (* a a))

and when I run the program and evaluate 'a', I get 36. Perhaps you 
accidentally squared it twice when you were trying it out?

Ryan


> _________________________________________________
>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme



Posted on the users mailing list.