Why is my (guile) scheme macro evaluating its argument?

202 Views Asked by At

Within Guile, I am trying to learn define-syntax and syntax-rules. I was under the impression that scheme macros do not evaluate their arguments, but it seems like mine is doing so:

(define-syntax foo
    (syntax-rules ()
        ((foo word)
            (if (eqv? word 'bar) (begin (write "Caller said BAR!") (newline)))
            )))

If I call it with (foo bar), I get the error message

Unbound variable: bar

Whereas if I call it with (foo 'bar), I get the expected

"Caller said BAR!"

This makes it seem as though the argument is getting evaluated prior to application of the macro.

1

There are 1 best solutions below

3
On BEST ANSWER

You should try and look at what the macro expansion is first:

scheme@(guile-user)> (use-modules (language tree-il))
scheme@(guile-user)> (tree-il->scheme (macroexpand '(foo bar)))

indented edited for clarity

(if ((@@ (#{ g184}#) eqv?) bar (quote bar))
    (begin ((@@ (#{ g184}#) write) "Caller said BAR!")
       ((@@ (#{ g184}#) newline))))

So (foo bar) is transformed into(after removing @@s):

(if (eqv? bar (quote bar))
    (begin (write "Caller said BAR!")
       (newline)))

before evaluation happens. Now the error makes sense doesn't it?

Now what happens if you quote the word parameter? See how this expands:

(define-syntax foo
  (syntax-rules ()
    ((foo word)
     (if (eqv? 'word 'bar) (begin (write "Caller said BAR!") (newline))))))