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

Reply via email to