Subject: Re: Using C libraries?
From: (Rob Warnock)
Date: 2000/04/29
Newsgroups: comp.lang.scheme
Message-ID: <8edmli$53sgs$>
felix <> 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 Warnock, 41L-955
Applied Networking
Silicon Graphics, Inc.		Phone: 650-933-1673
1600 Amphitheatre Pkwy.		PP-ASEL-IA
Mountain View, CA  94043