[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.


Posted on the users mailing list.