[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
multiple-values alternative with better destructuring
- To: info-dylan@cambridge.apple.com
- Subject: multiple-values alternative with better destructuring
- From: farrow@stephanie.hc.ti.com (Rob Farrow)
- Date: Mon, 4 Jan 93 11:02:39 CST
For me multiple values is nice to have when you have auxilliary
information being returned from a function. I've used this alot in
Common Lisp. The best example is a predicate which can optionally
give more than just true or false.
The only reason for not returning a list is ease of use/readability.
It is a nuisance to have to return a list and then destructure the
list every time, even though often all you want is the predicate
result. Even just wrapping FIRST around every call to the function
gets to be error prone and costly.
One major problem with multiple values, besides funky syntax of the
binding forms, is the inconsistency of handling. It appears that
DYLAN, correct me if I'm wrong, does not return multiple values from
all the primitive forms (Common Lisp makes this mistake too). This
can make binding multiple-values a pain, because I now need to be
aware which forms will and won't return multiple-values.
Before I propose a change, I want to discuss destructure bindings. One
of the nice things in the latest Common Lisp standard is
DESTRUCTURING-BIND. This allows the use of the robust MACRO
lambda-list format to bind values in a nested list. To me,
destructuring is the key to simplify multiple-values.
Simply allow BIND in DYLAN to do things similar to DESTRUCTURING-BIND
in Common Lisp. Then change the multiple-values specification to
return only two types of results: one or all. Normally every function
returns only a single value. The ALL wrapper would return a list
(always) which contained a complete return value specification,
including any auxilliary values which were specified.
FOR EXAMPLE:
(bind (((foo &optional bar) (all (zed ..)))
(foo (zed ..)) )
(print foo) (print bar))
I think this ALL or ONE approach would simplify the use and
implementation of multiple-values. Special binders for
multiple-values won't be necessary. Also, every primitive could
handle multiple-values since they never actually have to be concerned
whether they are or not. This approach also relates to my experience
that when you are going to use more than one return value, you usually
need all of them.
As a final note I would like to go even further with destructuring to
propose that BIND and SET! use the same format for destructuring.
Bind would not need to include some special magic destructuring format
as in the example above.
Simply allow the same kind of binding formats in BIND that are already
in SETF (and I assume will be in SET!). Such as:
(setf (list a b) (list 1 2))
(bind (((list a b) (list 1 2)) )
(print a) (print b))
In order to include the lambda-list syntax, define a new destructure
format called LAMBDA-LIST:
(bind (((lambda-list foo &optional bar) (all (zed ..)) ))
(print foo) (print bar))
SET! could use the same destructuring formats!
(set! (lambda-list foo &optional bar) (list 1 2))
And of course, it would be nice to be able to define new destructure
formats. But the LAMBDA-LIST and LIST formats would be standard.
-- Rob.