[plt-scheme] send/suspend return values

From: Greg Pettyjohn (gregp at ccs.neu.edu)
Date: Mon Nov 22 11:59:31 EST 2004

On Nov 21, 2004, at 4:17 PM, Matthias Felleisen wrote:

> No. When you can (send/suspend f), send/suspend does not invoke f in 
> tail-position. Instead it names the result and makes sure it is a 
> response. I have to admit that after looking at the code I find it way 
> too defensive. The author should have instead stated the contract of 
> send/suspend as
>  (String -> X) -> X
> which would then allow f to return multiple values.

You're proposed contract for send/suspend would break the web-server.

It needs to be:  (string -> response) -> request

The web-server doesn't know how to make a response out of an arbitrary 
X and
the continuation of send/suspend needs to get a request.

A multi-valued send/suspend would have a contract like this:
(string -> response . X) -> request . X

I.e. the first of multiple values returned *to* send/suspend would be
a response and the first of multiple values returned *from* send/suspend
would be a request.

This is an interesting idea, because it allows the servlet writer to 
close the continuation
over the extra values.

Here's my take on the proposed pattern:

;; ****************************************

;; form-gen: X -> string -> request
;; generate a response generator
(define (form-gen . data)
   (lambda (url)
     F(url, data)))

;; client code for form-gen
(let ([request (send/suspend (form-gen some-data))])
   G(request, data))

;; ****************************************

;; form-and-data-gen: (-> (string -> request) . X)
;; generate a response generator and the data it is closed over
(define (form-and-data-gen)
   (let ([data ...])
      (lambda (url) F(data))

;; client code
(let-values ([(make-form data) (form-and-data-gen)])
   G((send/suspend make-form) data))

;; ****************************************
;; EXAMPLE 3 (using proposed multi-valued send/suspend)

;; form-and-data: (string -> response . X)
;; generate a response and the data it is closed over
(define (form-and-data url)
   (let ([data ...])
      `(html ... ,url ...)

;; client-code
(let-values ([(request data) (send/suspend form-and-data)])
   G(request data))

;; ****************************************
;; EXAMPLE 4 (using send/suspend/dispatch)

(let ([data ...])
    `(html ... ,(embed-procedure (lambda (request) G(request, data))))))

If I understand the pattern correctly, I think we've already got it 
thanks to Pete Hopkins.

Posted on the users mailing list.