[plt-scheme] send/suspend/dispatch and javascript?

From: Bob McCormick (bobm at adt.com)
Date: Mon Nov 29 19:02:14 EST 2004

No, I've been unsuccessful so far.   I received a reply from Peter 
Hopkins suggesting I use his version of send/suspend/dispatch instead 
of the version from the Scheme Cookbook because it gives the programmer 
access to the generated URL.

I've tried to copy Peter's version of send/suspend/dispatch from his 
paper (located here: http://continue.cs.brown.edu/research/ ) and use 
it with a simple example page like the one from the Scheme Cookbook 
entry on send/suspend/dispatch, but I must be doing something wrong.   
In the logs for the web server I'm getting the message "Servlet 
exception: "reference to undefined identifier: send/suspend"".

Here's the code I've got so far:

(require (lib "unitsig.ss")
          (lib "servlet-sig.ss" "web-server")
          (lib "servlet-helpers.ss" "web-server")
          (lib "contract.ss")
          )


(define embed/url-contract
   ((-> string?) . case-> .
    ((request? . -> . any) . -> . string?)
    (string? (request? . -> . any) . -> . string?)))

(define page-func/ssd-contract
   (embed/url-contract . -> . any))

(define/contract send/suspend/dispatch
   (page-func/ssd-contract . -> . any)
   (lambda (page-func)
     (let* ([embed-hash (make-hash-table)]
            [request (send/suspend
                      (lambda (k-url)
                        (page-func
                         (case-lambda
                           [() k-url]
                           [(embed-func)(let ([key (unique-hash-key 
embed-hash)])
                                          (hash-table-put! embed-hash 
key embed-func)
                                          (url-append/path k-url 
key))]))))]
            [path
             (post-servlet-path
              (url->string (request-uri request)))])
       (if (null? path)
           request
           ((hash-table-get
             embed-hash
             (string->number (car path))
             (lambda ()
               (lambda _
                 (send/back
                  `("text/plain"
                    "ERROR: Key was not found in "
                    "send/suspend/dispatch hash table")))))
            request)))))


(define unique-hash-key
   (lambda (ht)
     (let ([key (random 200000)])
       (let/ec exit
         (hash-table-get ht key (lambda () (exit key)))
         (unique-hash-key ht)))))

(define post-servlet-path
   (lambda (s-rul)
     (let([result (regexp-math "\\.ss(/[^;#\\?]*)" s-url)])
       (if result
           (filter
            (lambda (s) (> (string-length s) 0))
            (regexp-split "/" (cadr result)))
           null))))


(define url-append/path
   (lambda (s-url rel-path)
     (let ([url (string->url s-url)])
       (url->string
        (make-url
         (url-scheme url)
         (url-port url)
         (format "~a/~a" (url-path url) rel-path)
         (url-params url)
         (url-query url)
         (url-fragment url))))))

(unit/sig () (import servlet^)

   (define (page2 req)
     `(html (head (title "Page Two"))
            (body (h1 "Page Two"))))

   (define (page3 req)
     `((p (id "test") "Bye")))

   (send/suspend/dispatch
    (lambda (embed/url)
    `(html (head (title "Page One"))
           (body (h1 "Page One")
                 (p (a ((href ,(embed/url (lambda (request) (page2))))) 
"Page Two"))
                 (p (a ((href ,(embed/url (lambda (request) (page3))))) 
"Page three"))
                 (p ((id "test")) "hi")))
   )))


If anyone can tell me what I'm doing wrong I'd appreciate it.   I'm 
very new to Scheme.   I was going to re-writing some CGI's I've done 
previously in Perl as an exercise to learn Scheme, but maybe I've 
bitten off more than I can chew.   :-)

On Nov 26, 2004, at 10:56 AM, Matthias Felleisen wrote:

> Have you been able to fix this? Since HTML is just `text' for 
> servlets, 
> I don't see why this shouldn't work.
>
> -- Matthias 
>
>
>
> On Nov 22, 2004, at 2:51 PM, Bob McCormick wrote:
>
> >  For list-related administrative tasks:
>http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>  >
>  > With send/suspend/dispatch 
>  > <http://schemecookbook.org/view/Cookbook/WebDispatchOnLink> , is 
> there 
> > anyway to include the continuation URL into the arguments to a 
> > javascript function?   For example, instead of the HTML output like 
> > this:
>  >
>  > <a 
> href="http://localhost/servlets/test2.ss;id58*k1-419981834">Click 
> > Here</a>
>  >
>  > I'd like to be able to output something like this:
>  >
>  > <a href="#" 
> > onclick="liveUpdaterUri(http://localhost/servlets/test2.ss;id58*k1
> > -419981834)">Click Here</a>
>  >
>  > But I can't get send/suspend/dispatch to expand my function name 
> into 
> > a continuation url if it's within the quotes for the javascript.
>  >
>  >
>  > BTW.. Why would I want to do something like this?   I'd like to 
> take 
> > advantage of the Avi Bryants very cool liveUpdater script 
> > <http://www.cincomsmalltalk.com/userblogs/avi/blogView?
>  > showComments=true&entry=3268075684> .  For those of you who haven't 
> > seen it, it's a javascript that lets you replace elements of the 
> > current page.  The idea is to create richer, more responsive client 
> > interfaces by updating just those parts of the page than *need* to 
> > change instead of reloading the whole page.


Posted on the users mailing list.