[<<][plt][>>][..]
Wed Jul 22 09:17:34 CEST 2009

Avoiding macros with 'eval

Let's abstract the pattern in [1] since it seems quite useful in
general.  What I'm interested in is to trigger evaluation of input
syntax to guide expansion.  The basic form that does what I need is:

(define-syntax (foo stx)
  (syntax-case stx ()
    ((_ e)
     #`(let-syntax ((m
                     (lambda (stx)
                       (let ((v e))  ;; (1)
                         (if (zero? v)
                             #'zero
                             #`e)))))  ;; (2)
         (m)))))

The `foo' form expands to a form that defines a local macro using
`let-syntax' and triggers its expansion.

This macro has the original syntax object, represented by the `e'
syntax variable, occuring in two positions: (1) in an expression
position valid at the macro's run time, and (2) in a quoted form that
will make it into the output syntax of that macro.

The net result is that both a syntax object and its evaluated form are
available to a macro body.  This can be captured in a `let-staged'
form:


(define-syntax (foo stx)
  (define-syntax-rule (let-staged ((n v) ...) body ...)
    #`(let-syntax
          ((m (lambda (stx)
                (let ((n v) ...) body ...))))
        (m)))
  (syntax-case stx ()
    ((_ e)
     (let-staged ((e-eval e))
         (if (zero? e-eval)
             #'zero
             #`e)))))

Basicly, `let-staged' behaves as `let' with the exception that the `v'
forms are made up of syntax that will be evaluated.  This is useful
because these forms can refer to syntax variables in the enclosing
`syntax-case' context.

[1] entry://20090719-142813



[Reply][About]
[<<][plt][>>][..]