[plt-scheme] Where is macroexpand in PLT Scheme?

From: Joe Marshall (jrm at ccs.neu.edu)
Date: Wed Nov 12 10:37:09 EST 2003

Bill Clementson <bill_clementson at yahoo.com> writes:

>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme
> I wanted to expand a macro in Scheme today. I had a
> look for "macroexpand" in R5RS and the PLT
> documenation.  Didn't find it.  At least, not in R5RS.

`macroexpand' would only be useful as a top-level debugging tool.  It
would be quite difficult to make it work `correctly' with R5RS macros.
I'm guessing that is one reason it is not in R5RS.

> In PLT Scheme, the following code seems to be roughly
> equivalent to macroexpand:
> (syntax-object->datum (expand-to-top-form '(some-macro
> some-params)))

Roughly, yes.

> Seems odd that there isn't some more convenient way to
> do a macro expansion. 

I stole this from Eli Barzilay and put it in my mzscheme.rc file:

;;; Syntax debugging
;;; -test or (-test)     returns current syntax object as an s-expression
;;; (-test foo)          set current
;;; (-test :this)        show current
;;; (-test :expand)      expand current (possibly in a context)
;;; (-test :expand-once) expand one step
;;; (-test :expand*)     expand one step repeatedly
;;; (-test :pp)                 pprint current
(define-syntax -test
  (let ((v #f)
        (->datum (lambda (x) (if (syntax? x) (syntax-object->datum x) x))))
    (lambda (stx)
      (syntax-case stx ()
        ((_ m)
         (let ((msg #'m))
           (let loop ((new (case (->datum msg)
                             ((:this :pp) v)
                             ((:expand) (expand v))
                             ((:expand-once :expand*) (expand-once v))
                             (else msg))))
             (if (eq? ':pp (->datum msg))
                 ((dynamic-require '(lib "pretty.ss") 'pretty-print)
                  (->datum new))
                 (printf "--> ~s\n" (->datum new)))
             (let ((old v))
               (set! v new)
               (when (eq? (->datum msg) ':expand*)
                 (if (equal? (->datum new) (->datum old))
                     (printf "--> ...\n")
                     (loop (expand-once v))))))
        (_ #`'#,v)))))

Posted on the users mailing list.