Home > Archive > Scheme > June 2007 > (values ...) - I don't get it
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
(values ...) - I don't get it
|
|
| bcbarnes 2007-06-07, 7:13 pm |
| Ok, here is another case where I may be looking at things the entirely
wrong way, because of years of imperative programming, but I just
don't get the usefulness of the "values" form. It seems that if I want
multiple values, I can just package them up in a list or vector.
Since I'm obviously missing something, can someone shed some light on
the reasons for (values ... ) and what it might be good for?
Brian.
| |
| Jens Axel Søgaard 2007-06-07, 7:13 pm |
| bcbarnes skrev:
> Ok, here is another case where I may be looking at things the entirely
> wrong way, because of years of imperative programming, but I just
> don't get the usefulness of the "values" form. It seems that if I want
> multiple values, I can just package them up in a list or vector.
>
> Since I'm obviously missing something, can someone shed some light on
> the reasons for (values ... ) and what it might be good for?
Let's look at the conceptual side first.
What's the result of running the euclidean division algorithm
on 21 and 4? The result is two values: 5 is the quotient and
1 is the remainder.
In a Scheme implementation of the division algorithm, one
could return the two conceptual values as a single list
containing the quotient and the remainder. However it doesn't
really communicate to the reader that the intention is to
return two values.
Here is a toy definition of divide which calculates
the quotient and remainder from the division of x with y.
(define (divide x y)
(cond
[(< x y) (values 0 1)]
[else (let-values ([(q r) (divide (- x y) y)])
(values (+ q 1) r))]))
> (divide 21 4)
5
1
From a more practical viewpoint we can compare
"parallel assignment" in imperative languages
to returning multiple values.
(define-values (x y) (values 3 4))
or
> (define-values (q r) (divide 21 4))
> q
5
> r
1
--
Jens Axel Søgaard
| |
| Steve Schafer 2007-06-07, 7:13 pm |
| On Thu, 07 Jun 2007 06:01:08 -0700, bcbarnes <brian.barnes@amd.com>
wrote:
>Ok, here is another case where I may be looking at things the entirely
>wrong way, because of years of imperative programming, but I just
>don't get the usefulness of the "values" form. It seems that if I want
>multiple values, I can just package them up in a list or vector.
You can use the same argument to say that a procedure never needs to
have more than one parameter--you can always package up multiple
parameters into a list or vector. As Jens says, it's more about
demonstrating intent than anything else: The implied semantics of "two
values" are different from those of "a list containing two values."
There's also an efficiency consideration (in some implementations, at
least). Packaging and unpackaging of values into and out of lists takes
time and memory that isn't required otherwise.
Steve Schafer
Fenestra Technologies Corp.
http://www.fenestra.com/
| |
| Ray Dillinger 2007-06-07, 7:13 pm |
| bcbarnes wrote:
> Ok, here is another case where I may be looking at things the entirely
> wrong way, because of years of imperative programming, but I just
> don't get the usefulness of the "values" form. It seems that if I want
> multiple values, I can just package them up in a list or vector.
>
> Since I'm obviously missing something, can someone shed some light on
> the reasons for (values ... ) and what it might be good for?
>
It has been a point of contention. The semantics of Scheme include
reified continuations, which are basically a non-local procedure return
treated as a procedure call.
If you're familiar with imperative languages, you're probably familiar
with returning continuations, in the form of catch/try/throw constructions
and similar. Reified continuations are a lot like that, except you can
store them in variables, call them as many times as you want, call them
even after the procedure they're captured in has returned, etc.
In fact, in the formal semantics of scheme, there is no real distinction
between a function return and a function call. Our reified continuations,
which "return" from the point where a continuation was captured, are
identical to calls or returns.
But up through the fourth revision of the language standard, there was
one difference between function calls and function returns, and that
difference was that function returns could only have one argument (functions
could only return one value) whereas function calls could have any number
of arguments. Since a reified continuation was equivalent to a function
return, it could only be called with one argument.
VALUES makes function returns, function calls, and reified continuation
calls all be exactly the same thing semantically, which makes certain
kinds of proofs easier to reason about by reducing the number of different
cases, certain kinds of automatic code transformations possible because
now you can always map calls onto returns and returns onto calls as your
transforming code manipulates the program, etc. This makes it a powerful
tool for deep thinking macrologists and compiler writers, even though
it's kind of esoteric as regards mainstream programming.
But even if you're not yet a compiler writer or a deep-thinking
macrologist, as a matter of style, a call to (values) with *NO*
arguments makes it clear that a routine is called with no intention
to return a value, which is the case for most routines called for
side effect only, and a handy way to make it clear to a later
generation of coders.
Bear
| |
| Brian C. Barnes 2007-06-07, 7:13 pm |
| bcbarnes wrote:
> Ok, here is another case where I may be looking at things the entirely
> wrong way, because of years of imperative programming, but I just
> don't get the usefulness of the "values" form. It seems that if I want
> multiple values, I can just package them up in a list or vector.
>
> Since I'm obviously missing something, can someone shed some light on
> the reasons for (values ... ) and what it might be good for?
>
> Brian.
Thanks once again to everyone for shedding a little light.
Brian.
--
|
|
|
|
|