3

For some reason, running this line of code:

(TEST '("A"))

matches the syntax definition:

(define-syntax TEST
    (syntax-rules ()
       [(TEST [<table> <name>])
         (print "Should not be here")] ;This statement is executed
      [(TEST <table>) 
         (print "Should be here")] ;This should be executed but is not 
    ))  

How is this possible? It doesn't make sense to me because the literal after TEST is just a single parameter. How can it match two pattern variables?

Sam
  • 133
  • 4

2 Answers2

4

The reader turns '("A") into (quote ("A")). This means that (TEST '("A")) turns into (TEST (quote ("A"))).

This explains why the pattern (TEST [<table> <name>]) matches. The subpattern <table> matches quote and <name> matches ("A").

soegaard
  • 30,661
  • 4
  • 57
  • 106
3

Note that 'x is just a reader abbreviation for (quote x). For that reason, when you write (TEST '("A")), it is exactly the same as writing (TEST (quote ("A"))). Therefore, it matches the first pattern, where <table> is bound to quote and <name> is bound to ("A").

This might be a little confusing, but keep in mind that macros operate entirely at compile-time. For that reason, '("A") is never evaluated to anything before being passed to the macro, it’s just handed off directly. The syntax-rules pattern-matching construct doesn’t care at all about the special meaning of quote, it just matches against the syntactic structure of lists and pairs, so you get the behavior you’ve discovered.

Depending on what you are actually trying to do, there are a couple ways to get the behavior you might want. If you want pattern-matching against runtime values, use match, not syntax-rules. If you really want a macro, but you want to be more specific about the kinds of things that will match, you might want to use syntax-parse instead of syntax-rules. Without more information, though, it’s hard to give a concrete suggestion.

Alexis King
  • 43,109
  • 15
  • 131
  • 205