Newsgroups: comp.lang.scheme
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!news.mathworks.com!udel!gatech!newsxfer.itd.umich.edu!gumby!newspump.wustl.edu!news.ecn.bgu.edu!siemens!princeton!news.princeton.edu!blume
From: blume@dynamic.cs.princeton.edu (Matthias Blume)
Subject: Re: Explanation about call-with-values
In-Reply-To: djello@well.sf.ca.us's message of 23 Jan 1995 10:24:14 GMT
Message-ID: <BLUME.95Jan23140314@dynamic.cs.princeton.edu>
Originator: news@hedgehog.Princeton.EDU
Sender: news@Princeton.EDU (USENET News System)
Nntp-Posting-Host: dynamic.cs.princeton.edu
Organization: Princeton University
References: <3fqdq2$9g0@nkosi.well.com> <BLUME.95Jan21131442@dynamic.cs.princeton.edu>
	<3ft107$fgt@nkosi.well.com>
	<BLUME.95Jan22133847@dynamic.cs.princeton.edu>
	<3g004e$7ps@nkosi.well.com>
Date: Mon, 23 Jan 1995 19:03:14 GMT
Lines: 83

In article <3g004e$7ps@nkosi.well.com> djello@well.sf.ca.us (Darius Bacon) writes:

The other problem I see with `values' and `call-with-values' it that
it asymmetrically duplicates functionality.  No matter how it is
implemented, the result of `values' can be understood as having a
special `tuple' type.  `values' is the constructor for objects of this
type, and `call-with-values' is the corresponding deconstructor: it
takes the tuple apart and spreads its contents over the argument list
of a given function.

But we already *have* this pair of operators: they are called `list'
and `apply'.  The only remaining argument in favor of `values' seems
to be safety -- something that doesn't sound overly convincing given
the rest of the language.  The difference in usefulness between a
scheme where `wrong-number-of-values' errors are caught at the time
those values arrive at the receiving function or at the time this
function actually tries to access them seems to be marginal at most.

SML really got this part right: *all* functions take *one* argument
and produce *one* result.  If you want to pass more than that in
either direction you must use a structured type like a tuple or a
record.  It is just as convenient to use as ordinary function-call
syntax (SML's pattern matching helps quite a bit here, though.),  but
the compiler must do some work to get it efficient.  But so what?
It's the compiler doing the work, not me...

I would be surprised if Andrew Wright's `soft typing' couldn't point
out occurences of `values' and `call-with-values' disguised as `list'
and `apply'.  A compiler could easily optimize this kind of contruct
and even issue `wrong number of arguments' errors at compile-time.
And the amount of effort appears to be precisely the same as if we
used the special `values' instead.

If you want early error checking, then, please, make sure it can be
done at compile time.  The only reason for waiting until runtime seems
to be taking advantage of non-strictness, and there you really want to
delay errors as much as possible.

   [ ... ]  That wouldn't catch
   all errors immediately, but at least it would keep you from doing a
   vector-ref or a car on the result returned by  values.

In what sense is a `wrong number of arguments' type of error
preferable over `wrong argument to CAR'?  I really fail to see the
point here.

   I was wrong -- we both misunderstood.

Yes, I figured that out myself after I sent my last article.

   I thought you were talking about the
   implicit continuation the first time.  In turn, I said "bar needs to know
   that baz returns multiple values" where it would be more precise to say
   "bar needs to know that baz follows the multiple-value return convention of
   taking an explicit continuation".  My point is, if different parts of your
   code follow different calling conventions, the pieces no longer go together
   without fuss.  Procedures not directly involved with returning multiple
   values must act as if they were.

That is certainly true.  What I was saying was that multi-argument
implicit continuations don't buy you much, because the can easily be
simulated by making them explicit.

However, by the same token we don't need implicit continuations and
call/cc, because by passing explicit continuations *everywhere* we
could simulate that, too.  The fine point here is that IMO multi-arg
continuations are rare, and they don't blend in with the rest of the
languages very well, so they don't get used very often.  (Normal
function calls always create one-arg continuations, we must use a
special construct to create a multi-arg continuation.  Therefore,
one-arg continuations are ubiquitous, even if we never invoke call/cc
to reify them.)

We can afford passing explicit continuations in places, where this
appers to be unavoidable. (VSCM's first compiler pass is written this
way mainly because I felt I need multiple return values.  After the
first two functions written this way it begins to become second
nature.)  Moreover, the use of implicit multi-arg continuations is so
awkward in itself, that I don't see much benefits in programmer's
convenience either.

--
-Matthias
