> Jay McCarthy writes: >> Modules don't evaluate to values. They have effects and they have >> exported symbols. If you want to observe the evaluation of your >> language's module, you'll have to look at one of those two things. >> Both are used by existing Racket languages and infrastructure: `raco >> test` relies on test modules making effects on a global box that >> counts how many tests ran and failed. `scribble` relies on inspecting >> an export named `doc`. In either case, I think you want to make >> `#%module-begin` capture the last expression and expose its value via >> an effect or an export.
Christopher Lemmer Webber writes: > Well I gave it a try and couldn't quite figure out how to make it work. > I tried writing out this file, dungeon/room-ch.rkt: > [...] > It just hangs, so I assume that the module never wrote to that channel. > I guess it probably wouldn't until it's required, but I have no idea how > to "require" this dynamically-read-in module to prime it? Wow, ok. So I figured, "this must be possible to talk to a module loaded at runtime, because I see in sandbox.rkt that when the user specifies a lang to the sandbox that it makes a module": (define (use-lang lang) `(module program ,lang . ,body)) So I figured that ok, there must be some way to evaluate a module and get it to "run", and it must be taking either of the approaches Jay mentioned. So I spent about an hour digging around in sandbox.rkt and taking notes thinking I'd find out where it did that. Well... I was in for a surprise. My assumptions appear to be wrong. As far as I can tell: - sandbox.rkt first sets up a fresh namespace to do the evaluation in (ok, expected) - Then later in evaluate-program: (define ns (syntax-case* program (module) literal-identifier=? [(module mod . body) (identifier? #'mod) (let ([mod #'mod]) (lambda () (for ([submod-name (in-list submod-names)]) (eval `(when (module-declared? '(submod (quote ,mod) ,submod-name) #f) (dynamic-require '(submod (quote ,mod) ,submod-name) #f)))) (module->namespace `(quote ,(syntax-e mod)))))] [_else #f])) sandbox.rkt is then piecing apart the module and taking the module path and adding it to the namespace?! Or at least preparing to, since this is wrapped in a lambda to be run later. - It actually appears that the program (the whole `(module ...)` structure is actually just eval'ed first, and *then* I guess the namespace is set up: (if (and (pair? program) (eq? 'begin (car program))) (eval* (cdr program)) (eval program)) (when ns (set! ns (ns))) - At the end of it the current-namespace is set to ns if indeed evaluate-program is dealing with a (module ...) thing: (when (namespace? ns) (current-namespace ns)) - Then later on when the user uses the sandboxed evaluator and passes in expressions, I guess that namespace is used and evaluation takes place in it. That is NOT what I was expecting. What I figured when I saw the `(module program ,lang . ,body) stuff was that the module would be evaluated on some sort of very generic module-dynamically-loaded-at-runtime way. That doesn't quite seem to be the case. This was a useful read; I'm still unsure if I'm reading it right though. I guess it seems to say "this tooling doesn't quite exist out of the box, but you can assemble something resembling it on your own"? -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/87v9rrh76f.fsf%40dustycloud.org.