[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

multiple values




Maybe some of you missed or have forgotten the relevant discussion last
October and November, so here's a digest.  If you remember this stuff,
you needn't examine this message any further, and I apologize for
cluttering your mailboxes.

The mechanism in T3 is essentially the same as that presented in my
message of Thu, 30 Oct 86 22:08:03 EST.  That message also includes some
motivation, which I won't repeat here, and Dan has already sent out the
technical content.  The rather important detail ommitted from the T3
release notes is that it's an error whenever the number of values
expected doesn't match the number delivered, and argument and predicate
positions expect exactly one value.  Thus (list (return 1 2)) is an
error in T3 and in my proposal.

The mechanism that Dan Friedman proposes was suggested on this list by
Andy Freeman:

    Date: Thu 30 Oct 86 12:25:22-PST
    From: Andy Freeman <ANDY@Sushi.Stanford.EDU>
    
    This proposal is a variant on the technique Carolyn Talcott used
    in her thesis; Richard Weyrauch was also involved in that work.
    
    Their idea requires one procedure; I'll call it values.  Procedure
    invocation spreads multiple values; (cons (values 1 2)) is completely
    equivalent to (cons 1 2) and (list (values) 4 (values 1 2) 3) is
    equivalent to (list 4 1 2 3). ...

It was dismissed by the only people on the list (besides maybe Sussman)
who had actual experience using it, namely Steele and Gabriel:

    Date: Mon, 3 Nov 86 11:24 EST
    From: Guy Steele <gls@Think.COM>
    
    It [MARVEL] did pretty much all the obvious things: every function
    call was implicitly like the Common Lisp MULTIPLE-VALUE-CALL, and
    most side-effecting forms such as SETQ, PRINT, and COMMENT were made
    to return zero values.  I believe I also arranged for variables to
    be able to hold multiple values.
    
    My experience with the language was that it was perfectly clean
    and elegant, but programs that made non-trivial use of multiple
    values were very hard to read, precisely because of the loss
    of the one-form/one-value correspondence.  Having the extra power
    everywhere in the language was not worth the loss of clarity.
    I therefore abandoned the experiment without writing it up.
    (Maybe I should have, but there were other, more promising variations
    of Scheme to explore.)
    ...
    I believe that experience with the POP languages (especially POP-2)
    may be relevant to this discussion, but I am not an expert there.
    

    Date: 03 Nov 86  1214 PST
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
    ...    
    The code, as Steele mentions, was elegant in a certain sense, but
    very hard to read most of the time, because you had to take into
    account that some other values than the primary value (the first
    one) would be passed to some program.  The places where SEUS code
    was easy to read were when you were writing something that, in
    Common Lisp, would be
    
    (multiple-value-call #'foo (baz) (bar))
    
    The places where it was hard to read were when you were writing something
    that, in Common Lisp, would be
    
    (foo (baz) (bar))
    
    That is, there was no easy way to check that the right values from the
    right places got passed. I think that the latter is the more commonly
    used case, so SEUS was optimized the wrong way.
    ...
    When the Common Lisp multiple value scheme was being devised, I thought
    that we (the designers) should look at SEUS for its experience. I'm now
    glad we didn't do anything more that invent MULTIPLE-VALUE-CALL as a
    result of that experience.

I tend to agree that it's a bad idea, not only from the point of view of
someone using it, but also for implementation reasons: unlike the T
proposal, which is trivially implementable (VALUES = LIST) in any scheme
implementation, it's grossly incompatible with current implementations;
and it has a performance cost that you have to always pay for, even when
you're not using the feature, because all calls to unknown procedures
must be prepared to splice in an arbitrary amount of crud.

Jonathan