Re: An error in the SRFI document, and multi-indices are what (values ...) returns Bradley Lucier 10 Feb 2026 16:22 UTC

On 2/9/26 21:44, Bradley Lucier wrote:
> The design is correct, it's just that the statement
> ===================
> The vectors of upper and lower bounds of an interval can have zero
> elements, in which case the zero-dimensional interval itself has no
> elements ...
> ===================
> is incorrect, the zero-dimensional interval has one element, namely
> (values). That's why
>
>  > (import (srfi 231))
>  > (interval-volume (make-interval '#()))
> 1

Thank you all for your comments, which I'll try to address here.

First, allow me a little frivolity: Thinking about this issue brought to
mind the movie "Cool Hand Luke", where Paul Newman says "Sometimes
nothing can be a real cool hand" and, in a different context, the prison
warden says "What we've got here is a failure to communicate."

The connection: I believe that sometimes, nothing can be a multi-index,
and I've found it hard to think about and communicate this idea.

Perhaps the most direct way is to consider the procedure

(specialized-array-share array new-domain new-domain->old-domain)

Here new-domain->old-domain takes a multi-index as an argument and
returns another multi-index, e.g.,

 > (define matrix (list->array (make-interval '#(3 3)) (iota 9)))
 > (define diagonal (specialized-array-share matrix (make-interval
'#(3)) (lambda (i) (values i i))))
 > (array->list* matrix)
((0 1 2)
  (3 4 5)
  (6 7 8))
 > (array->list* diagonal)
(0 4 8)

In this example new-domain->old-domain is (lambda (i) (values i i)),
i.e, (values i i) is the multi-index.  This specific example isn't in
the document, but there are many similar examples.

Now we can consider a different example:

 > (define array (make-specialized-array (make-interval '#())))

 > (define shared-result (specialized-array-share array (make-interval
'#(1)) (lambda (i) (values))))
 > (array->list* array)
#f
 > (array->list* shared-result)
(#f)
 > (define shared-result-2 (specialized-array-share array (make-interval
'#(1 1 1)) (lambda (i j k) (values))))
 > (array->list* shared-result-2)
(((#f)))

So here (values) is the multi-index.

Privately, I've long thought of array transformations as a meditation on
manipulation of (values ...).

To answer Peter's "Would it be better to describe the multi-index as a
proper list of exact integers?", no, I've worked really hard not to
package the arguments to array getters and setters into lists or
vectors.  That's partly what's behind the following paragraph in the SRFI:
=========================
Certain ways of sharing generalized arrays, however, are relatively easy
to code and are not expensive. If we denote (array-getter A) by A_, then
if B is the result of array-extract applied to A, then (array-getter B)
is simply A_. Similarly, if A is a two-dimensional array, and B is
derived from A by applying the permutation π((i,j))=(j,i), then
(array-getter B) is (lambda (i j) (A_ j i)). Translation and currying
also lead to transformed arrays whose getters are relatively efficiently
derived from A_, at least for arrays of small dimension.
=========================

Hope this helps a bit.

Brad