[plt-scheme] Beginner Macrology

From: Keith Frost (keith.l.frost at gmail.com)
Date: Thu Jun 14 20:25:34 EDT 2007

; I write the following:
  (require (lib "defmacro.ss"))

  (define-for-syntax (transform-bars sexps)
    (define bars null)
    (define (xform-bars sexps)
       (lambda (sexp)
         (if (pair? sexp)
             (if (eq? (car sexp) 'abar)
                   (let ((name (gensym)))
                     (set! bars (cons (list name (cadr sexp)) bars))
                     (cons name (xform-bars (cddr sexp)))))
                 (xform-bars sexp))
    (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))))
       (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?


Keith Frost

Posted on the users mailing list.