<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">After playing around with Asumu’s branch to use require again instead of local-require, submodules still don’t work. I’m not sure why, but I’ve collected a series of examples of how different things fail in different ways. Perhaps someone more intimately familiar with the internals of Typed Racket and Racket’s module system can help to figure something out from this information.</div><div class=""><br class=""></div><div class="">First, I have this simple program:</div><div class=""><br class=""></div><div class=""><div class=""><font face="Courier" class="">#lang typed/racket/base</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">(require (for-syntax racket/base</font></div><div class=""><font face="Courier" class=""> syntax/parse</font></div><div class=""><font face="Courier" class=""> typed-racket/private/syntax-properties))</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">(define-syntax (begin-ignored stx)</font></div><div class=""><font face="Courier" class=""> (syntax-parse stx</font></div><div class=""><font face="Courier" class=""> [(_ ex:expr ...)</font></div><div class=""><font face="Courier" class=""> (quasisyntax/loc stx</font></div><div class=""><font face="Courier" class=""> #,(ignore #'(begin ex ...)))]))</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">(module foo racket</font></div><div class=""><font face="Courier" class=""> (define x 7)</font></div><div class=""><font face="Courier" class=""> (provide x))</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">(require 'foo)</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">(begin-ignored</font></div><div class=""><font face="Courier" class=""> x)</font></div></div><div class=""><br class=""></div><div class="">This fails with the following error message:</div><div class=""><br class=""></div><div class=""><div class=""><font face="Courier" class="">link: module mismatch;</font></div><div class=""><font face="Courier" class=""> possibly, bytecode file needs re-compile because dependencies changed</font></div><div class=""><font face="Courier" class=""> importing module: 'explode</font></div><div class=""><font face="Courier" class=""> exporting module: (submod "/tmp/explode.rkt" foo)</font></div><div class=""><font face="Courier" class=""> exporting phase level: 0</font></div><div class=""><font face="Courier" class=""> internal explanation: variable not provided (directly or indirectly) in: x</font></div></div><div class=""><br class=""></div><div class="">This is bizarre, and rather unhelpful. Note that this shouldn't involve any typechecking at all—using ignore should prevent that from happening—but somehow TR’s still making this fail. However, swapping typed/racket/base for typed/racket/base/no-check (perhaps unsurprisingly) makes it work fine.</div><div class=""><br class=""></div><div class="">Next up, I tried cheating a bit by using two submodules instead of just one. I hoped the following program would be a hacky workaround:</div><div class=""><br class=""></div><div class=""><div class=""><font face="Courier" class="">#lang typed/racket/base</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">(module foo racket/base</font></div><div class=""><font face="Courier" class=""> (define x 7)</font></div><div class=""><font face="Courier" class=""> (provide x))</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">(module bar typed/racket/base</font></div><div class=""><font face="Courier" class=""> (require/typed</font></div><div class=""><font face="Courier" class=""> (submod ".." foo)</font></div><div class=""><font face="Courier" class=""> [x Number])</font></div><div class=""><font face="Courier" class=""> (define y : Number x)</font></div><div class=""><font face="Courier" class=""> (provide y))</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">(require 'bar)</font></div></div><div class=""><font face="Courier" class="">y</font></div><div class=""><br class=""></div><div class="">Like the above, this program typechecks. However, it still fails with the exact same error message. Still, I was able to glean some more information from this oddity. Removing the final line of the program causes it to run successfully, as expected. Now, evaluating <font face="Courier" class="">y</font> in the REPL gives me a different error message:</div><div class=""><br class=""></div><div class=""><div class=""><font face="Courier" class="">Type Checker: missing type for identifier;</font></div><div class=""><font face="Courier" class=""> consider using `require/typed' to import it</font></div><div class=""><font face="Courier" class=""> identifier: y</font></div><div class=""><font face="Courier" class=""> from module: (submod . bar) in: y</font></div></div><div class=""><br class=""></div><div class="">If anything, this feels even stranger. The provided variable is clearly typed, but apparently TR has decided it’s not. Why? I don’t know.</div><div class=""><br class=""></div><div class="">As a semi-interesting side note, simply changing the #lang declaration of the above program to racket/base makes it work without a hitch, demonstrating that the problem doesn’t seem to be within the require/typed form itself, but somehow has something to do with how TR handles the resulting binding?</div><div class=""><br class=""></div><div class="">Any ideas on what’s happening here? I’ve tried digging through some of the Typed Racket source, but I’m really too unfamiliar with how everything fits together to figure it out just yet.</div><div class=""><br class=""></div><div class="">Also, Asumu, a related problem: are there any issues with changing local-require back to require that would break anything else? Or can you possibly implement that change in TR with no issues?</div><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 12, 2015, at 08:06, Asumu Takikawa <<a href="mailto:asumu@ccs.neu.edu" class="">asumu@ccs.neu.edu</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">On 2015-01-11 23:29:28 -0800, Alexis King wrote:<br class=""><blockquote type="cite" class=""> This is a real problem, since Typed Racket’s require/typed form uses<br class=""> local-require, which in turn uses syntax-local-lift-require. This means<br class=""> that require/typed currently cannot require submodules.<br class=""></blockquote><br class="">Interesting, thanks for tracking this down! IIRC Typed Racket switched<br class="">to using `local-require` in order to support uses of `require/typed` in<br class="">the REPL/top-level.<br class=""><br class="">(as the comment on<br class=""> <a href="https://github.com/racket/typed-racket/blob/master/typed-racket-lib/typed-racket/utils/require-contract.rkt#L57" class="">https://github.com/racket/typed-racket/blob/master/typed-racket-lib/typed-racket/utils/require-contract.rkt#L57</a><br class=""> notes)<br class=""><br class="">So one possible solution is to switch back to using `require` but also<br class="">overhaul how TR handles the REPL to avoid these issues.<br class=""><br class="">(for the REPL, local expanding everything at once doesn't work well<br class=""> because an early definition in a `begin` has to be registered<br class=""> before later clauses are typechecked)<br class=""><br class="">Cheers,<br class="">Asumu<br class=""></div></blockquote></div><br class=""></body></html>