Subject: Re: Using C libraries?
From: rpw3@rigden.engr.sgi.com (Rob Warnock)
Date: 2000/04/29
Newsgroups: comp.lang.scheme
Message-ID: <8edmli$53sgs$1@fido.engr.sgi.com>
felix <felix@anu.ie> wrote:
+---------------
| Without low-level support multiple values can not be implemented completely.
+---------------

I think I disagree. I think it *can* be implemented completely, though not
particularly efficiently. Granted, the naive student version:

	> (define values list)
	> (define (call-with-values producer consumer)
	    (apply consumer (producer)))
	> (call-with-values (lambda () (values 4 5))
			    (lambda (a b) (* a b)))
	==> 20
	> 

*almost* works, as you see, but unfortunately the "producer" thunk is
not required to use "values" to return its result. (Oops!) Specifically,
in R5RS there's this example, which fails with the above:

	> (call-with-values * -)
	apply: expects type <proper list> as 2nd argument, given: 1
	> 

But all is not lost. The following somewhat uglier hack suffices, I think:

	> (define values 'not-yet)
	> (define call-with-values 'not-yet)
	> (let ((magic (cons #f #f)))
	    (set! values
	      (lambda vals (cons magic vals)))
	    (set! call-with-values
	      (lambda (producer consumer)
	        (let ((v (producer)))
		  (if (and (pair? v) (eq? (car v) magic))
		    (apply consumer (cdr v))
		    (consumer v))))))

and seems to work:

	> (call-with-values (lambda () (values 4 5))
			    (lambda (a b) (* a b)))
	==> 20
	> (call-with-values * -)
	==> -1
	> 


-Rob

-----
Rob Warnock, 41L-955		rpw3@sgi.com
Applied Networking		http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673
1600 Amphitheatre Pkwy.		PP-ASEL-IA
Mountain View, CA  94043