macroslispschemesyntax-rulesdefine-syntax

How are vector patterns used in syntax-rules?


I have been writing Common Lisp macros, so Scheme's R5Rs macros are a bit unnatural to me. I think I got the idea, except that I don't understand how one would use vector patterns in syntax-rules:

(define-syntax mac
  (syntax-rules ()
    ((mac #(a b c d))
     (let ()
       (display a)
       (newline)
       (display d)
       (newline)))))

(expand '(mac #(1 2 3 4)))  ;; Chicken's expand-full extension shows macroexpansion

=> (let746 () (display747 1) (newline748) (display747 4) (newline748))

I don't see how I'd use a macro that requires its arguments to be written as a vector:

(mac #(1 2 3 4))
=>
1
4

Is there some kind of technique that uses those patterns?

Thank you!


Solution

  • A macro might not require its arguments to be written as a vector, yet provide useful behaviour for when they are. The most notable example would probably be quasiquote:

    ;; a couple of test variables
    (define foo 1)
    (define bar 2)
    
    ;; vector literals in Scheme are implicitly quoted
    #(foo bar) ; returns #(foo bar), i.e. a vector of two symbols
    
    ;; however quasiquote / unquote can reach inside them
    `#(,foo ,bar) ; returns #(1 2)
    

    As another example, see this pattern matching package which allows matching on vectors and thus uses vector patterns in its macro definitions (included on the linked-to page together with the package metadata).