macrosschemesyntax-rules

Scheme macro pairwise processing question


(For now please ignore that what I'm after is un-Schemey, because this for a DSL aimed at non-programmers)

I'd like to do something eqivalent to this:

(pairwise key1 value1 key2 value2)

Which would expand to this, m being another macro I've defined (hence I can't simply use a variadic style function):

(list (cons key1 (m value1)) (cons key2 (m value2)))

I've tried this:

(define-syntax pairwise
  (syntax-rules ()
    ((_ key value ...)
     (list (cons key (m value)) ...))))

But as I guessed it expanded to:

(list (cons key1 (m value1)) (cons key1 (m key2)) (cons key1 (m value2)))

I'm a bit stuck on how to process these elements pairwise in the way I'd like, without requiring a user to add inner brackets.


Solution

  • You can do this with recursion. Instead of having one case that looks like

    ((_ key value ...)
     (list (cons key (m value)) ...))
    

    You can have two cases that look like

    ((_)
     '())
    ((_ key value . rest)
     (cons (cons key (m value)) (pairwise . rest)))
    

    Similar to how you would design a recursive list-processing function, but with the base case as a syntax-rules case (detected at compile-time) instead of an if or cond condition (detected at run-time).