Gauche has values->list and values-ref.   It is indeed handy.
However, it's a bit difficult to make those primitives cover the necessary situations.
Suppose you want to branch by the number of values yielded by EXPR.

   (if (= (values-length EXPR) 1)
      (let ((val EXPR))   ;; fast path
         ...)
      (let ((vals (values->list EXPR))) ;; generic path
         ...))

You have to evaluate EXPR twice.   If you want to make it evaluate once, you have to reify it
in some way, which defeats the original motivation to write this kind of code.







On Mon, May 4, 2020 at 8:12 PM Marc Nieper-Wißkirchen <xxxxxx@nieper-wisskirchen.de> wrote:
John, Shiro, thank you for your comments.

I see two ways how to implement what you are asking for. The obvious
way would be to specify procedures like

(unbox-value <box> <index>)

and

(box-values-length <box>)

that retrieve a single value or return the number of values store, respectively.

There is a second way, however, which can also be applied in other
situations where multiple values occur. What I am thinking of are
special forms not restricted to boxes (but could be applied to, say,
the Justs and Rights of SRFI 189 likewise) as follows:

(values->vector <expr>)
(values-length <expr>)
(values->list <expr>)
(values-ref <expr> <index>)

These are expressions defined as syntax (important because Scheme's
applicative syntax doesn't allow multiple values). When they are
evaluated, <expr> is evaluated and expected to return values, which
are then converted to a vector, a list, etc. Moreover, as this is
syntax, an implementation can expand these forms into the most
efficient ones.

Applied to the case of boxes, instead of "(box-values-length <box>)",
we would then have (values-length (unbox box)). Again, as this is
syntax, the implementation's expander can expand "(values-length
(unbox box))" into some specialized code.

In case, you also want to set a single value, the way to go in the
second approach is as in SRFI 17: (values-set! <expr> <index> <value>)
is a special form that works in a context like "(values-set! (unbox
<box>) <index> <value>)".

Am Mo., 4. Mai 2020 um 23:22 Uhr schrieb John Cowan <xxxxxx@ccil.org>:
>
> And also, I think, to retrieve the nth value.
>
> On Mon, May 4, 2020 at 5:21 PM Shiro Kawai <xxxxxx@gmail.com> wrote:
>>
>> Can it also have an interface to query how many values a given box is holding?
>> Without that, any generic code to deal with boxes must receive the unboxed values
>> as a list.  Although clever compilers may eliminate construction of intermediate lists
>> in some cases, it'll be easier if one can get the information (e.g. one can have fast-path
>> for single-valued box, or check the box argument and reject early if the passed box
>> has different values than expected.)
>>