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

implementing multiple values



We have gotten to the place where I have to actually implement multiple
values.  I find that I need to know a bit more about what the semantics
are, and what compromises are and are not acceptable.  What I would love
to hear is that I can use the Maclisp implementation.  It is certainly
the obvious approach for a conventional machine:  VALUES just saves away
its arguments in some global place (global variables - probably we would
use a separate stack - it doesn't much matter).  Then MULTIPLE-VALUE-xxx
simply retrieves them and makes them into a list, binds variables to
them, etc.  The problem turns out to be knowing when it is safe to use
those stored-away values. E.g. consider the following example from Maclisp:

(multiple-value-list (progn (values 'a 'b 'c) nil)) --> (nil b c)

It seems fairly clear that this should return either (nil) or (a b c).
This seems like a simple bug in the Maclisp implementation.  But it
does illustrate the kind of problems that are going to come up.
I do need to know exactly how long multiple values last.  Here are
the definitions I can see as being reasonable, with the ones I
prefer first (as you might guess, this is simply in order of how easy
they are to implement):

  - an m.v. receiver is only valid when the most recent value computed
	was computed by an m.v. producer.  Other cases are errors, and
	the results are undefined.
  - an m.v. receiver returns the most recent values produced by an
	m.v. producer.  Other non-multiple-values produced in the
	interim are ignored.
  - an m.v. receiver returns the most recent value computed, m.v. or
	otherwise.
  - like the last, except that some constructs "kill" multiple values
	and some do not.  If this definition is used, we need a list
	of the ones that do and don't.

Probably the last two definitions are going to require that every
value computation will interact with the m.v. mechanism, an overhead
I would like to avoid.  At least this is true if m.v.'s can be survive
function returns.  Consider the following example:

    (defun foo nil (bar) 'success)

Since (BAR) may return multiple values, even something as simple as
'SUCCESS is going to have to explicitly do something to make sure that
any multiple values returned by BAR are no longer active.  Either that
or

   (defun foo nil (bar))

is going to have to do something explicit to make sure that if (BAR)
happens to return multiple values, they get returned.

In any case, I need a precise definition.  Can somebody help? The
following cases are given just to spark your thoughts, not to relieve
Guy of the need to give a  precise specification. Please assume that
functions stay defined until they are explicitly redefined.

1.

(defun foo nil (values a b c))
(defun bar nil (foo))
(defun baz nil (multiple-value-list (bar]

2.

(defun baz nil (multiple-value-list
		 (cond ((moon-phase) (foo))
		       (t  (trunc 5 2]

3.

(defun bar nil (cond ((moon-phase) (foo))
		     (t (trunc 5 2]
(defun baz nil (multiple-value-list (bar]

4.

(defun baz nil (multiple-value-list (progn (foo]

5.

(defun baz nil (multiple-value-list (progn (foo) nil]



-------