[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))))