[racket] problem with module language
On 03/22/2012 01:54 PM, Joop Ringelberg wrote:
> Hello all,
>
> I try to write a small module language (named: biglooModuleSyntax.scm)
> in order to be able to run some files with a bigloo module statement in
> Racket. However, I run into a problem I do not understand at all.
>
> The (Bigloo) code loads a library ssax-sxml. In Racket, this must be
> replaced by: (require (planet "sxml.ss" ("lizorkin" "sxml.plt" 2 1))).
> The Bigloo code also needs some extra functions not provided by sxml.ss,
> so I require an additional small module (in missing-ssax-functions.scm).
> To this end, biglooModuleSyntax.scm contains the following macro:
>
> (define-syntax library
> (syntax-rules ()
> [(library ssax-sxml)
> (begin
> (require (planet "sxml.ss" ("lizorkin" "sxml.plt" 2 1)))
> (require "missing-ssax-functions.scm")
> )
> ]
> ))
The problem is that 'require' is an unhygienic binding form. It
introduces the imported names with the lexical context of (IIRC) the
module path. That means that the names are imported, but they can only
be accessed by references that have the hygiene mark from that expansion
of the 'library' macro. You can see this if you put something like
'(display SRV:send-reply)' at the end of the 'begin' in the macro
definition above; it'll work (if you remove the other syntax errors from
the rest of the module), but (unmarked) references to 'SRV:send-reply'
in the module's body will still fail.
> This, however, does not produce the desired results, as shown below. Now
> there is another macro in biglooModuleSyntax.scm that handles (some)
> import forms::
>
> (define-syntax import
> (syntax-rules ()
> [(import (moduleName path))
> (require path)]
> ))
>
>
> and that works just fine. [...]
Right, because the module path comes from the macro argument, so it
doesn't have a mark, so the names that 'require' binds don't have a mark.
Here's one way to fix your macro:
(define-syntax (library stx)
(syntax-case stx ()
[(library)
(with-syntax ([(mod ...)
(syntax-local-introduce
#'((planet "sxml.ss" ("lizorkin" "sxml.plt" 2 1))
"missing-ssax-functions.scm"))])
#'(require mod ...))]))
'syntax-local-introduce' cancels the mark for the currently executing
macro, so in the expansion of 'library' the module paths passed to
'require' will be unmarked.
There are other solutions, too. The general problem is "hygienic macros
that expand into unhygienic macros/forms".
Ryan