[racket-dev] A strange problem with namespaces
I see. The errors are about the modules that require "evaluator.rkt".
That is, the modules that use `phase1-phase0-eval` need to be
available, not just "evaluator.rkt", so that transformer bindings in
those modules can be used.
So,
(define (prep! varref)
(define p (variable-reference->resolved-module-path varref))
(when p
(parameterize ([current-namespace namespace])
(dynamic-require p 0))))
...
(define-syntax phase1-phase0-eval
(syntax-parser
[(_ form:expr ...)
#'(begin
(prep! (#%variable-reference))
(eval-syntax ....))]))
(define-syntax phase1-eval
(syntax-parser
[(_ form:expr ...)
#'(begin
(prep! (#%variable-reference))
(phase1-phase0-eval ....))]))
A way to look at it is that you want an anchor in each module that uses
`phase1-phase0-eval`, and `(#%variable-reference)` is the primitive
form of an anchor.
At Wed, 7 May 2014 11:43:39 -0400, Sam Tobin-Hochstadt wrote:
> 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