Ryan,
Thank you very much. I was reading up on macro's in the online
documentation and began to understand there is a lot more to it than
syntax-rules.
I get the general drift of your explanation without fully understanding
it, so I will study it some more and read the docs.
Thanks again. I may come back to it.
Cheers,
Joop
On 03/23/2012 12:04 AM, Ryan Culpepper wrote:
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
____________________
Racket Users list:
http://lists.racket-lang.org/users