[plt-scheme] inexpressible module imports

From: Dave Herman (dherman at ccs.neu.edu)
Date: Sun Nov 9 09:55:11 EST 2008

I have a whole-module compiler that's trying to construct a require/ 
rename-in line and I can't create references to the require'd name.  
Here's the smallest example I could create. Take a module language  
with three forms: an import line, a definition, and a single variable  
reference:

;; -- module.ss --
#lang scheme/base

(require (for-syntax scheme/base)
          (for-syntax "compile.ss"))

(define-syntax (module-begin stx)
   (syntax-case stx ()
     [(_ import definition expression)
      (with-syntax ([program (compile-program (syntax->datum #'import)
                                              (syntax->datum  
#'definition)
                                              (syntax->datum  
#'expression))])
        #'(#%plain-module-begin program))]))

(provide (except-out (all-from-out scheme/base) #%module-begin)
          (rename-out [module-begin #%module-begin]))
;; --

Since we called syntax->datum, we need to call `syntax-local- 
introduce' on any variables that come from the input, so that any  
introduced references won't be captured. So if we write a program like:

;; -- test.ss --
(module test "module.ss"
   (import scheme/math [pi newline])
   (define print 42)
   newline)
;; --

neither `print' nor `newline' should capture compiler-introduced  
references to the scheme/base identifiers of the same name.

But I can't come up with any plausible combination of arguments to  
`datum->syntax' and insertions of `syntax-local-introduce' into the  
compiler to get that reference to `newline' to refer to the imported  
name. Here was my best shot:

;; -- compile.ss --
#lang scheme/base

(require scheme/match)
(require (for-template scheme/base))

(provide compile-program)

(define (compile-program import definition reference)
   #`(begin
       #,(compile-import import)
       #,(compile-definition definition)
       (print #,(compile-reference reference))
       (newline)))

(define (compile-import import)
   (match import
     [(list 'import mod (list (? symbol? external) (? symbol?  
internal)))
      (let ([external-id (datum->syntax #'here external)]
            [internal-id (syntax-local-introduce
                          (datum->syntax #f internal))])
        #`(require (rename-in #,mod [#,external-id #,internal-id])))]))

(define (compile-definition definition)
   (match definition
     [(list 'define (? symbol? x) (? number? n))
      (let ([id (syntax-local-introduce (datum->syntax #f x))])
        #`(define #,id #,n))]))

(define (compile-reference reference)
   (syntax-local-introduce (datum->syntax #f reference)))
;; --

But for some reason, it tries to turn the reference into a #%top  
reference. I tried lots of other combinations but to no avail. Is  
there something secret about module-imports?

Thanks,
Dave



Posted on the users mailing list.