[plt-scheme] Using eval in modules

From: Richard Cleis (rcleis at mac.com)
Date: Sun Jun 24 00:08:47 EDT 2007

I don't believe your test case is relevant; evaluating an expression  
as the module is being loaded is not the same thing as evaluating an  
expression after the namespace is satisfied.  The following example  
might be closer to what you want.  In this case, eval-any-input is  
called from outside the module so that the argument can be returned  
for proof of concept.  However, you can write threads in the module  
that require no interaction from the requiring program.

(module simple-socket mzscheme
   (define  buffer (make-bytes 128))
   (define  udp-socket (udp-open-socket))

   (udp-bind! udp-socket "127.0.0.1" 12345)

   (define  (eval-any-input)
     (let-values
         (((n-rxed ip port)
           (udp-receive! udp-socket buffer)))
       (eval
        (read
         (open-input-string
          (substring (bytes->string/utf-8 buffer)
                     0
                     n-rxed))))))

   (define  (provided-f arg)
     arg)

   (provide eval-any-input
            provided-f))

(require simple-socket)

(let  ((the-socket  (udp-open-socket)))
   (udp-send-to the-socket
                "127.0.0.1"
                12345
                (string->bytes/utf-8 "(provided-f 'modulated- 
argument)"))
   (udp-close the-socket))

(eval-any-input)


rac




On Jun 23, 2007, at 11:08 AM, Jean-Pierre Lozi wrote:

> Thanks for your answers,
>
> Actually, what I am trying to do is quite simple : at some point in  
> my program, I get different messages (strings). I am trying to call  
> the appropriate function depending on the message I received.
>
> Of course I could dispatch the messages using cond - calling the  
> right function for each message. But I thought it would look nicer  
> using a function :
>
> (define (dispatch-message message)
>      ((let-values (((sender command args) (parse-message message)))
>         (let ((function (string->symbol
>                  (string-append "answer-"
>                                 (string-downcase command) "- 
> command"))))
>           ((eval function) sender command args)))))))
>
> Of course, using the hash-table approach is similar to the cond  
> approach. Such a function could be unsafe, but I could test the  
> message with member before calling eval, in order to be sure that  
> the handling function exists.
>
> From what you all said, I understand that it is impossible. Too  
> bad. I guess I'll have to choose the cond/hashtable approach or to  
> avoid modules :)
>
> Well, if you have other ideas...
>
> On 6/23/07, Danny Yoo <dyoo at cs.wpi.edu> wrote:
>
>
> On Sat, 23 Jun 2007, Jean-Pierre Lozi wrote:
>
> > This works because you are calling (eval-string-with-1 "abc") from
> > outside the module - but it doesn't when the function is called  
> from the
> > inside the module. For instance :
> >
> > (module foo mzscheme
> >  (define  (abc x)
> >    (display "foo")
> >    (newline))
> >
> >  (define  (eval-string-with-1 string)
> >    ((eval (string->symbol string)) 1))
> >
> > (eval-string-with-1 "abc")
> >
> >  (provide eval-string-with-1
> >           abc))
> >
> > (require foo)
> >
> > Doesn't work. And that's what I need to do :/
>
> Hello Jean-Pierre Lozi,
>
> Question: do you really need the full power of eval?  What are you  
> really
> trying to do?
>
>
> If you're trying to expose a few functions to the outside world for
> dynamic dispatch, then rather than eval, then would a simpler dispatch
> table approach work for you?
>
> Here's what it might look like:
>
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> (module foo mzscheme
>    (require (lib "etc.ss"))
>
>    (define (abc x)
>      (display "foo")
>      (newline))
>
>    (define registered-handlers (hash-table 'equal
>                                            ("abc" abc)))
>    (define (eval-string-with-1 string)
>      ((hash-table-get registered-handlers string) 1)))
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>
> This requires no eval trickiness, and is much safer in terms of  
> limiting
> what kind of mischief the caller can do.  If the user tries to eval
> something that's not in the dispatch table, we can reliably catch that
> kind of thing.
>
> In contrast, the eval approach exposes the full power of the language,
> including all the primitives, so in your original approach, stuff  
> like:
>
>      (eval-string-with-1 "exit")
>
> will kill the runtime.
>
>
>
> -- 
> Jean-Pierre Lozi
> http://www.lozi.org
> mailto: jean-pierre at lozi.org
> _________________________________________________
>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20070623/363ffbbf/attachment.html>

Posted on the users mailing list.