[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
multiple values
And this is the feature I'm most critical of. Unless an implementation
does support the truncation feature, I don't see any reason why we should
require that "(values e)" be equivalent to "e". I would like to feel
free to signal an error if "(values e)" is returned to a context that
is not prepared to accept multiple values.
The question is whether you want to catch your personal errors, or you
want to catch everyone else's errors.
1) If you want to catch everyone else's errors, you don't gain
anything by making this additional restriction. No one but you, and I
suspect not even you, is going to write the following code:
(with-values
(lambda ()
<some code>)
(lambda (k) ; Single value expected
<more code>))
Given this, everyone (except perhaps you) will redefine values in the
following way:
(define (lax-values . all)
(if (not (singleton? all))
(apply values all)
(car all)))
Furthermore, if ACCEPTS? is in the language, people will do the
following
(define (lax-with-values generator recvr)
(if (not (arity-is-1? recvr))
(with-values generator recvr)
(let ((value (generator)))
(recvr value))))
Where
(define (singleton? list)
(and (pair? list)
(null? (cdr list))))
(define (arity-is-1? procedure)
(and (accepts? procedure 1)
(not (accepts? procedure 0))
(not (accepts? procedure 2))))
and you won't gain any error checking on everyone else's code.
[PS: I realize that lax-values above has a bug, but it will do for
most people. The bug can be fixed with ACCEPTS? in the following way:
(define (lax-values . all)
(if (not (singleton? all))
(apply values all)
(call-with-current-continuation
(lambda (k)
(if (arity-is-1? k)
(car all)
(apply values all))))))
]
2) If you want to catch your own errors, you (personally) can use the
following versions instead:
(define (dyb-with-values generator recvr)
(with-values generator
(lambda all
(if (< (length all) 2)
(error "dyb-with-values: Mismatch" all)
(apply recvr (cddr all))))))
(define (dyb-values . all)
(apply values (cons 'ignore-0 (cons 'ignore-1 all))))