After studying DrRacket source code for a long time, I believe I found the answer.
`enter!` is essentially: (dynamic-require path #f) (current-namespace (module->namespace path)) But the key seems to be to use the `configure-runtime` (if any) provided by the module's language's language-info. Also, this must be done _before_ actually requiring the module. Based on DrRacket, I now do this: ;; Load language-info, if any (define info (module->language-info path #t)) (displayln info) (when info (define get-info ((dynamic-require (vector-ref info 0) (vector-ref info 1)) (vector-ref info 2))) (define configs (get-info 'configure-runtime '())) (for ([config (in-list configs)]) ((dynamic-require (vector-ref config 0) (vector-ref config 1)) (vector-ref config 2))) (define cr-submod `(submod ,path configure-runtime)) (when (module-declared? cr-submod) (dynamic-require cr-submod #f))) ;; Require the module and use its namespace: (namespace-require path) (current-namespace (module->namespace path)) And finally for bonus points, give a clearer error message if the language doesn't define any #%top-interaction: ;; Check that the lang defines #%top-interaction (unless (memq '#%top-interaction (namespace-mapped-symbols)) (error 'run "lang doesn't support a REPL (no #%top-interaction)")))) Doing this appears to make my Emacs racket-mode work correctly, at least for the simple Typed Racket problem example I showed. 1. "It works". But is this correct? 2. Although I don't use `enter!` in racket-mode, I would be happy to submit a PR to add similar to `enter!` -- or if backward compatibility is a concern, add a variation that is `language-info`-aware. Thoughts? ____________________ Racket Users list: http://lists.racket-lang.org/users