Newsgroups: comp.lang.scheme
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!news.mathworks.com!udel!gatech!howland.reston.ans.net!news.sprintlink.net!ixc.ixc.net!news.ecn.bgu.edu!siemens!princeton!news.princeton.edu!blume
From: blume@atomic.cs.princeton.edu (Matthias Blume)
Subject: giving up (Was: Re: Explanation about call-with-values)
In-Reply-To: will@ccs.neu.edu's message of 25 Jan 1995 19:10:38 GMT
Message-ID: <BLUME.95Jan25165400@atomic.cs.princeton.edu>
Originator: news@hedgehog.Princeton.EDU
Sender: news@Princeton.EDU (USENET News System)
Nntp-Posting-Host: atomic.cs.princeton.edu
Organization: Princeton University
References: <BLUME.95Jan22133847@dynamic.cs.princeton.edu> <3g004e$7ps@nkosi.well.com>
	<BLUME.95Jan23140314@dynamic.cs.princeton.edu>
	<3g67ne$e4e@narnia.ccs.neu.edu>
Date: Wed, 25 Jan 1995 21:54:00 GMT
Lines: 138

In article <3g67ne$e4e@narnia.ccs.neu.edu> will@ccs.neu.edu (William D Clinger) writes:

   blume@dynamic.cs.princeton.edu (Matthias Blume) writes:
     Has anybody measured the benefits from using call-with-values?

   One of the results reported by Ashley and Dybvig is that three passes
   of the Chez Scheme compiler ran 20% faster when rewritten to use
   call-with-values, implemented as described in their paper, instead of
   returning a vector.

   This is a fairly impressive speedup for such a simple change to such
   a large program.

Hmm, but it is against the spirit of Scheme.  If we pile feature on
top of feature just to gain a few percent here and there, then we will
soon end up with something like Common Lisp, PL/1, C, C++, or worse.
Why not adding some `(asm ...)' directive for inline assembly
language?  This would certainly beat the hell out of every Scheme
compiler...  (Ok, ok, I exaggerate...)

If Ashley and Dybvig would be talking about a special kind of
analysis, that makes multiple values (as vectors/lists/...) fast, or
if they would point out the things that need to be removed from the
language without sacrificing expressiveness, which enable such
optimizations -- well, *that* would be an interesting result.

Even if values/call-with-values takes zero time their numbers seem to
indicate that the original program spent 20% of its time returning
from functions having multiple resturn values!  This sounds fairly
unbelievable to me.  Or did they rewrite those passes to take
advantage of values/call-with-values?  (In this case the numbers don't
mean anything, because we are not comparing the same program anymore.)

   blume@dynamic.cs.princeton.edu (Matthias Blume) continues:  In
     addition, I would venture to say that in places where the compiler can
     benefit from `values' and `call-with-values' it wouldn't be too hard
     to find corresponding `vector' and `vector-ref' calls (and to optimize
     them away) either.

     ....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....

     ....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....

   Not so.  Lists and vectors are first class.

Exactly.  It is against the spirit of Scheme -- as I understand it,
and as far as the language still has one -- to have a procedure
(`values') to construct second-class objects.  I still don't
understand why first-class-ness prevents us from taking advantage of
Wright's soft typing or similar kinds of analyses.

   Furthermore they have
   individual personalities that can be tested using eqv? and side
   effects.

If you can prove that they never participate in such tests...

   A global analysis would therefore be required to eliminate
   calls to vector and vector-ref, or list and apply, which means the
   optimization would fail when lists or vectors are passed across the
   boundary of a compilation unit.

Correct.  But so what?  What is a compilation unit in Scheme, anyway?
This doesn't make sense to me at all.  We are dealing with a language,
which doesn't even have the notion of `compilation' or `compilation
unit', no sound module system, no sound definition of the behavior of
its interactive top-level, but we are talking/arguing about
cross-module optimizations?!

   Multiple values are not a data structure at all, much less first
   class.

But that's a pity!  And what a pity!

   There are only two things an implementor must do to make
   multiple values fast, even when passed between compilation units:

       1.  Make values and call-with-values into integrable procedures.

Something the languages doesn't give you a portable handle onto.

   blume@dynamic.cs.princeton.edu (Matthias Blume) also writes:
     Given that Scheme's current design makes it pretty hard to optimize
     even (usually) trivial things for speed (such as arithmetic because of
     the very general number type tower) this kind of optimization is
     hardly worth the paper it is proposed on...

   In fact it doesn't, because
   Standard ML doesn't have any destructive operations or eq?
   predicate that is defined on tuples.

I would like to see eq? go, and set-car!/set-cdr! as well...  Things
would be so much simpler.  But heh, what's wrong with global analysis?
Your `tuple' type sounds like a good alternative, too...

The bottom line is that I am still unconvinced about the merits of
`values'.  Their second-class-ness is utterly despicable, and there
seems to be no reason why they should be faster than explicit CPS.

I do not understand why we suddenly give up on the goal of conceptual
simplicity, and the goal of power through orthogonality.  In my eyes,
`values' is a performance hack and as such it doesn't belong into a
language like Scheme.

There are many other regrettable descisions that have been made in the
past -- decisions which not only lead to difficulties for compilers,
but also to difficulties with the cleanliness of the language as a
whole.  They should be cleaned up first.  (... but by removing the
weaknesses and restrictions that made additional features appear
necessary.) `values' is a blatant symptom of feature cancer.  It is
easy to define in other terms:

        (define values list)
        (define (call-with-values thunk receiver)
          (apply receiver (thunk)))

The properties of this pair of functions contain those of the proposed
values/call-with-values, granted -- they are not that easy to make
fast, but I don't count this as an argument -- they fit right in with
the rest of the language, communicate via first-class objects and are
therefore more convenient to use, easy to combine, etc. etc.

Maybe it is time to ask ourselves: Why do we still need Scheme at
all? Performance is clearly not one of the reasons, and language
design becomes less and less of a reason.  So what is left?  Probably,
it is time to get out of here...

I'm sorry that I came to having to paint such a gloomy picture of the
state of my once-favorite language.  But looking at what's going on
(Guile/`R5RS'/values/eval/dynamic-wind/no module system/...) I can't
help it anymore.  If there only was a good alternative... :(

--
-Matthias
