[plt-scheme] Beginner Macrology

From: Noel Welsh (noelwelsh at gmail.com)
Date: Fri Jun 15 08:57:50 EDT 2007

Hi Keith,

If I had more time I'd explain fully, but I don't, so:

 - syntax-case is simply a pattern matcher for syntax objects, just
like match is a pattern matcher for other types of data.  There is
nothing magic about syntax-case

 - to unhygienically introduce an identifier you basically write

   (with-syntax ([id (datum->syntax-object
stx-object-that-is-the-scope-in-which-to-bind-the-name
name-as-symbol)])
      ... more code)

 - consider replacing unhygienic macros with hygienic ones.

 - follow the links for the Cookbook for more info,

   http://schemecookbook.org/Cookbook/GettingStartedMacros

HTH,
Noel

   Particularly Dybvig and JRM's contributions.
On 6/15/07, Keith Frost <keith.l.frost at gmail.com> wrote:
> ; I write the following:
>   (require (lib "defmacro.ss"))
>
>   (define-for-syntax (transform-bars sexps)
>     (define bars null)
>     (define (xform-bars sexps)
>       (map
>        (lambda (sexp)
>          (if (pair? sexp)
>              (if (eq? (car sexp) 'abar)
>                  (begin
>                    (let ((name (gensym)))
>                      (set! bars (cons (list name (cadr sexp)) bars))
>                      (cons name (xform-bars (cddr sexp)))))
>                  (xform-bars sexp))
>              sexp))
>        sexps))
>     (let ((result (xform-bars sexps)))
>       (values result (reverse! bars))))
>
>   (define-macro (make-foo args . body)
>     (define-values (xformed-body bars)
>       (transform-bars body))
>     `(let ,(map (lambda (name-arg)
>                   `(,(car name-arg)
>                      (make-bar ,(cadr name-arg))))
>                 bars)
>        (lambda ,args
>          , at xformed-body)))
>
>
>  So that when I say
>  (make-foo (x) (+ (abar 1 x) (abar 2 (abar 3 x))))
>  It is understood that I mean -->
>   (let ((bar1 (make-bar 1)) (bar2 (make-bar 2)) (bar3 (make-bar 3)))
>      (lambda (x)
>         (+ (bar1 x) (bar2 (bar3 x)))))
>
> This works, well enough.  (It is to be understood that a bar is a
> closure with some internal state...)  But, although this is reasonably
> straightforward, I am left with an uneasy feeling that it is not the
> Scheme way.  Trolling through source code S-expressions, looking for
> an identifier in the car position to replace, that is.  Are there any
> syntax-case/or-whatever wizards reading who would care to enlighten me
> as to a better way to do this, and how it works?
>
> Thanks,
>
> Keith Frost
> _________________________________________________
>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>


Posted on the users mailing list.