### Conventional Arrays

Arrays read and write as a `#` followed by the rank (number of dimensions) followed by what appear as lists (of lists) of elements. The lists must be nested to the depth of the rank. For each depth, all lists must be the same length.

```(make-array 'ho 3 3) =>
#2((ho ho ho) (ho ho ho) (ho ho ho))
```

Unshared conventional (not uniform) 0-based arrays of rank 1 (dimension) are equivalent to (and can't be distinguished from) vectors.

```(make-array 'ho 3) => (ho ho ho)
```

When constructing an array, bound is either an inclusive range of indices expressed as a two element list, or an upper bound expressed as a single integer. So

```(make-array 'foo 3 3) == (make-array 'foo '(0 2) '(0 2))
```

primitive: array? obj
Returns `#t` if the obj is an array, and `#f` if not.

procedure: make-array initial-value bound1 bound2 ...
Creates and returns an array that has as many dimensions as there are bounds and fills it with initial-value.

primitive: array-ref array index1 index2 ...
Returns the element at the `(index1, index2)` element in array.

primitive: array-in-bounds? array index1 index2 ...
Returns `#t` if its arguments would be acceptable to array-ref.

primitive: array-set! array new-value index1 index2 ...
Sets the element at the `(index1, index2)` element in array to new-value. The value returned by array-set! is unspecified.

primitive: make-shared-array array mapper bound1 bound2 ...
`make-shared-array` can be used to create shared subarrays of other arrays. The mapper is a function that translates coordinates in the new array into coordinates in the old array. A mapper must be linear, and its range must stay within the bounds of the old array, but it can be otherwise arbitrary. A simple example:
```(define fred (make-array #f 8 8))
(define freds-diagonal
(make-shared-array fred (lambda (i) (list i i)) 8))
(array-set! freds-diagonal 'foo 3)
(array-ref fred 3 3) => foo
(define freds-center
(make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j))) 2 2))
(array-ref freds-center 0 0) => foo
```

primitive: transpose-array array dim0 dim1 ...
Returns an array sharing contents with array, but with dimensions arranged in a different order. There must be one dim argument for each dimension of array. dim0, dim1, ... should be integers between 0 and the rank of the array to be returned. Each integer in that range must appear at least once in the argument list.

The values of dim0, dim1, ... correspond to dimensions in the array to be returned, their positions in the argument list to dimensions of array. Several dims may have the same value, in which case the returned array will have smaller rank than array.

examples:

```(transpose-array '#2((a b) (c d)) 1 0) => #2((a c) (b d))
(transpose-array '#2((a b) (c d)) 0 0) => #1(a d)
(transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) =>
#2((a 4) (b 5) (c 6))
```

primitive: enclose-array array dim0 dim1 ...
dim0, dim1 ... should be nonnegative integers less than the rank of array. enclose-array returns an array resembling an array of shared arrays. The dimensions of each shared array are the same as the dimth dimensions of the original array, the dimensions of the outer array are the same as those of the original array that did not match a dim.

An enclosed array is not a general Scheme array. Its elements may not be set using `array-set!`. Two references to the same element of an enclosed array will be `equal?` but will not in general be `eq?`. The value returned by array-prototype when given an enclosed array is unspecified.

examples:

```(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1) =>
#<enclosed-array (#1(a d) #1(b e) #1(c f)) (#1(1 4) #1(2 5) #1(3 6))>

(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) =>
#<enclosed-array #2((a 1) (d 4)) #2((b 2) (e 5)) #2((c 3) (f 6))>
```

procedure: array-shape array
Returns a list of inclusive bounds of integers.
```(array-shape (make-array 'foo '(-1 3) 5)) => ((-1 3) (0 4))
```

primitive: array-dimensions array
`Array-dimensions` is similar to `array-shape` but replaces elements with a `0` minimum with one greater than the maximum. So:
```(array-dimensions (make-array 'foo '(-1 3) 5)) => ((-1 3) 5)
```

primitive: array-rank obj
Returns the number of dimensions of obj. If obj is not an array, `0` is returned.

primitive: array->list array
Returns a list consisting of all the elements, in order, of array.

primitive: array-copy! source destination
Copies every element from vector or array source to the corresponding element of destination. destination must have the same rank as source, and be at least as large in each dimension. The order is unspecified.

primitive: serial-array-copy! source destination
Same as `array-copy!` but guaranteed to copy in row-major order.

primitive: array-fill! array fill
Stores fill in every element of array. The value returned is unspecified.

primitive: array-equal? array0 array1 ...
Returns `#t` iff all arguments are arrays with the same shape, the same type, and have corresponding elements which are either `equal?` or `array-equal?`. This function differs from `equal?` in that a one dimensional shared array may be array-equal? but not equal? to a vector or uniform vector.

primitive: array-contents array
primitive: array-contents array strict
If array may be unrolled into a one dimensional shared array without changing their order (last subscript changing fastest), then `array-contents` returns that shared array, otherwise it returns `#f`. All arrays made by make-array and make-uniform-array may be unrolled, some arrays made by make-shared-array may not be.

If the optional argument strict is provided, a shared array will be returned only if its elements are stored internally contiguous in memory.