[racket] Calling eval from the web server

From: Steve Knight (stknig at gmail.com)
Date: Thu Sep 30 08:02:34 EDT 2010

Yes, that definitely does help.   I was figuring this out and trying
to grok the docs and I also hit upon define-namespace-anchor which
seemed like it would do the job and does in fact look like it works
like I want it to.  Good to hear I'm on the right track.

My eval definitely does contain at least one error in the one I
pasted, apologies for the confusion on that.   But there was
definitely a problem with 'last' not being in the namespace, because
that was the first error that led me down this path.



On Thu, Sep 30, 2010 at 11:05 AM, YC <yinso.chen at gmail.com> wrote:
> Steve -
> Others will correct me if I have this wrong, but IIRC #:servlet-namespace is
> for sharing the namespace with other servlet modules, not for defining the
> namespace for eval.
> It looks like by default the current-namespace is empty (maybe web-server
> set it to racket/base but in repl it's empty), so parameterize or explicitly
> pass in a well defined namespace appears to be the way to go.  The simplest
> way I've found is using the module's namespace, since parameters and structs
> will be instantiated again in another module so if you use them your code
> will "mysteriously" fail if you don't use the "same" namespace (there are
> other ways of achieving the same effect but more complicated).
> To do so use define-namespace-anchor in the module, and then convert it into
> a namespace via namespace-anchor->namespace.  You can then parameterize or
> explicitly pass it into eval.
> Also I would suggest you replace "FAIL" with (format "FAIL: ~a" (exn-message
> f)) instead, so you can see the actual error that would aid debugging.  Your
> eval contains an error as it needs a quote for the list (1 2 3).  Not sure
> if your problem was due to this missing quote or not, as it could be just a
> typo for the email, but having the actual error message will aid the
> determination.
> HTH.  Cheers,
> yc
> On Thu, Sep 30, 2010 at 1:40 AM, Steve Knight <stknig at gmail.com> wrote:
>> Hello,
>> I'm using Racket 5.0.1 (from emacs) and I'm having trouble
>> understanding some behaviour I'm seeing in the web server.
>> If I start a servlet and dispatch some URL to this function:
>> (define (ev request)
>>   `(div (h1 "Last = " ,(format "~A" (last '(1 2 3))))
>>             (h1 "Last = " ,(format "~A"
>>                                    (with-handlers ((exn:fail? (lambda
>> (f) "FAIL")))
>>                                      (eval '(#%top-interaction .
>> (last (1 2 3)))))))))
>> I get "Last = 3" and "Last = FAIL" as the result, and I think I
>> understand why.   Looking at the code of the web-server I think it is
>> because the web-server places each servlet in its own namespace and
>> that namespace does not include racket/list.   Therefore I think what
>> is happening is that the first 'last' is compiled (from #lang racket)
>> and so is fine and the second 'last' is not and so relies on the
>> current-namespace.   Now because of the namespace fandangling done to
>> preserve servlet separation, current-namespace is made from
>> 'make-base-namespace' and so does not include racket/list.   So far so
>> good.
>> I can make this work by changing the call to eval to pass a well-known
>> namespace to 'eval' but that is a bit awkward (and feels a bit wrong).
>>  It seems like the right thing to do is to use the
>> #:servlet-namespace option in serve/servlet (i.e.
>> "#:servlet-namespace '(racket/list)") but when I try it it has no
>> obvious effect although looking at the web-server code it seems like
>> it should.
>> Can someone tell me what I'm doing wrong?!
>> Steve

Posted on the users mailing list.