[plt-scheme] "transitivity" in module namespaces

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Tue Apr 5 09:57:52 EDT 2005

At Wed, 30 Mar 2005 11:25:07 -0600, Corey Sweeney wrote:
> ;;;;;;;;file bp.ss
> (module bp (lib "plt-pretty-big-text.ss" "lang") 
> (provide b->p)
> (require (lib "plt-match.ss"))
> 
>  ;;use match in a function that's a first class citizen
> (define (bnf->p list-in)
>         [...]
> (let ((match-expression
>            (append
>             `(lambda (x) match x)
>               [... list-in ...]
>               )))
>       (eval match-expression)))))

`eval' always uses the current namespace as determined by the
`current-namespace' parameter. By default, then, symbols (as opposed to
syntax) in the argument to `eval' get attached to the top-level
environment, not to any module's environment.

> ;;;;;;;;next file xx.scm
> (require "bp.ss")
> 
> ;define what a var is
> (define (var? x)   
>     [...]
>     )
>   
> (define P-BNF
>   `(
>      [...]
>     (? var?)
>      [...]
>      ))
> 
> (define PC? (bnf->p P-BNF))

In this case, you've bound `var?' in the top level environment, so it
works.

> ;;;;;;;;next file xx.ss
> (module xx
> (require "bp.ss")
> (provides PC?
>               var?)
> 
> ;define what a var? is
> (define (var? x)   
>     [...]
>     )
>   
> (define P-BNF
>   `(
>      [...]
>     (? var?)
>      [...]
>      ))
> 
> (define PC? (bnf->p P-BNF))
> 
> 
> ;;;;;;;;then next file yy.scm
> (require  "xx.ss")
> (PC? `(correct pc list))
> 
> 
> then the call to PC? returns:
> 
>           ---reference to undefined identifier: var?---

In this case, there's no top-level binding.

> so i thought it's geting eval'ed under the wrong namespace, so i make
> var? available in every namespace (i cut and paste a copy of "define
> var?" to bp.ss).  But even after this i still get the same error.

Putting `var?' definitions in multiple modules still leaves it
undefined in the top level environment.

Put another way, a module is not a "namespace" in MzScheme terminology
(although it's possible to obtain a namespace that corresponds to the
module body --- but that feature is intended for exploring and
debugging).

If you use syntax objects instead of plain S-expressions, then things
will probably work as you expect, because identifiers will become
associated to bindings when the identifier is created, instead of when
the identifier is `eval'ed.

Matthew



Posted on the users mailing list.