[racket-dev] A strange problem with namespaces

From: Sam Tobin-Hochstadt (samth at cs.indiana.edu)
Date: Wed May 7 11:43:39 EDT 2014

On Wed, May 7, 2014 at 11:07 AM, Sam Tobin-Hochstadt
<samth at cs.indiana.edu> wrote:
> Great, thanks!

Also, can you say more about when this trick is needed? When I try to
use it in the actual code that I want to run, I end up with the same
error, or about other submodules that are missing.

More specifically, I added `prep!` to
`tests/typed-racket/unit-tests/evaluator.rkt` and then ran this
program:

    #lang racket
    (define ns (make-base-namespace))
    (current-namespace ns)
    ((dynamic-require 'tests/typed-racket/main 'go/text)
     (dynamic-require 'tests/typed-racket/main 'unit-tests))

It produces lots of errors, of the same form that `weird.rkt` had
before the `prep!` fix.  You get the same errors if you take out the
namespace.

However, there aren't any other uses of namespace anchors in that
code, so I'm not sure what to try to fix.

Sam


>
> On Wed, May 7, 2014 at 10:58 AM, Matthew Flatt <mflatt at cs.utah.edu> wrote:
>> I think the right change might be
>>
>>  (module evaluator racket
>>    ....
>>    (define (prep!)
>>      (parameterize ([current-namespace namespace])
>>        (dynamic-require (variable-reference->module-path-index
>>                          (#%variable-reference))
>>                         0)))
>>    ....
>>    (define-syntax phase1-phase0-eval
>>      (syntax-parser
>>       [(_ form:expr ...)
>>        #'(begin
>>            (prep!)
>>            (eval-syntax .....))])))
>>
>> The `prep!` function ensures that the enclosing module is available.
>>
>> At Wed, 7 May 2014 10:11:49 -0400, Sam Tobin-Hochstadt wrote:
>>> This program: https://gist.github.com/samth/e7b55fcef66da9b8416a works
>>> when line 33 is uncommented, otherwise it gives the error:
>>>
>>> ?: module mismatch;
>>>  attempted to use a module that is not available
>>>   possible cause:
>>>    using (dynamic-require .... #f)
>>>    but need (dynamic-require .... 0)
>>>   module: (submod "weird.rkt" evaluator)
>>>   phase: 0
>>>   in: phase1-phase0-run
>>>   context...:
>>>    weird.rkt: [running body]
>>>
>>> From reading the docs on `dynamic-require`, I can see that
>>> `(dynamic-require m 'f)` doesn't make anything available for higher
>>> phases.  However, the actual `dynamic-require` in the program is just
>>> for a function -- the need for higher phases is an implementation
>>> detail that's leaking in because it doesn't behave like a regular
>>> value wrt `dynamic-require`.
>>>
>>> Is there something I can change in the implementation of the internals
>>> of `f` so that clients of `f` don't need to do the extra
>>> `(dynamic-require m 0)` in order for `f` to work?
>>>
>>> Sam
>>> _________________________
>>>   Racket Developers list:
>>>   http://lists.racket-lang.org/dev

Posted on the dev mailing list.