Newsgroups: comp.lang.scheme
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!howland.reston.ans.net!ix.netcom.com!netcom.com!NewsWatcher!user
From: hbaker@netcom.com (Henry Baker)
Subject: Re: multiple-value return & optimising compilers
Message-ID: <hbaker-3101950851350001@192.0.2.1>
Sender: hbaker@netcom.com (Henry G. Baker)
Organization: nil
References: <dig-Scheme-7.26@mc.lcs.mit.edu> <9501310741.AA25479@clark.lcs.mit.edu>
Date: Tue, 31 Jan 1995 16:49:14 GMT
Lines: 61

In article <9501310741.AA25479@clark.lcs.mit.edu>,
shivers@clark.lcs.mit.EDU (Olin Shivers) wrote:

> Matthias Blume makes the claim that multiple-value return produces objects
> that aren't first-class, in the sense that the "container" holding the
> multiple values isn't accessible as other values are.
> 
> Multiple return values are not a data-structure; this is like saying variables
> aren't first class or something.
> 
> Multiple return values are completely symmetric with multiple parameters to
> procedures. The latter allows you to pass multiple values to a procedure; the
> former allows you to pass multiple values to an implicit continuation.
> CALL-WITH-VALUES essentially allows you to specify the arity of a
> continuation.

I have exactly the same problem with multiple-values in Common Lisp.  These
really kludge up both the syntax and semantics without much corresponding
gain.  The ML solution is extremely elegant; the only question is whether
it can be implemented efficiently.

I have spent a number of years trying to answer this question, and I
believe that the answer is now an unqualified _yes_.

There are actually at least 2 good answers to the question: stack allocation
of first-class argument lists and return values, and 'linear objects'.

The MIT Lisp machine allocated argument lists as first-class objects on
the stack, but these 'first-class' objects could lead to dangling references
if you grabbed an '&rest' argument and stored it somewhere.

My paper at URL ftp://ftp.netcom.com/pub/hb/hbaker/LazyAlloc.html (also .ps.Z)
discusses how to do this _without_ introducing dangling references.  A more
radical proposal is given at URL
ftp://ftp.netcom.com/pub/hb/hbaker/CheneyMTA.html (also .ps.Z).

Of course, the 'first-class' parameter list and returned values objects
are 'functional', and hence achieve 'object identity' by being compared
extensionally, rather than using EQ.  See
ftp://ftp.netcom.com/pub/hb/hbaker/ObjectIdentity.html (also .ps.Z) for
more details.  (ML already handles this correctly; only Lisp, Scheme &
Smalltalk seem to get confused by this.)

The other part of the equation is to allow 'update-in-place' for functional
objects, and this leads to 'linear' objects.  If one considers a parameter
list to be a 'first-class' object, but also a 'linear' object, then it can
be efficiently accessed and handled, so long as the user doesn't attempt
to make it _non-linear_ -- i.e., so long as the user doesn't attempt to
_share_ it.  These kinds of issues are discussed at URL
ftp://ftp.netcom.com/pub/hb/Use1Var.html (also .ps.Z)

(BTW, I do _not_ suggest hiding linearity as some kind of compiler
inferencing technique.  Linearity is the sort of thing that the
programmer wants/needs to know about, and should therefore be explicit in
the programmer's type system.)

> It's easy to appeal to hypothetical static analyses to justify introducing
> inefficient features into a language. It's a lot harder to do it.

Amen!!  See also ftp://ftp.netcom.com/pub/hb/hbaker/TInference.html to
see some of the headaches of the multiple-return-value approach.
