[plt-scheme] Evaling syntax with module bindings

From: Lauri Alanko (la at iki.fi)
Date: Mon Jan 30 17:38:08 EST 2006

Lord almighty, this boggles the mind. It seems that things work OK if I
accept that the syntax transformer _has_ to run during the
syntax-expansion phase, even if it is the syntax-expansion phase of
eval. So I move the piece of code that calls the transformer into inside
the eval.

(module a mzscheme
(provide xa)
(define (xa x) (* x x)))

(module b mzscheme
(provide xb)
(require-for-template mzscheme a)
(define (xb v) #`(xa #,v)))

(define old-ns (current-namespace))
(define ns (make-namespace))
;; This is supposed to be some dynamically generated input.
(define v (datum->syntax-object #'here '(+ 3 2)))
(namespace-require 'a)
(namespace-require 'b)
(parameterize ((current-namespace ns))
  ;; In real code the modules would just get loaded by the standard resolver.
  (namespace-attach-module old-ns 'a)
  (namespace-attach-module old-ns 'b)
  (eval #`(module d mzscheme
          (require-for-syntax b)
          (provide xd)
          (define xd
            (let-syntax ((foo (lambda (stx)
                                (#,(datum->syntax-object #f 'xb) #,v))))
  (namespace-require 'd)
   (namespace-variable-value 'xd (module->namespace 'd)))

Maybe the least obvious thing was that I cannot replace
#,(datum->syntax-object #f 'xb) with simply xb. I don't quite understand
why, since xb is not bound by anything where it appears. It seems that
whenever generating syntax to be fed into eval, one has to be really
careful about using ((quasi)?quote-)?syntax, if even free variables get
marked in some way that makes them unusable in the new namespace.

Well, at least it works.


Posted on the users mailing list.