[racket-dev] Top level is hopeless or bug?

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Tue Sep 18 08:45:06 EDT 2012

At Mon, 17 Sep 2012 23:48:06 -0400, Asumu Takikawa wrote:
> Is the following interaction the expected behavior here or is it a bug?
> 
> Welcome to Racket v5.3.0.24.
> -> (module foo racket (define x 0) (provide x))
> -> (require 'foo)
> -> x
> 0
> -> (module foo racket (module* bar #f (define x 1) (provide x)))
> -> x
> ; readline-input:4:0: link: module mismatch;
> ;  possibly, bytecode file needs re-compile because dependencies changed
> ;   exporting module: 'foo
> ;   exporting phase level: 0
> ;   internal explanation: variable not provided (directly or indirectly)
> ;   in: x
> ; [,bt for context]

That looks right to me. I don't think the submodule is relevant; it's
just that `x' has gone away:

 > (module foo racket (define x 1) (provide x))
 > (require 'foo)
 > (module foo racket)
 > x
 readline-input::80: link: module mismatch;
 ...


> This is also interesting:
> 
> Welcome to Racket v5.3.0.24.
> -> (module foo racket (define x 0) (provide x))
> -> (require 'foo)
> -> x
> 0
> -> (module foo racket (define x 1) (provide x))
> ; define-values: assignment disallowed;
> ;  cannot re-define a constant
> ;   constant: x
> ;   in module: 'foo
> ; [,bt for context]
> -> x
> 1

Neat. That's the inliner exposing a mismatch between the current module
code and the instantiated variable `x'.

Adding a use of `namespace-variable-value' (which forces a variable
look-up) at the end of your trace:

 > (namespace-variable-value 'x)
 0

As another example, using a non-literal right-hand side for `x' avoids
inlining:

 > (module foo racket (define x (random 1)) (provide x))
 > (require 'foo)
 > x
 0
 > (module foo racket (define x (add1 (random 1))) (provide x))
 define-values: assignment disallowed;
  cannot re-define a constant
   constant: x
   in module: 'foo
   context...:
    foo: [running body]
    /Applications/Racket v5.3/collects/racket/private/misc.rkt:87:7
 > x
 0

Maybe inlining of module bindings should be disabled in the top level,
but I'm inclined to treat this as just another limitation of the top
level.


Posted on the dev mailing list.