[racket] Evaluating Racket source files from within another Racket source file

From: Matthew Butterick (mb.list.acct at gmail.com)
Date: Sun Apr 28 11:28:46 EDT 2013

>
> 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 <mflatt at 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 <mflatt at 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.acct at 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.acct at 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
> > >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130428/5648c8d5/attachment-0001.html>

Posted on the users mailing list.