On Sun, Jan 16, 2022 at 5:11 PM Bradley Lucier <xxxxxx@math.purdue.edu> wrote:
 
but I don't see how to get around specifying the domain interval.

It suffices to specify the rank, I think.  Common Lisp array literals are of the form `#rA(...)` where r is a sequence of digits representing the rank and (...) is a (possibly) nested list of values representing the contents of the array.   The storage class is always generic.

In Scheme we can write this as a procedure (array rank list) that returns a specialized array.  All the lower bounds are 0, but this is easily fixed up with array-translate and is a common case anyway.  We can infer the upper bounds from the sizes of the nested lists, but we cannot infer the rank reliably: (array 2 '((1 2 3) (4 5 6) (7 8 9)) is an array of numbers, whereas (array 1 '((1 2 3) (4 5 6) (7 8 9)) is an array of lists of numbers.  It is an error to pass a non-rectangular list as far as the rank, but of course (array 1 '((1) (2 3) (4 5 6 7)) is fine.

My original idea was to use array-copy to convert the result to the desired storage class, but for very large arrays that would create too much GC pressure.  So I think the Right Thing is to accept an optional third argument, the storage class.

Lastly, it seems to be common to use a nested-vector representation when the problem domain has a fixed rank, as in a 2D or 3D transformation matrix, and there is no need to abstract over the interval.  Since there is no existing function to convert a nested vector to a nested list, it makes sense to me for `array` to accept either a list or a vector as its second argument.