[plt-scheme] (require... ) expanded from a macro

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sun Oct 22 02:33:18 EDT 2006

At Sun, 22 Oct 2006 07:58:12 +0300, "Dan Muresan" wrote:
> (define-syntax require-library
>   (lambda (stx)
>     (define libraries '())  ;; broken, should be outside lambda
>     (syntax-case stx (quote)
>       ((_ (quote lib))
>        (let ((slib (syntax-object->datum #'lib)))
>          (if (memv slib libraries)
>              (syntax (begin))
>              (let ((str (string-append
>                            (symbol->string
>                              (syntax-e #'lib)) ".scm")))
>                (set! libraries (cons slib libraries))
>                (display (format "Including ~a\n" slib))
>                (with-syntax ((fname (datum->syntax-object #'lib str)))
>                  #'(include fname)))))))))
> 
> (require-library 'x)  ;; should expand to (include "x.scm")
> ;; x.scm just contains (define (f x) x)
> 
> f  ;; raises "undefined identifier"
> 
> The macro runs, but the binding for f seems to be hidden.
> 
> Firstly, why are the included bindings hidden?

Mostly the same as before. The `fname' trick didn't work because
`include' (more or less arbitraily) uses the whole `(include fname)'
context for the included code, instead of just `fname'.

In this case, you can use

 (with-syntax ([str str])
  (include-at/relative-to lib lib str))

which causes `str' to be resolved relative to the source of `lib', and
also makes the inserted code have the context of `lib'.

In other words, since `include' is commonly inserted by macros, we
offer a variant that more directly supports macros.

> And, secondly, where
> should I put the "libraries" catalog (inside (lambda (stx) ...) is
> obviously broken, but putting them outside generates an error)?

Writing it as

 (define-syntax require-library
   (let ([libraries  '()])
     (lambda (stx)
       ...)))

probably works for your purposes.

It doesn't work right with separate compilation, but I'm guessing that
separate compilation is not an issue.

Matthew



Posted on the users mailing list.