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

[Scheme-reports] Multiple values

Three hours ago, John Cowan wrote:
> Eli Barzilay scripsit:
> > You can't avoid the extra cost.  Implementations vary with heap or
> > stack allocation which is something that goes in a different
> > level.
> You can't reduce the cost to zero, [...], but you can reduce it.

The cost is the *same*: two values and a wrapper, where a
stack-of-values implementation need some indication of the number of
values or some marker -- and that's equivalent to a wrapper.
It's true that in some cases you can do a static optimization, but
that holds just as well for lists and other containers.

> > In any case, your original statement of multiple values as some
> > lightweight alternative is even more wrong given this.  (The
> > historical context is first class continuations.)
> I don't see how that can be.

That's very unfortunate.

> Multiple values first appeared (AFAIK) in Zetalisp, which did not
> have first-class continuations.  [...]

Different langauge, very different context.  Scheme is the context
where an addition of a new `values' type is immediately rejected since
there's nothing new that you get with it.  OTOH, it's a context where
a question like "if we have continuations reified as callable
functions, then what does it mean to call such a function with more
than one value?" is very relevant.  To rephrase this, once you have
`call/cc' in the language, you need to figure out what

  (lambda xs (call/cc (lambda (k) (apply k xs))))

means -- one way out is to declare it invalid (or "unspecified") to
call a continuation function with more or less than one argument.
This is what R4RS did:

  The escape procedure is a Scheme procedure of one argument [...]

Later, R5RS chose the more schemely way out and removed this
restriction (sorry the over-abused quote):

  The escape procedure accepts the same number of arguments as the
  continuation to the original call to call-with-current-continuation.

In any case, that's how multiple values fit in the scheme historical

And BTW, as long as I gave the above example, and was dragged to quote
the relevant part of R5RS, I can just as well continue the quote:

  Except for continuations created by the call-with-values procedure,
  all continuations take exactly one value.

and it should be clear now why Chibi's implementation is just plain

  > (define (v . xs)
      (call-with-current-continuation (lambda (k) (apply k xs))))
  > (call-with-values (lambda () (v 1 2 3)) list)
  ERROR on line 64 of file ./lib/init.scm: too many args
      #<procedure #f>

If you want to get pickier, then all implementations that don't barf

  (list 1 (values 2 3 4) 5)

are broken because according to R5RS:

  (values obj ...)

  Delivers all of its arguments to its continuation.  Except for
  continuations created by the call-with-values procedure, all
  continuations take exactly one value.

And while I'm at this rampage of pickiness, I'll note also that *none*
of the above has changed in R6RS.  Revisiting an earlier burst of
bogosity, where you said:

| Well, you can write a conformant implementation that does so.
| [Reifies multiple values]

which is wrong,

| Or you can use a unique type, or even a non-unique type.

is also wrong,

| Because multiple values are only conformant in specific contexts,
| *all* of those implementations, with their different tradeoffs, are
| allowed,

is wrong too,

| and portable programs don't have to care about the differences.

should be even more clearly wrong now, and

| Chibi's use cases just aren't anything like Racket's.

was just irrelevant nonsense, since Chibi's implementation is just

(And yes, "Ultimately, if you want R6RS, you know where to find it."
is wrong too, but who's counting?)

          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Scheme-reports mailing list