[racket] Understanding error in use of submodule in my language

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Fri Aug 22 11:38:49 EDT 2014

I think this may be a problem in macro expansion with submodules.

The `#%module-begin` from `racket/base` adds a submodule declaration
for `configure-runtime` when it doesn't see an existing submodule
declaration for `configure-runtime` --- but it looks for an existing
declaration as an immediate one, before macro-expanding the module

In your code, the `mute` wrapper hides the declaration of
`configure-runtime`, so a conflicting one gets added. The tricky part
is that this happens the second time that the `test` submodule is

 * The overall module's body is forced via `local-expand`.

 * As a part of that local expansion, the `test` submodule is expanded'
   its expansion includes a declaration of a `configure-runtime`

 * The overall module's expanded body is wrapped back in
   `#%module-begin`, which will re-expand all of the content, including
   the `test` submodule.

 * The `test` submodule this second time around has a `#%module-begin`
   that is supposed to be bound to `#%plain-module-begin`, but it ends
   up being captured[*] by `#%module-begin` from "bootstrap-lang.rkt",
   so that the submodule's body is again local-expanded and again send
   to `#%module-begin` from `racket/base` with a `mute` wrapper around
   the `configure-runtime` sub-submodule.

The [*] step seems wrong to me. I think this may be an example of a
problem deep in the macro expander, and solving that is my next

Since the repair (assuming that I have correctly diagnosed the cause)
may be a while, do you have a workaround already? The macro name `mute`
suggests that you may want to suppress the printing of expression
results at the top-level of a module, and that might be as easy as
expanding `#%module-begin` to `#%plain-module-begin`. Or maybe
`syntax/wrap-modbeg` can help, or maybe the strategy used by
`syntax/wrap-modbeg` would work better for your macro.

At Thu, 21 Aug 2014 17:22:29 +0100, Marco Monteiro wrote:
> Hello!
> I'm using Racket 6.1
> I'm trying to understand this error. I'm using submodules in a language I
> defined. The language file is here:
> http://pastebin.com/7RiHHRmi
> Notice the commented out line 28.
> I use that language in the following code
> http://pastebin.com/Qa6RD9wF
> raco expanding this last file fails with
> module: duplicate submodule definition
>   at: configure-runtime
>   in: module
>   context...:
>    /usr/share/racket/pkgs/compiler-lib/compiler/commands/expand.rkt:29:11:
> loop
>    /usr/share/racket/pkgs/compiler-lib/compiler/commands/expand.rkt:
> [running body]
>    /usr/share/racket/collects/raco/raco.rkt: [running body]
>    /usr/share/racket/collects/raco/main.rkt: [running body]
> If I uncomment line 28 it no longer fails. If I use (module ...) instead of
> (module* ...) it no longer fails independently of line 28 being commented
> out or not.
> Trying to macro expand that in drracket gives me "Internal error: car:
> contract violation ." error.
> What is happending here?
> Thanks,
> Marco
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users

Posted on the users mailing list.