[comp.lang.misc] multiple values

quiroz@cs.rochester.edu (Cesar Quiroz) (03/29/88)

Expires:

Sender:

Followup-To:



Gaynor@porthos asks
:How would Scheme's continuations fit into the area of multiple
:return values?

In a capsule:
1- Returning == Calling a continuation
so
2- Returning multiple values == Calling a continuation with multiple
arguments.

So, if `k' is the normal continuation of `f', and `f' tries to
return `v1', `v2', ..., you could model

                         (values v1 v2 ...)

as

                           (k v1 v2 ...)

I believe Scheme doesn't have this class of continuations
(Scheme's continuations take only one argument). However, that this
modification is possible has been known for a long time (at least
since Steele's work in RABBIT, which is as old as one can get
relative to Scheme), so I wouldn't be surprised if at least one
implementation has supported multiple values.  Actually, this has
been known to denotational semantics people for even longer.

Cesar

-- 
Cesar Augusto  Quiroz Gonzalez
Department of Computer Science     ...allegra!rochester!quiroz
University of Rochester            or
Rochester,  NY 14627               quiroz@cs.rochester.edu

karl@haddock.ISC.COM (Karl Heuer) (03/30/88)

In article <727@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes:
>In article <3177@haddock.ISC.COM>, karl@haddock.ISC.COM (Karl Heuer) writes:
>>   (setq z
>>         ((lambda (qr) (+ (* (car qr) (car qr)) (* (cdr qr) (cdr qr))))
>>          (div x y)))
>
>In Lisp, the language certainly suggests that at some time there is a real
>machine object called qr.  The way I am proposing the list, this is never
>more than a virtual object, and does not need a name.  However, the user
>assigns names to the elements of the list, and refers to them, rather than
>having to write (car qr) and (cdr qr).

So?  The way I wrote it, q and r are never more than unnamed virtual objects.
I'm looking for a syntax that allows all three (qr, q, r) to disappear, if
all I really want is an expression that returns q*q+r*r.  If we allow 2-d
notation, this could be written

                      +---+
         +---+    /-->| * |
     x-->|   |---+--->|   |---\    +---+
         |div|        +---+    --->| + |--->z
     y-->|   |--\     +---+    --->|   |
         +---+   +--->| * |---/    +---+
                  \-->|   |
                      +---+

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

barmar@think.COM (Barry Margolin) (03/30/88)

In article <3213@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes:
>So?  The way I wrote it, q and r are never more than unnamed virtual objects.
>I'm looking for a syntax that allows all three (qr, q, r) to disappear, if
>all I really want is an expression that returns q*q+r*r.  If we allow 2-d
>notation, this could be written

I thought we were discussing multiple-valued functions, not language
syntax.  I would expect each language to use a syntax for multiple
values that is consistent with the rest of the language.  In Lisp, if
you want to use something twice, you must name it with a variable;
Forth, on the other hand, lets you (requires you to?) manipulate the
stack directly.  These features are independent of whether functions
can return multiple values.

So, if Lisp requires me to say

(multiple-value-bind (q r) (floor x y)
  (+ (* q q) (* r r)))

that is because this is a Lispy way to do it.  If you don't like Lisp,
fine, but don't put down its multiple-value feature because it is
consistent with the rest of the language.

By the way, when you don't want to refer to a value twice, but just
want to pass it along to another function, you can do that:

(multiple-value-call #'+ (floor x y))

adds the quotient and remainder, which are, indeed, unnamed virtual
objects.  Unfortunately, there's no built-in swap operation as there
is in Forth, so if the function being called takes its arguments in a
different order from the return values you must bind variables to
them.  There's no fundamental reason why Common Lisp couldn't have
such an operation (although I'm not sure what it would mean when the
function doesn't return exactly two values), it just wasn't considered
necessary when the language was being designed, presumably because
variable binding is a much more familiar concept to Lisp programmers.

Barry Margolin
Thinking Machines Corp.

barmar@think.com
uunet!think!barmar

cik@l.cc.purdue.edu (Herman Rubin) (03/31/88)

In article <3213@haddock.ISC.COM>, karl@haddock.ISC.COM (Karl Heuer) writes:
> In article <727@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes:
> >In article <3177@haddock.ISC.COM>, karl@haddock.ISC.COM (Karl Heuer) writes:

> So?  The way I wrote it, q and r are never more than unnamed virtual objects.
> I'm looking for a syntax that allows all three (qr, q, r) to disappear, if
> all I really want is an expression that returns q*q+r*r.  If we allow 2-d
> notation, this could be written

This shows that flexibility and non-portability are needed.  If the quotient 
and remainder are not simultaneouly generated, then the choice between the
order of computation is quite great, while if the hardware simultaneously
can generate them, and registers can hold the information, the pair (q,r)
as a real object should exist for the purpose of reasonable efficiency.  In
the case where the programmer or compiler wishes to use that capability of the
hardware, it is necessary to have an object which I call a list.  Namely, the
operation returns more than one value, and there is no necessary relation 
between the locations of the various objects. 

If the hardware insists in putting the quotient and remainder in adjacent
registers, this in no way complicates matters.  Typically, the user will
allow an optimizing compiler to take these things into account.  If the
compiler is not sufficiently optimizing, the user will have to edit the
compiler's output.  But the language which does not have lists is unlikely
to be able to act reasonably if they are useful.
inter

-- 
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907
Phone: (317)494-6054
hrubin@l.cc.purdue.edu (ARPA or UUCP) or hrubin@purccvm.bitnet

jeff@aiva.ed.ac.uk (Jeff Dalton) (04/01/88)

Gaynor@porthos asks
:How would Scheme's continuations fit into the area of multiple
:return values?

In article <8121@sol.ARPA> quiroz@cs.rochester.edu (Cesar Quiroz) writes:

>In a capsule:
>1- Returning == Calling a continuation
>so
>2- Returning multiple values == Calling a continuation with multiple
>arguments.

>I believe Scheme doesn't have this class of continuations.  (Scheme's
>continuations take only one argument). However, that this modification
>is possible has been known for a long time [...], so I wouldn't be
>surprised if at least one implementation has supported multiple values.

T does more or less what you suggest.  You can write

     (receive-values receiver sender)

to call receiver with the values returned by sender.  Sender should
be a "thunk" that returns the right number of values when called.
Return is used to return multiple values.  So

     (receive-values
       (lambda (a b c) (list a b c))
       (lambda () (return 1 2 3)))     =>  (1 2 3)

Then,

     (reveive (<variable>*) <values-expr> <expr>*)
         ==
            (receive-values
              (lambda (<variable>*) <expr>*)
              (lambda () <values-expr>))

Jeff Dalton,                      JANET: J.Dalton@uk.ac.ed             
AI Applications Institute,        ARPA:  J.Dalton%uk.ac.ed@nss.cs.ucl.ac.uk
Edinburgh University.             UUCP:  ...!ukc!ed.ac.uk!J.Dalton

gateley@m2.csc.ti.com (John Gateley) (07/28/89)

In an article in comp.arch, Nick@lfcs.ed.ac.uk claims that
in order for multiple values to be useful, you must be able to
pass them around as structures.

I disagree with this, if the language needs structures, add structures.
If the language needs multiple values, add multiple values. They
are two different orthogonal concepts: a structure is somthing which
holds several objects; multiple values are several objects returned
from a function. A structure has creators/accessors for accessing
the object, and unlimited extent (or whatever default extent objects
in the language have). Multiple values have two 'operations': return
and accept. These operations are extensions of the single value returning
function operations. Multiple values have limited extent.

John
gateley@m2.csc.ti.com