[plt-scheme] Question: Restoring lexical context in anaphoric macros

From: Remco Bras (vrsoft at gmail.com)
Date: Fri Feb 19 06:59:03 EST 2010


I have a question regarding datum->syntax, specifically about a macro
alambda given below.

(define-syntax alambda
 (lambda (exp)
   (syntax-case exp (alambda)
     [(alambda args body ...)
      (datum->syntax exp
                     `(letrec ((self (lambda ,(syntax->datum #'args)
                                       ,@(syntax->datum #'(body ...)))))

This macro works fine in simple cases and things like the below
definition of counter work.

(define counter (let ((x 1))
                 (alambda (message . stuff)
                   (cond ((eq? message ':get) x)
                         ((eq? message ':set) (set! x (+ x (apply +
stuff))) (self ':get))))))

However, if I define a macro dlambda using syntax-rules, like below,
the counter2 (given below) fails to assign the proper context to x in
the body of dlambda, expanding it to a top-level binding instead.

(define-syntax dlambda
 (syntax-rules (dlambda)
   [(dlambda (name args body ...) ...)
    (alambda (message . stuff)
             (cond ((eq? message (quote name)) (apply (lambda args
body ...) stuff)) ...))]))

(define counter2 (let ((x 1))
                  (dlambda (:get () x)
                           (:set args
                                 (set! x (+ x (apply + args)))
                                 (self ':get)))))

The cause of this bug appears to be the datum->syntax call in
alambda's definition.
Is there a way to properly restore the lexical context of the
arguments to alambda, while injecting the self binding?

Thanks for your time,

-Remco Bras

Posted on the users mailing list.