[racket] Lifting submodules

From: Stephen Chang (stchang at ccs.neu.edu)
Date: Tue Sep 17 16:54:27 EDT 2013

> I've been trying to answer it, but having one of those humbling
> experiences where I wonder how much I've really learned about macros,
> after all.  I distilled it to just:
>
> #lang racket
> (define-syntax (define-modularize stx)
>   (syntax-case stx ()
>     ([_ thing-name mod-name]
>      #'(begin
>          (module mod-name racket
>            (define thing-name #t)
>            (provide thing-name))
>          (require 'mod-name)))))
>
> (define-modularize foo foo-mod)
> ;; (require 'foo-mod)
> foo ;; => foo: unbound identifier in module

I've struggled with this before as well.

For this example, if I understand the docs correctly, the scope of the
require-spec has to match the scope of the use.

http://docs.racket-lang.org/reference/syntax-model.html?#(part._macro-introduced-bindings)

"In require for other require-specs, the generator of the require-spec
determines the scope of the bindings"

So the code below would work. Is there a better way?

#lang racket
(define-syntax (define-modularize stx)
  (syntax-case stx ()
    ([_ thing-name mod-name]
     (with-syntax ([require-spec (datum->syntax stx `(quote
,(syntax->datum #'mod-name)))])
       #'(begin
           (module mod-name racket
             (define thing-name #t)
             (provide thing-name))
           (require require-spec))))))

(define-modularize foo foo-mod)
;; (require 'foo-mod)
foo ;; => foo: unbound identifier in module



>
> Only if the previous line with the require is uncommented, does it
> work. IOW the module and thing define/provide seem just fine, it's the
> require that is not working. Why?
>
> I've thought about it, used the stepper in DrRacket, tried everything
> I can think of -- but can't get it to work.
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users

Posted on the users mailing list.