require is a syntactic form with restricted syntax to allow determining dependencies without evaluation. Your example with define breaks this restriction. -Ian ----- Original Message ----- From: Matthew Butterick <mb.list.a...@gmail.com> To: Matthew Flatt <mfl...@cs.utah.edu> Cc: Racket mailing list <users@racket-lang.org> Sent: Sun, 28 Apr 2013 11:28:46 -0400 (EDT) Subject: Re: [racket] Evaluating Racket source files from within another Racket source file
> > The syntax of `enter!' is supposed to be like `require', where the > module name is not quoted OK, I see what you're saying. And yes, the enter! / require connection is noted in the docs. As a reader of docs, what trips me up here is that the docs for enter! and require both refer to a module-path, but they will not necessarily take as input something that returns #t for module-path?, for instance: (require "filename.rkt") ; works (define name "filename.rkt") (module-path? name) ; returns #t (require name) ; doesn't work However, dynamic-require works differently: (define name "filename.rkt") (module-path? name) ; returns #t (dynamic-require name 'foo) ;works I notice that dynamic-require uses the module-path? contract, and enter! and require apparently do not. So OK, I guess that's why they can be more restrictive. But then when I look up the meaning of module-path?, it says: Returns #t if v corresponds to a datum that *matches the grammar for module-path for require*, #f otherwise. That is, module-path? seems to be defined in terms of what require will accept, but in practice module-path? accepts more than require will. Which, if true, is strange. On Sun, Apr 28, 2013 at 6:11 AM, Matthew Flatt <mfl...@cs.utah.edu> wrote: > The syntax of `enter!' is supposed to be like `require', where the > module name is not quoted. If you remove the quote, then something like > > (enter! file/gif) > > doesn't work. > > > It would make sense to move the transitive module-reloading part of > `enter!' to a a new module and provide a `dynamic-re-require' function > that's similar to `do-enter!' --- and that would more directly be what > you want, I think. I'll look into that. > > > At Sun, 28 Apr 2013 00:09:13 -0700, Matthew Butterick wrote: > > Thanks, I'll try that. However, I still think there might be a bug in > > racket/enter.rkt. Currently lines 10-11 look like this: > > > > [(enter! mod flag ...) (andmap keyword? (syntax->datum #'(flag > ...))) > > #'(do-enter! 'mod '(flag ...))] > > > > But when I remove the quoting from mod in line 11, like so … > > > > [(enter! mod flag ...) (andmap keyword? (syntax->datum #'(flag > ...))) > > #'(do-enter! mod '(flag ...))] > > > > Then (enter! module-name-variable) works as hoped, and (enter! > > "module-name-string.rkt") still works too. > > > > Making it work proves nothing ;) I will file a bug report. > > > > Matthew Butterick > > > > > > > > On Sat, Apr 27, 2013 at 7:17 PM, Matthew Flatt <mfl...@cs.utah.edu> > wrote: > > > > > I think you probably want to create a new namespace for each > > > instantiation of the Scribble module, and attach Scribble (or whatever > > > modules you want to stay the same across runs) to the namespace before > > > `dynamic-require'ing the module in the new namespace: > > > > > > #lang racket/base > > > (require scribble/base) > > > > > > (define (re-run module-path) > > > (define ns (make-base-namespace)) > > > (namespace-attach-module (current-namespace) 'scribble/base) > > > (parameterize ([current-namespace ns]) > > > (dynamic-require module-path #f))) > > > > > > > > > At Sat, 27 Apr 2013 19:08:53 -0700, Matthew Butterick wrote: > > > > OK, so the proposed solution failed once I tried to pass in the > module > > > name > > > > as a variable. Even though enter! claims to take a module-path as an > > > > argument, this will not work: > > > > > > > > (define name "module.rkt") > > > > (module-path? name) ; reports #t > > > > (enter! name) ; error: collection "name" not found > > > > > > > > enter! is treating "name" as a module path instead of resolving it > as a > > > > defined term. What I can't tell is whether this is mandatory > behavior for > > > > enter!, or if it's a bug in the enter! macro. (I did look at > enter.rkt, > > > but > > > > this week, it's over my head.) > > > > > > > > Matthew Butterick > > > > > > > > > > > > On Sat, Apr 27, 2013 at 6:16 PM, Matthew Butterick > > > > <mb.list.a...@gmail.com>wrote: > > > > > > > > > Aha, combining enter! with dynamic-require seems to do the trick: > > > > > > > > > > (define (route req) > > > > > (enter! "module.rkt") > > > > > (define foo (dynamic-require "module.rkt" 'foo)) > > > > > (response/xexpr `(p ,(format "~a" foo)))) > > > > > > > > > > Once this route is running in the web server, I can make changes to > > > > > module.rkt, then click reload in the browser, and the changes will > > > appear > > > > > in the browser. > > > > > > > > > > If this is a terrible idea let me know, otherwise I'll consider > this > > > > > solved. > > > > > > > > > > > > > > > On Sat, Apr 27, 2013 at 9:56 AM, Matthew Butterick < > > > mb.list.a...@gmail.com > > > > > > wrote: > > > > > > > > > >> I'm building a website using Scribble as the source format. As a > > > > >> development tool, I've built a web server in Python that lets me > view > > > all > > > > >> my Scribble source files and look at them in different states of > > > > >> processing. To view the results of the Scribble files, the Python > > > server > > > > >> just sends the files to Racket via a system command (os.Popen) and > > > reads > > > > >> the result. This works but it's slow, because it has to launch a > new > > > > >> Racket thread for every request. > > > > >> > > > > >> I thought I could speed things up by rewriting the development web > > > server > > > > >> in Racket. But having tried a few approaches, I'm not sure how to > > > duplicate > > > > >> this functionality within a Racket web servlet: > > > > >> > > > > >> *(require <modulename>) * > > > > >> This only gets evaluated once, when the server is started. That > > > doesn't > > > > >> help, since the <filename> is going to be passed in as a parameter > > > while > > > > >> the server is running. > > > > >> > > > > >> *(dynamic-require <** modulename **>) * > > > > >> This gets evaluated only when invoked, and thus can take > <modulename> > > > as > > > > >> a parameter, but then <filename> can't be reloaded (this is > > > essential, as > > > > >> the point of the system is to be able to edit the files and see > the > > > changes > > > > >> in the web browser immediately) > > > > >> > > > > >> *(enter! <modulename>)* > > > > >> This reloads the file, but it's not clear how to get access to > names > > > > >> provided by <modulename>. (The documentation for enter! suggests > that > > > this > > > > >> is not how it's meant to be used anyhow.) > > > > >> > > > > >> Obviously, I could call a new instance of Racket as a system > command, > > > but > > > > >> that wouldn't offer any advantage over the current approach. > > > > >> > > > > >> > > > > >> I suppose what I'm looking for is an equivalent of the Python > > > > >> reload(<modulename>) command. > > > > >> > > > > >> > > > > >> Matthew Butterick > > > > >> > > > > > > > > > > > > > > ____________________ > > > > Racket Users list: > > > > http://lists.racket-lang.org/users > > > > ____________________ Racket Users list: http://lists.racket-lang.org/users