[plt-scheme] Problem with syntax-case macro under MzScheme 352

From: Jens Axel Søgaard (jensaxel at soegaard.net)
Date: Sat Sep 9 13:44:01 EDT 2006

Blake McBride skrev:
> 
> Never mind, I figured it out.  The macro should have been:
> 
> (define-syntax m4
>   (lambda (x)
>     (syntax-case x ()
>                   ((_ v)
>                    (with-syntax ((name (datum->syntax-object (syntax v) 
> (string->symbol (string-append (symbol->string (syntax-object->datum 
> (syntax v))) ":g")))))
>                                   (syntax (begin
>                                              (define name '())
>                                              (define v '()))))))))
> 
> I figured it out by using Chez Scheme.  It gave me a meaningful message
> with the wrong macro.  MzScheme lets it run and hints that it's right.
> 
> I can't hardly imagine making it any more complicated.  The simplest
> things are made rocket science with define-syntax and friends.  Lisp
> macros may not be perfect but normal people (those who don't devote
> their life to understanding the intricacies of syntax-case) can use
> and understand it.  Syntax-case is killing scheme.

Rubbish. It is just another example of "there is no free lunch".
The syntax-case system makes it easy to write one type of macros,
in return another type becomes a little harder.

Here is small module with some utilites to write macros:

(module macro-utilities mzscheme
   (provide with-captures
            symbol-append
            identifier->symbol)

   (define-syntax (with-captures stx)
     (syntax-case stx ()
       [(_ so ([name expr] ...) body)
        (syntax
         (with-syntax ([name (datum->syntax-object so expr)]
                       ...)
           body))]))

   (define (symbol-append s1 s2)
     (string->symbol
      (string-append
       (symbol->string s1)
       (symbol->string s2))))

   (define identifier->symbol syntax-e))


With these utilities your macro becomes:

(require-for-syntax macro-utilities)

(define-syntax (m4 stx)
   (syntax-case stx ()
     [(_ v)
      (identifier? (syntax v))
      (with-captures stx
         ([name (symbol-append (identifier->symbol #'v) ':g)])
         (syntax
          (begin
            (define name '())
            (define v    '()))))]))

The guard expression (identifier? (syntax v)) isn't strictly necessary,
but will give a better error message, if the m4 macro is misused.

-- 
Jens Axel Søgaard


-- 
Jens Axel Søgaard




Posted on the users mailing list.