views:

77

answers:

1

I want to make a helper macro for writing match-extensions. I have something like this:

(define-match-expander my-expander
  (λ (stx)
    (let* ([dat (cdr (syntax-e stx))]
           [var1 (car dat))]
           [var2 (cadr dat)])
      ;transformer goes here )))

So I wanted a macro that will do this let binding. I've started with something like this:

(define-syntax-rule (define-my-expander (id vars ...) body)
  (define-match-expander id
    (λ (stx)
      (match-let ([(vars ...) (cdr (syntax-e stx))])
        body))))

but match-let isn't defined in transformation time.

First question would be is there any other way of doing this (making this expanders, I mean)? Maybe there is already something similar in plt-scheme that I'm not aware of, or I'm doing it wrong in some way.

Regardless of answer on the first question, if I ever want to bound list of variables to list of values inside of a macro, how should I do it?

EDIT: In combination with Eli's answer macro now looks like this:

(define-syntax-rule (define-my-expander (id vars ...) body)
  (define-match-expander id
    (λ (stx)
      (syntax-case stx ()
        [(_ vars ...)
         body]))))
+3  A: 

I don't know what it is that you're trying to achieve, but my guess is that this goes in the right direction:

(define-match-expander my-expander
  (lambda (stx)
    (syntax-case stx ()
      [(_ (var1 var2) stuff ...)
       ;; use #'var1 #'var2 and #'(stuff ...) here
       ])))

The thing is that syntax-e is used to "unwrap" a syntax object and give you what it holds -- but the actual content may surprise you. For example, (foo . (bar)) will have a little different contents than (foo bar). So generally speaking, using syntax-case to do the pattern matching for you is much easier. In addition to being easier, it will also give some sensible error messages when there are errors, instead of what you'd get with your code.

Eli Barzilay
Thanks, this was helpful and helped me solve my problem. For a completeness sake, if I was not making expanders, but say, macro that expands into something that has lambda that takes a list and I want to bind list elements to macro params?
Slartibartfast
It most cases when you write macros using pattern matching works. But every once in a while (perhaps more frequently when you write more advanced macros with issues like good error messages) you need to turn them into a list. For this, you can use something like `(syntax->list #'(stuff ...))` -- it takes the parenthesized syntax object, and turns it into a list of syntax objects.
Eli Barzilay