[plt-scheme] macro question

From: Michael Vanier (mvanier at cs.caltech.edu)
Date: Sat Jun 7 05:17:42 EDT 2008

I've run into a problem with a macro I don't know how to solve.  Here's the macro:

(define-syntax get-stack-vals
   (syntax-rules ()
     ((_ n (env first rest) expr ...)
      (let*-values (((env stk) (es-values es))
                    ((first rest) (take n stk)))
        expr ...))))

Here's a use:

(define (do-def es)
   (get-stack-vals 2 (env first rest)
      (let ((sym (cadr first))
            (val (car first)))
        (if (symbol? sym)
            (let ((env2 (env-add env sym val)))
              (make-es env2 rest))
            (error "cannot define non-symbol: " sym)))))

which should expand to:

(define (do-def es)
   (let*-values (((env stk) (es-values es))
                 ((first rest) (take 2 stk)))
     (let ((sym (cadr first))
           (val (car first)))
       (if (symbol? sym)
           (let ((env2 (env-add env sym val)))
             (make-es env2 rest))
           (error "cannot define non-symbol: " sym)))))

and apparently does, at least according to the macro stepper.  However, when I call do-def I get an 
error message: "reference to undefined identifier: es".  This seems odd, because es is in scope at 
the macro expansion location.  Is the es in the get-stack-vals macro bound in the lexical scope of 
that macro?  All the other external identifiers in the macro are bound at the top-level, so it works 
either way for them.  If this is the case, how do I get es to be bound the way I want it to be?  I 
realize that I'm trying to do something a bit naughty since I'm assuming a binding for es will exist 
at all macro expansion locations; alternative suggestions are welcome (other than "don't give up 
your day job").

I'm a macro newbie, so please be gentle ;-)  PLT Scheme's macro system is an intricate and beautiful 
thing that I'm just beginning to wrap my head around.

Mike




Posted on the users mailing list.