[racket] Macros With Multiple Ellipsis

From: Stephen Chang (stchang at ccs.neu.edu)
Date: Wed Jan 8 15:33:36 EST 2014

Yeah I'm pretty sure syntax-case won't let you do that.

One solution is to use syntax-parse, which is (almost) a drop-in
replacement for syntax-case (omit the list of literals), but with many
additional features.

#lang racket
(require (for-syntax syntax/parse))

(define-syntax (define/test stx)
  (syntax-parse stx
    [(_ (id arg ...) body ... #:test test-expr ...)
     #'(define (id arg ...) body ... test-expr ...)]))

(define/test (my-fn a b c)
  (print a)
  (print b)
  (print c)
  #:test
  (print 'test1)
  (print 'test2))
(define-values (x y z) (values 10 20 30))
(my-fn x y z)

=> 102030'test1'test2

On Wed, Jan 8, 2014 at 2:58 PM, Scott Klarenbach <scott at pointyhat.ca> wrote:
> I have a macro that modifies define to perform some additional processing.
>
> (define-syntax (define/test stx)
>   (syntax-case stx ()
> [(_ (id arg ...) body ... #:test test-expr)
> #'(define (id arg ...) body ... test-expr)]))
>
> (define/test (my-fn a b c)
>   (print a)
>   (print b)
>   (print c)
>   #:test
>   (print 'test))
>
> This works, but only if test-expr is one expression or wrapped in a begin or
> something.  I'd like the test-expr to be the same as the define body.  I
> wish I could write:
>
> (define-syntax (define/test stx)
>   (syntax-case stx ()
> [(_ (id arg ...) body ... #:test test-expr ...)
>  #'(define (id arg ...) body ... test-expr ...)]))
>
> But I get a "misplaced ellipsis in pattern" error.
>
> I could change the pattern to something like (body ...) #:test (test-body
> ...), but now the syntax of the macro has changed to include the extra
> parenthesis.
>
> Am I making a simple mistake?  Or am I resigned to manually parsing out the
> single test-expr into multiple forms in the template?
>
> Thanks.
> --
> Talk to you soon,
>
> Scott Klarenbach
>
> PointyHat Software Corp.
> www.pointyhat.ca
> p 604-568-4280
> e scott at pointyhat.ca
> 200-1575 W. Georgia
> Vancouver, BC V6G2V3
>
> _______________________________________
> To iterate is human; to recur, divine
>
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users
>

Posted on the users mailing list.