Newsgroups: comp.lang.scheme
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!news3.near.net!noc.near.net!paperboy.wellfleet.com!news-feed-1.peachnet.edu!gatech!howland.reston.ans.net!ix.netcom.com!netcom.com!NewsWatcher!user
From: hbaker@netcom.com (Henry Baker)
Subject: Re: not giving up on multiple values
Message-ID: <hbaker-0602951013140001@192.0.2.1>
Sender: hbaker@netcom.com (Henry G. Baker)
Organization: nil
References: <BLUME.95Jan30110005@atomic.cs.princeton.edu> <3glo60$npe@cantaloupe.srv.cs.cmu.edu> <3gr4ef$20v@narnia.ccs.neu.edu> <3gr4ls$21b@narnia.ccs.neu.edu>
Date: Mon, 6 Feb 1995 18:10:44 GMT
Lines: 109

In article <3gr4ls$21b@narnia.ccs.neu.edu>, will@ccs.neu.edu (William D
Clinger) wrote:

> CRITICISM #1
> 
> The following code creates a list, only to take it apart.
> 
>     (define (compose f g)
>       (lambda args
>         (f (apply g args))))
> 
> Obviously the multiple values proposal is not responsible for
> the inefficiency caused by Scheme's rest argument and apply
> mechanisms.

Uh...  How do I get the multiple values returned from (apply g args) and
give them to f??  Wouldn't I need something like (sorry about the CL
syntax):

(multiple-value-call f (apply g args))

> CRITICISM #2
> 
> Blume is correct when he asserts that Standard ML, by making
> "every function take exactly one argument and produce exactly one
> result", "allows for maximum orthogonality, and therefore for
> maximum convenience".  For example,
> 
>     fun compose f g = fn x => f (g x)
> 
>     val h = compose (fn (x, y) => [x, y])
>                     (fn x => x);
> 
>     h (3, 4)
> 
> works in Standard ML but
> 
>     (define (compose f g) (lambda (x) (f (g x))))
> 
>     (define h
>       (compose (lambda (x y) (list x y))
>                (lambda (x) x)))
> 
>     (h 3 4)
> 
> doesn't work in Scheme.  Obviously the multiple values proposal
> is not responsible for this problem.
> 
> 
> CRITICISM #3
> 
> Blume thinks we should restrict Scheme to procedures that take
> one argument and return one result, using data structures to
> get the effect of passing multiple arguments or returning
> multiple results.  This technique can be implemented efficiently,
> as is shown by the performance of Standard ML of New Jersey.
> 
> But in Standard ML there are no side effects on tuples, and
> the equality operator is defined structurally on tuples (like
> Scheme's equal?, but not like eqv? or eq?).  Thus a tuple of
> Standard ML can be passed (or returned) by passing its elements
> in registers.  A compiler for Standard ML can do this without
> any optimization whatsoever.
> 
> A Scheme compiler generally can't do this for lists and vectors
> because of procedures such as eqv?, set-car!, and vector-set!.
> It has been suggested that a sufficiently clever compiler could
> deal with this through optimization, but no such compiler has
> been proved to exist, even in the mathematical sense.
> 
> Obviously the multiple values proposal is not responsible for
> the fact that R4RS Scheme has no immutable data structures that
> cannot be tested for identity using eq? and eqv?.
> 
> 
> A MODEST PROPOSAL
> 
> This proposal would address all three of the above criticisms
> without breaking *any* portable Scheme code.  On the other hand,
> this proposal would require changes to all existing implementations
> of Scheme.
> 
> Add a new data type, called "sequences", to Scheme.  The values
> of this data type are sequences of Scheme values.  Sequences are
> written like lists, but square brackets are used in place of
> parentheses:
> 
>     ["hello" "cruel" "world"]          ; a sequence of 3 elements
> 
> As with the tuples of Standard ML, a sequence with exactly one
> element is identical to that element:
> 
>     (eq? '[[[[foo]]]] 'foo)  =>  #t
> 
> Thus every Scheme value is a sequence of one element.  For example,
> [a b c d] is a sequence of one element as well as a sequence of
> four elements.

Haven't you just introduced a new _second class_ datatype?  If I
can't detect the difference between the empty sequence and the
sequence of one element which is the empty sequence, then I'm back
into the second class soup, because I can't pass or return empty
sequences as first class values.

I have a better proposal:  exchange the roles of '()' and '[]'.  Now
every list is immutable, and I have to go to some trouble to make
a mutable list.  Eliminate the troublesome and inelegant notion that
[a] = a.  Even mathematicians fail to make this distinction rather
frequently, because they are misled by the notation.
