[plt-scheme] Controlling execution in macro defining macros

From: Noel Welsh (noelwelsh at yahoo.com)
Date: Wed Jun 23 12:15:39 EDT 2004

I am writing a macro A that expands into the definition of
a macro B.  When macro B is called I want it to expand
into a function that stashes away the values of its
parameters and then executes some expressions specified
when A was called.  I want the parameters to B to be
executed only once, and this is proving to be difficult.
Attached in some code that indicates the difficulty I am
facing.

If I uncomment 1 the code fails because stash-it isn't in
the same environment as B.

If I uncomment 2 the parameters are evaluated multiple
times

If I uncomment 3 (and comment out the line below it) the
code fails because foo isn't defined in the expander
environment.

I've tried a number of other variations and they all fail
for some reason or other.  Any suggestions from the
assembled macrology experts?  It is crucial that the macro
A expands into another macro definition (B), that calls to
A may declare expressions defined in the execution
environment, and that the parameters to B are executed
once.

Thanks,
Noel

----------------------------------------------------------

(define stash
  (make-parameter #f))

(define (stash-it val)
  (stash val))

(define-syntax a
  (lambda (stx)
    (syntax-case stx ()
      ((test name (param ...) expr ...)
       (syntax
        (begin
          (define-syntax name
            (lambda (stx)
              (define the-fn
                (lambda (param ...)
;; 1;                  (stash-it (list param ...))
                  expr ...))
              (syntax-case stx ()
                ((name param ...)
                 (with-syntax ((the-fn the-fn))
                   (syntax (begin 
;; 2;                              (stash-it (list param
...)) 
                             (the-fn param ...)))))))))
          )))))

(define counter 0)

(define (foo x y) (+ x y))

;; 3;(a b (x y) (foo x x))
(a b (x y) (+ x y))

(b (begin (set! counter (add1 counter)) 1)
   (begin (set! counter (add1 counter)) 2))

(if (not (= counter 2))
    (printf "Counter value ~a is wrong~n" counter))

=====
Email: noelwelsh <at> yahoo <dot> com
Jabber: noelw <at> jabber <dot> org

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 


Posted on the users mailing list.