On Mon, Oct 14, 2013 at 6:20 PM, Matthew Butterick <mb.list.a...@gmail.com>wrote:
> I reviewed the docs about the module > registry<http://docs.racket-lang.org/reference/syntax-model.html?q=module%20registry#%28tech._module._registry%29>, > but just so I understand the principle behind this technique — > > When you call (namespace-attach-module orig-ns 'module-name), what you're > saying to the new namespace is "if you need module-name, use the one that's > already been imported into orig-ns". Is this right? > > Right. > And if so, do I improve performance by adding another (namespace-attach-module > ...) declaration for each module that will never need to be reloaded in the > eval namespace? > > Right. > BTW I tried your suggestion on the quasicode, and it was indeed faster. > However, when I moved it back into the real code, there was no improvement > — in fact, the real code became slower. Running the real code through > profile suggests that most of the time is being spent traversing the > imports (which is consistent with my observation that the complexity of the > page itself doesn't count for much). So whatever I can do to avoid > re-importing modules will probably be the winning technique. > > Which module's imports, do you know? Robby > Thanks. > > > On Mon, Oct 14, 2013 at 11:22 AM, Robby Findler < > ro...@eecs.northwestern.edu> wrote: > >> Did you try using namespace-attach-module to attach 'racket and >> 'web-server/templates? Something like: >> >> (define orig-ns (current-namespace)) >> (parameterize ([current-namespace (make-base-empty-namespace)]) >> (namespace-attach-module orig-ns 'racket) >> (namespace-attach-module orig-ns 'web-server/templates) >> (namespace-require 'racket) >> (eval `(begin >> (require web-server/templates) >> (require ,my-source-path-string) >> (include-template ,my-template-path-string)) >> (current-namespace))) >> >> But 7 seconds seems remarkably long (I see a speed up of about 50% for >> that function (with the my-source-path-string and my-template-path-string >> lines commented out): from 250 to 170 msec). >> >> It may be that your .zo files or something are not up to date. So you may >> want to stick a 'raco make' somewhere in there to avoid recompiling your >> files every time and just recompile the ones that changed. >> >> Robby >> >> >> >> >> On Mon, Oct 14, 2013 at 1:14 PM, Matthew Butterick < >> mb.list.a...@gmail.com> wrote: >> >>> At RacketCon I talked about my Pollen system for making web pages. >>> Though I don't use the Racket webserver to provide live generation of web >>> pages, I do use it to provide a kind of browser-assisted REPL for >>> development. As I edit the project files, I want to reload the URL in the >>> browser and see the changes (without restarting the webserver). >>> >>> Moreover, since it's a development tool, it wants to be maximally >>> dynamic. For instance, I might be editing source files containing page >>> content, or the design templates (which might also contain Racket code), or >>> supporting Racket libraries (e.g., CSS generators). >>> >>> Jay has suggested that this can be done with eval. And indeed it can. >>> Here's the quasicode I use: >>> >>> (parameterize ([current-namespace (make-base-empty-namespace)]) >>> (namespace-require 'racket) >>> (eval `(begin >>> (require web-server/templates) >>> (require ,my-source-path-string) >>> (include-template ,my-template-path-string)) >>> (current-namespace)))) >>> >>> This works great, with one wrinkle: it's the slowest operation in the >>> whole system, taking about 7-8 secs to render each page. This is not a >>> grave hardship, and certainly faster than restarting the web server. But >>> I'd still be curious if I'm overlooking a better approach. >>> >>> In general, the render time is fairly consistent regardless of what's in >>> the page, which suggests to me that most of the expense comes from setting >>> up the fresh namespace. I did try making a namespace separately and reusing >>> it, but that didn't work (code wouldn't get reloaded). Is there a way to >>> "clean" a namespace that's cheaper than setting up a new one? >>> >>> Another option I considered is starting up another instance of Racket in >>> a subprocess, but it would need to be made into a synchronous operation. >>> Long drive for a short day at the beach, etc. >>> >>> It's also possible that I'm running up against the irreducible cost of >>> high-quality eval, in which case, I will accept it and move on. >>> >>> >>> Matthew Butterick >>> >>> >>> >>> >>> On Thu, Jun 6, 2013 at 7:36 PM, Greg Hendershott < >>> greghendersh...@gmail.com> wrote: >>> >>>> Great timing! It's been on my short list to make my static blog >>>> generator more flexible. From >>>> http://docs.racket-lang.org/web-server/templates.html I got the idea >>>> that it would be suitable only for static templates, but now I >>>> understand that's not the case. Today I made a topic branch using this >>>> approach that's working well, which I plan to merge after some testing >>>> and polishing. >>>> >>>> p.s. Maybe it's obvious, but because `include-template` uses >>>> `include-at/relative-to/reader`, it won't include a template if you >>>> give it a full path. Maybe there's a more-elegant way, but I found it >>>> worked to parameterize `current-directory` around the call to `eval`. >>>> >>>> >>>> On Wed, Jun 5, 2013 at 4:45 PM, Jay McCarthy <jay.mccar...@gmail.com> >>>> wrote: >>>> > While it is supposed to be pithy, it is also serious. >>>> > >>>> > When I wrote it, I imagine that people would do something like this: >>>> > >>>> > #lang racket/base >>>> > (require web-server/templates) >>>> > >>>> > (define (template-content t x) >>>> > (eval #`(let ([x #,x]) (include-template #,t)))) >>>> > >>>> > (template-content "t.txt" 5) >>>> > (template-content "t.txt" 6) >>>> > >>>> > and trust that the template wouldn't include @(system "rm -fr /"). I >>>> > think that a simple eval works just fine for when you, the programmer, >>>> > want to change the content dynamic (although I'd say it is better to >>>> > use the web-server language so you can restart with the same >>>> > continuations, etc.) >>>> > >>>> > Your solution is great for a template that a user provides, although >>>> > it has the hole that the template could call @include-template and >>>> > maybe find itself and go into a infinite loop, so it's not totally >>>> > "secure" unless you use a sandbox. >>>> > >>>> > Jay >>>> > >>>> > On Wed, Jun 5, 2013 at 1:53 PM, Joe Gibbs Politz <j...@cs.brown.edu> >>>> wrote: >>>> >> I'm writing a web server in a #lang that doesn't support macros or >>>> >> syntactic abstraction. I would like to be able to use some sort of >>>> >> templating dynamically with bindings given by values, e.g. >>>> >> >>>> >> template.render("page-with-hole-for-username.html", { username: >>>> "Joe" }) >>>> >> >>>> >> The FAQ ( >>>> http://docs.racket-lang.org/web-server/faq.html#(part._.How_do_.I_use_templates__dynamically__) >>>> ) >>>> >> in the documentation for templates ends with this pithy >>>> >> recommendation: >>>> >> >>>> >> "If you insist on dynamicism, there is always eval." >>>> >> >>>> >> I assume this isn't intended seriously, and instead to discourage >>>> what >>>> >> I'm asking about, but I'm unfortunately not seeing another way to >>>> >> write my program. The code at the end of this message seems like the >>>> >> best I can do while being relatively safe, but also like a dubious >>>> >> inclusion on a web server given the eval. >>>> >> >>>> >> Is this the best I can hope for? Is there another collection I >>>> should >>>> >> be looking into? Any other recommendations? >>>> >> >>>> >> Thanks! >>>> >> Joe P. >>>> >> >>>> >> >>>> >> #lang racket/base >>>> >> >>>> >> (require >>>> >> web-server/templates) >>>> >> >>>> >> (define (render-template filename dict) >>>> >> (define namespace-for-template (make-empty-namespace)) >>>> >> (namespace-attach-module (current-namespace) 'web-server/templates >>>> >> namespace-for-template) >>>> >> (hash-map dict >>>> >> (lambda (key value) >>>> >> (define name-of-identifier (string->symbol key)) >>>> >> (namespace-set-variable-value! >>>> >> name-of-identifier >>>> >> value >>>> >> #f >>>> >> namespace-for-template))) >>>> >> (parameterize [(current-namespace namespace-for-template)] >>>> >> (namespace-require 'web-server/templates)) >>>> >> (define to-eval #`(include-template #,(datum->syntax >>>> >> #'render-template filename))) >>>> >> (eval to-eval namespace-for-template)) >>>> >> ____________________ >>>> >> Racket Users list: >>>> >> http://lists.racket-lang.org/users >>>> > >>>> > >>>> > >>>> > -- >>>> > Jay McCarthy <j...@cs.byu.edu> >>>> > Assistant Professor / Brigham Young University >>>> > http://faculty.cs.byu.edu/~jay >>>> > >>>> > "The glory of God is Intelligence" - D&C 93 >>>> > ____________________ >>>> > Racket Users list: >>>> > http://lists.racket-lang.org/users >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>>> >>> >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >>> >>> >> > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > >
____________________ Racket Users list: http://lists.racket-lang.org/users