[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Multiple values in Dylan



[I first sent these suggestions to Andrew Shalit at Apple back in 
June, long before there was a mailing list.] 

I like multiple values, but I'm sorry that Dylan has made them as 
sloppy as they are in Common Lisp.  I think they should be defined 
to be, in effect, the arguments to the current continuation: no more, 
no less. 

If we did this, then we wouldn't have to make all those hack-y exceptions 
about supplying extra #f's and ignoring extra values.   Forms where 
(VALUES) occurred in a position that required a value could be flagged 
as errors, just as any function call would if it had the wrong number 
of arguments.  If the continuation wants to ignore values, it can 
do so, just as functions can. 

This would also allow us to avoid having to say that there are actually 
two false values, #f and "no values".  Ugh. 

All the forms that don't produce "real" values, like FOR-loops 
whose end-tests are true but which have no result-forms, should be 
defined as returning no values.  If I want such a form to return #f, 
I can write #f. 

We should generalize COMPOSE so that it uses multiple values: if 
one function returns N values, then all N should be passed to the 
"next" function.  This would allow us to define (COMPOSE) [i.e., 
with no arguments] in a consistent fashion. This is what I used in 
Common Lisp: 

(defun compose (&rest fns)
  (if (null fns)
      #'values
      #'(lambda (&rest arglist)
          (labels ((z (fns)
                      (if (null (cdr fns))
                          (apply (car fns) arglist)
                          (multiple-value-call (car fns) (z (cdr fns))))))
            (z fns)))))


By the way, is there a way to write the Dylan equivalent of
    (multiple-value-call f exp)
other than
    (bind ((#rest args exp)) (apply f args)) ?
In Common Lisp, multiple-value-call was the primitive from which 
you could build multiple-value-bind, multiple-value-setq, etc. Of 
course, Dylan doesn't specify what type of sequence is produced by 
#rest (it needn't be a list, for example), so perhaps compilers are 
expected to provide an internal, efficient values->sequence function.


--Jim Meehan