[plt-scheme] Macros in the same module

From: Eli Barzilay (eli at barzilay.org)
Date: Mon May 11 08:15:18 EDT 2009

On May 11, Paulo J. Matos wrote:
> #lang scheme
> (define-syntax (bar a)
>   (syntax-case a (else)
>     [(_ (else body))
>      #'(else body)]
>     [(_ (n body))
>      #'((n) body)]))
> (define-syntax (foo a)
>   (syntax-case a ()
>     [(_ name rules ...)
>      #'(case (name)
>          (bar rules) ...)]))
> [...]

This won't work because of a different reason -- the literals of a
`case' expression are not expressions, so they're not macro expanded.
It wouldn't make sense to make them expand, since

  (case 'if [(if) 1])

should return 1 instead of raising a syntax error.  If you want to
compute the expressions that go into the literals, you can do that
with a function (but this whole example can be done with a much
simpler macro):

  #lang scheme
  (define-for-syntax (bar a)
    (syntax-case a (else)
      [(else body) #'(else body)]
      [(n body)    #'((n) body)]))
  (define-syntax (foo a)
    (syntax-case a ()
      [(_ name rules ...)
       (with-syntax ([(branch ...) (map bar (syntax->list #'(rules ...)))])
         #'(case name branch ...))]))
  (define op 0)
  (foo op
       (0 'zero)
       (1 'one)
       (2 'two)
       (else 'else))

          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!

Posted on the users mailing list.