[racket] problem with module language

From: Ryan Culpepper (ryan at cs.utah.edu)
Date: Thu Mar 22 19:04:41 EDT 2012

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

Posted on the users mailing list.