title: Module meta-language in Racket
body: <p>I'm trying to write in Racket a module meta-language <code>mylang</code>, which accepts a second language to which is passes the modified body, such that:</p>
  
  <p></p>
  
  <pre class="lang-lisp prettyprint-override"><code>(module foo mylang typed/racket body)
  </code></pre>
  
  <p>is equivalent to:</p>
  
  <pre class="lang-lisp prettyprint-override"><code>(module foo typed/racket transformed-body)
  </code></pre>
  
  <p>where the <code>typed/racket</code> part can be replaced with any other module language, of course.</p>
  
  <p>I attempted a simple version which leaves the body unchanged. It works fine <a href="http://pasterack.org/pastes/24047">on the command-line</a>, but gives the following error when run in DrRacket:</p>
  
  <pre class="lang-lisp prettyprint-override"><code>/usr/share/racket/pkgs/typed-racket-lib/typed-racket/typecheck/tc-toplevel.rkt:479:30: require: namespace mismatch;
   reference to a module that is not available
    reference phase: 1
    referenced module: "/usr/share/racket/pkgs/typed-racket-lib/typed-racket/env/env-req.rkt"
    referenced phase level: 0 in: add-mod!
  </code></pre>
  
  <p>Here's the whole code:</p>
  
  <pre class="lang-lisp prettyprint-override"><code>#lang racket
  
  (module mylang racket
    (provide (rename-out [-#%module-begin #%module-begin]))
    (require (for-syntax syntax/strip-context))
    (define-syntax (-#%module-begin stx)
      (syntax-case stx ()
        [(_ lng . rest)
         (let ([lng-sym (syntax-e #'lng)])
           (namespace-require `(for-meta -1 ,lng-sym))
           (with-syntax ([mb (namespace-symbol-&gt;identifier '#%module-begin)])
             #`(mb . #,(replace-context #'mb #'rest))))])))
  
  (module foo (submod ".." mylang) typed/racket/base
    (ann (+ 1) Number))
  
  (require 'foo)
  </code></pre>
  
  <hr>
  
  <p><strong>Requirements (i.e. solutions I'd rather avoid):</strong></p>
  
  <ul>
  <li>Adding a <code>(require (only-in typed/racket))</code> inside the <code>mylang</code> module makes this work, but I'm interested in a general solution, where <code>mylang</code> does not need to know about <code>typed/racket</code> at al (i.e. if somebody adds a new language <code>foo</code>, then <code>mylang</code> should work with it out of the box).</li>
  <li><p>Also, I'm not interested in tricks which declare a submodule and immediately <code>require</code> and re-<code>provide</code> it, <a href="https://github.com/AlexKnauth/dotmethod/blob/master/dotmethod/lang/reader.rkt#L29">as is done here</a>, because this changes the path to the actual module (so <code>main</code> and <code>test</code> loose their special behaviour, for example).</p>
  
  <p>It is also slower at compile-time, as submodules get <a href="http://docs.racket-lang.org/reference/syntax-model.html#%28tech._visit%29">visited</a> and/or <a href="http://docs.racket-lang.org/reference/eval-model.html#%28tech._instantiation%29">instantiated</a> more times (this can be seen by writing <code>(begin-for-syntax (displayln 'here))</code>, and has a noticeable impact for large <code>typed/racket</code> programs.</p></li>
  <li><p>Bonus points if the arrows in DrRacket work for built-ins provided by the delegated-to language, e.g. have arrows from <code>ann</code>, <code>+</code> and <code>Number</code> to <code>typed/racket/base</code>, in the example above.</p></li>
  </ul>