array-lib egg
*************

Provides a SRFI-63 workalike

Written by Kon Lovett (mailto:klovett@pacbell.net)

   This manual corresponds to version 1.7 of the array-lib extension
library for Chicken Scheme.

1 About this egg
****************

1.1 Version history
===================

`1.7'
     Bug fix for ec

`1.6'
     Removal of common code, partial support for csi describe

`1.5'
     Exports

`1.4'
     Replaced #<rank>A print syntax with #A read/print 			syntax, bug fix
     for returning underlying storage object

`1.3'
     Optimized array construction

`1.2'
     Bug fix for unbound-variable array:store

`1.1'
     Record optimization

`1.0'
     Indexing optimization

`0.9'
     more SLIB procedures

`0.8'
     SLIB procedures

`0.7'
     Added procedures

`0.6'
     Added procedures

`0.5'
     Added procedures

`0.4'
     Added procedures

`0.3'
     Bug fix for empty arrays

`0.2'
     Bug fix for rank 0 arrays

`0.1'
     Initial release

1.2 Usage
=========

Load this egg like so:

   `(require-extension array-lib)'

1.3 Requirements
================

This egg requires the following extensions:

   `misc-extn'

2 Documentation
***************

The array-lib purports to be a Chicken workalike for SRFI-47
(http://srfi.schemers.org/srfi-47/srfi-47.html), SRFI-63
(http://srfi.schemers.org/srfi-63/srfi-63.html), 			and the SLIB array,
subarray & arraymap modules.

   Note: this array package is _not_ compatible with the
default array library SRFI-25 that is provided with the base
system. Do not use these two libraries together in the same
program. However it does provide a similar `shape' 			feature, but with a
SRFI-63 compliant API.

2.1 SRFI-63 Discussion
======================

The signatures of all SRFI-63 procedures are supported by 				this
API, only with extended interpretations of some 				arguments.

   Both SRFI-47 and SRFI-63 array prototypes are supplied,
including complex prototypes (see below).

   Array constructors will return the underlying storage
object, rather than an array object, when the constructed array 				is
0-origin & rank <= 1, per SRFI-63.

   Where dimensions are expected a shape is also accepted.
Where a rank is expected dimensions or a shape are also
accepted.

   Dimensions are a list of the number of elements for each
dimension, or a dimension object (see below). For example, `'(1 2)' are
dimensions of a rank 2 array.

   A shape is a list of intervals, [lower upper), or a shape
object (see below). For example, `'((0 1) (0 2))' is a 				shape of a rank
2 array, with bounds [0 0] [0 1].

   The dimensions `'(2 0 3)' are equivalent to the 				shape `'(0 2 0 0 0
3)'.

   The accepted list form of dimensions or shape for procedures 				taking
these as tail arguments is as an 'exploded' list. Each 				element as an
individual argument. For example, `(make-array '(1 2) '(-8 -5))', not
`(make-array '((1 				2) (-8 -5)))'.

   All indices/dimensions/bounds/ranks *must* be 				fixnum. Not much of a
restiction from SRFI-63, just a 				clarification.

   An empty dimension, a dimension of 0, is not actually empty.  				The
empty dimension will have a single element, the subarray
"inside". However, no storage is consumed by an empty 				dimension.

2.2 Read Syntax
===============

A SRFI-10 (http://srfi.schemers.org/srfi-10/srfi-10.html) printer and
reader is supplied.

   An array specific read/print syntax is supplied:
`#A<rank><elements>', where <rank> is the array 				dimensionality and
<elements> are a rank-nested list consisting 				of all the
elements, in row-major order.

   The SRFI-10 print-form preserves the underlying storage
model and shape information, unlike the #A form, which only
preserves the rank and element values. So, reading the #A form
may not reconstruct the exact printed array.

   Use `(current-array-print-form ...)' to select 				the desired form.

   A limit is placed on the number of array elements printed,
which may be overridden. See `(current-array-print-count 				...)'.

2.3 Parameters
==============

 -- parameter: current-array-bounds-check
          (current-array-bounds-check [FLAG #t])

     Sets or returns whether array indices are bounds-checked.

 -- parameter: current-array-element-check
          (current-array-element-check [FLAG #f])

     Sets or returns whether array elements are immediately
     type-checked before setting. When false the underlying storage
     type performs any validation.

 -- parameter: current-array-print-count
          (current-array-print-count [COUNT 50])

     Sets or returns the number of array elements to print. A `COUNT'
     of `#f' will set the count 0, and `#t' will set the count to a
     very big number. When `COUNT' is a number it must a zero or
     positive 					fixnum.

 -- parameter: current-array-print-form
          (current-array-print-form [FORM 'SRFI-10])

     Sets or returns the format for printing an array, either
     `'SRFI-10', `'A', or `#f' which 					turns off array element printing.

2.4 Predicates
==============

 -- procedure: array?
          (array? ARRAY)

     Returns whether the object is an array object, or 					accepted as an
     array. Acceptable objects are vector, string, 					byte-vector, and
     SRFI-4 (http://srfi.schemers.org/srfi-4/srfi-4.html)
     vectors.

 -- procedure: array-strict?
          (array-strict? ARRAY)

     Returns whether the object is _only_ an array 					object.

 -- procedure: equal?
          (equal? ARRAY1 ARRAY2)

     Are the two arrays equal in all properties and 					elements?

 -- procedure: array-equal?
          (array-equal? ARRAY1 ARRAY2)

     Are the two arrays equal in dimensionality and elements?

     Signals an error when either of the arguments is not an
     array.

 -- procedure: array-empty?
          (array-empty? ARRAY)

     Returns `#t' for an empty array, `#f' for anything else.

 -- procedure: array-dimensions?
          (array-dimensions? DIMENSIONS)

     A set of dimensions, as produced by `make-array-dimensions'?

 -- procedure: array-shape?
          (array-shape? OBJECT)

     A shape, as produced by `make-array-shape'?

 -- procedure: array-in-bounds?
          (array-in-bounds? ARRAY INDEX ...)

     Are the indices valid for the array?

     Signals an error when not an array.

2.5 Array Properties
====================

 -- procedure: array-store
          (array-store ARRAY)

     Returns the underlying storage object for `ARRAY', or `#f' when
     not an array. Use this at your 					peril.

 -- procedure: array-start
          (array-start ARRAY RANK)

     Returns the start, or lower bound, of `ARRAY' 					along dimension
     `RANK', or `#f' when not 					array.

 -- procedure: array-end
          (array-end ARRAY RANK)

     Returns the end, one beyond the upper bound, of `ARRAY' along
     dimension `RANK', or `#f' 					when not an array.

 -- procedure: array-rank
          (array-rank ARRAY)

     Returns the number of dimensions for `ARRAY', or 					`0' when not an
     array, an empty array, or a rank 0 					array.

 -- procedure: array-dimensions
          (array-dimensions ARRAY)

     Returns the list of dimensions for `ARRAY', or `#f' when not an
     array. The elements are the 					actual length of each dimension, so a
     dimension of 3, [0 3), 					is 3 and [1 3) is 2.

 -- procedure: array-bounds
          (array-bounds ARRAY)

     Returns the bounds list for `ARRAY', or `#f' when not an array. A
     list of pairs, one for each 					dimension. Each pair is the interval
     [low high].

 -- procedure: array-shape
          (array-shape ARRAY)

     Returns the shape list for `ARRAY', or `#f' when not an array. The
     list can be used as `(apply make-array-shape LIST)'.

     To access the compiled shape information of an array use
     `(array-bounds ...)'.

2.6 Array Shape & Dimensions
============================

 -- procedure: make-array-dimensions
          (make-array-dimensions DIMENSION ...)

     Returns a dimensions object.

 -- procedure: make-array-shape
          (make-array-shape START END ...)

     Returns a shape object suitable for use with the array
     construction procedures.

     A shape is composed of an even count series of intervals,
     [start end), for each dimension. Thus an index is within the
     bounds for a dimension if start <= index < end. To indicate an
     empty dimension use start = end, a special case.

     The interval may be on any integer, not just positive and
     0. The start must still be strictly less than the end. So [-5 					-2)
     is legal but [-2 -5) is not.

2.7 Array Operations
====================

 -- procedure: array-print
          (array-print ARRAY [COUNT <very-big-number>] [PORT (current-output-port)])

     Prints `COUNT' elements of the array `ARRAY' on the specified port
     `PORT'.

 -- procedure: array-copy
          (array-copy [PROTOTYPE] ARRAY)

     Returns a copy of the array. When prototype is missing a
     deep copy is performed. When the prototype and the source
     array are the same, `(eq? <prototype> <array>)', a 					fresh
     array is returned with the same shape, using the array 					as
     the prototype. Otherwise a fresh array is returned with the
     specified prototype and elements from the array.

     The prototype and source array element types must be
     assignment compatible. Even so, precision maybe lost.

 -- procedure: make-array
          (make-array [PROTOTYPE] [SHAPE/DIMENSION ...])

     Creates and returns an array of type prototype with
     dimensions or shape, and filled with elements from prototype.

     A valid prototype is any object the meets `(array?  					...)'.

     If the prototype has no elements, then the initial
     elements of the returned array are unspecified.  Otherwise, 					the
     returned array will be filled with the element at the
     origin of prototype.

     `(make-array [<prototype>])' will construct an empty
     array, not a rank 0 array. Such arrays cannot be used with any
     setter or getter. However, property queries will work.

     When the prototype is missing, vector is assumed.

 -- procedure: array
          (array [PROTOTYPE] RANK/SHAPE/DIMENSIONS [ELEMENT ...])

     Creates and returns an array of type prototype with
     dimensions, or shape, or rank and filled with the elements.

     When a rank is specified, it must be 0 or positive. When
     positive it is interpreted as the dimensions ((- rank 0) (- 					rank
     1) ... (/ <# of elements> (factorial rank))). So rank 1 					is
     (<#>), 2 is (2 <#>/2), 3 is (3 2 <#>/3x2), and so on. This 					is of
     dubious utility.

     When the prototype is missing, vector is assumed.

 -- procedure: make-shared-array
          (make-shared-array ARRAY MAPPER [SHAPE/DIMENSION ...])

     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.

 -- procedure: list->array
          (list->array SHAPE/DIMENSIONS/RANK PROTOTYPE LIST)

     The list must be a rank-nested list consisting of all the
     elements, in row-major order, of the array to be created.

     Returns an array of rank, or shape, or dimensions and type
     prototype consisting of all the elements, in row-major order, 					of
     the list.  When the rank is 0, list is the lone array
     element; not necessarily a list.

 -- procedure: array->list
          (array->list ARRAY)

     Returns the array elements as a rank-nested list. For 					rank
     0 arrays returns just the element. Will generate an error
     when not an array.

 -- procedure: vector->array
          (vector->array VECTOR PROTOTYPE [SHAPE/DIMENSION ...])

     The vector must be of length equal to the product of the
     dimensions, or shape element sizes.

     Returns an array of type prototype consisting of all the
     elements, in row-major order, of the vector.  In the case of a
     rank 0 array, the vector has a single element.

 -- procedure: array->vector
          (array->vector ARRAY)

     Returns the array elements as a new unpacked vector. Will
     generate an error when not an array.

 -- procedure: array-ref
          (array-ref ARRAY INDEX ...)

     Returns the array element at indices. Will generate an
     error when not an array or out-of-range condition.

 -- procedure: array-set!
          (array-set! ARRAY OBJECT INDEX ...)

     Sets the array element at indices to the object. Will
     generate an error when not an array, out-of-range 					condition, or
     the object is unsuitable as an array element.

2.8 Sub-Array Operations
========================

These are not part of the basic package. Be sure to `(use
array-lib-sub)' for access.

 -- procedure: subarray
          (subarray ARRAY [SELECT ...])

     Returns a subarray sharing elements with `ARRAY'.  					For an
     array of rank N, there must be at least N `SELECT' arguments. For
     0 <= I < N, `SELECT'[I] is 					either an integer, a list of two
     integers within the range for 					the Ith index, or `#f'.

     When `SELECT'[I] is a list of two integers, then 					the Ith index is
     restricted to that subrange in the returned 					array.

     When `SELECT'[I] is `#f', then the full 					range of the Ith
     index is accessible in the returned array.  					An elided argument is
     equivalent to `#f'.

     When `SELECT'[I] is an integer, then the rank of 					the returned
     array is less than `ARRAY', and only 					elements whose Ith
     index equals `SELECT'[I] are 					shared.

 -- procedure: array-trim
          (array-trim ARRAY [TRIM ...])

     Returns a subarray sharing elements with `ARRAY' 					except for slices
     removed from either side of each dimension.  					Each of the `TRIM'
     arguments is an exact integer 					indicating how much to trim.  A
     positive `TRIM' trims 					the data from the lower end and
     reduces the upper bound of the 					result; a negative `TRIM' trims
     from the upper end 					and increases the lower bound.

 -- procedure: array-row-ref
          (array-row-ref ARRAY INDEX ...)

     Returns the array row, as an unpacked vector, at indices.  					Will
     generate an error when not an array or out-of-range
     condition. The number of indices must be one less than the 					rank.

 -- procedure: array-row-set!
          (array-row-set! ARRAY OBJECT INDEX ...)

     Sets the array row at indices to the object. Will generate 					an
     error when not an array, out-of-range condition, or the
     object is unsuitable as an array row. The number of indices 					must
     be one less than the rank.

     The row object may be an one dimensional array, a list, or 					an
     atomic value. The row object length must match the target
     array row length. When an atomic value this operation is row 					fill.

 -- procedure: array-split
          (array-split ARRAY OUTER-RANK)

     Return a list of fresh subarrays, split along the 					specified outer
     rank, in ascending order by outer index.

 -- procedure: array-split/shared
          (array-split/shared ARRAY OUTER-RANK)

     Return a list of shared subarrays, split along the
     specified outer rank, in ascending order by outer index.

 -- procedure: array-join
          (array-join PROTOTYPE OUTER-SHAPE/DIMENSIONS [INNER-SHAPE/DIMENSIONS] [ARRAY ...])

     Construct a fresh array with specified prototype, outer
     dimensions, and optional inner dimensions, from the specified
     inner array(s).

     The outer dimension maybe a number (indicating the single, 					outer,
     dimension), a list of dimensions, a shape, or `#f'
     (indicating the count of the inner arrays is the outer
     dimension).

     If specified the inner dimension maybe a list of 					dimensions, or a
     shape. If missing the first inner array shape 					is used as the inner
     shape for the result array.

     The result array shape is the concatenation of the outer
     and inner shapes. The rank of the result array must be greater
     than the rank the inner array(s).

     All joined arrays must be of the same dimensionality.

 -- procedure: array-reverse
          (array-reverse ARRAY)

     Returns a fresh array with the top-level dimension
     reversed.

2.9 Higher Order Operations
===========================

These are not part of the basic package. Be sure to `(use
array-lib-hof)' for access.

 -- procedure: make-array-index-generator
          (make-array-index-generator SHAPE/DIMENSIONS/ARRAY)

     Returns a zero argument procedure which returns an indices 					list (a
     full index) for the specified bounds upon each 					invocation, or `#f'
     when the indices are exhausted.

     An indices list is suitable for use with `(apply
     array-ref/array-set! ... indices)'.

 -- procedure: array-for-each-index
          (array-for-each-index PROCEDURE [SHAPE/DIMENSIONS/ARRAY ...])

     Invokes the procedure with each set of indices for the
     specified bounds. The procedure arity is equal to the number 					of
     bounds. Each argument is a list of the indices, with rank
     length (length of the bounds).

     When an array is specified the bounds of the array are
     used.

     An indices list is suitable for use with `(apply
     array-ref/array-set! ... indices)'.

     All arrays should be of the same dimensions. The operation will
     terminate when any of the set of indices is exhausted.

 -- procedure: array-for-each
          (array-for-each PROCEDURE [ARRAY ...])

     Apply the procedure to each element of the array(s). The
     procedure arity is equal to the number of the array(s).

     All arrays must be of the same dimensionality.

 -- procedure: array-map!
          (array-map! ARRAY PROCEDURE [ARRAY ...])

     Apply the procedure to each element of the array(s). The
     procedure arity is equal to the number of the array(s).

     Returns the first array with the mapped elements. An
     in-place map.

     All arrays must be of the same dimensionality.

 -- procedure: array-map
          (array-map PROTOTYPE PROCEDURE ARRAY ...)

     Apply the procedure to each element of the array(s). The
     procedure arity is equal to the number of the array(s).

     Returns a fresh array from the `PROTOTYPE' and 					the shape of the
     first `ARRAY' with the mapped 					elements.

     All arrays must be of the same dimensionality.

 -- procedure: array-fold
          (array-fold PROCEDURE SEED ARRAY ...)

     Apply the fold procedure to each element of the array(s).  					The
     procedure arity is 1 + the number of array(s). The first
     argument is the current accumulated value, or the initial
     seed. The rest of the arguments are the array elements.

     Returns the accumulated value.

     All arrays must be of the same dimensionality.

 -- procedure: array-project
          (array-project PROTOTYPE RANK/SHAPE/DIMENSIONS PROJECTOR ARRAY)

     Conform an N dimensional source array to a fresh M
     dimensional destination array.

     The projector takes 2 arguments, the destination row
     vector and the source row vector. The destination vector
     length is M and the source vector is length N. The projector 					is
     not required to use the supplied destination vector.
     However, it must return some vector of length M.

     Returns the array projection.

 -- procedure: array-index-map!
          (array-index-map! ARRAY PROCEDURE)

     Applys the `PROCEDURE' to each list of indexes of 					the `ARRAY' and
     replaces the existing element with 					the result of the
     procedure application.

 -- procedure: array-indexes
          (array-indexes ARRAY)

     Returns an array of lists of indexes for the `ARRAY'.

 -- procedure: array-copy!
          (array-copy! DESTINATION-ARRAY SOURCE-ARRAY)

     Copy the elements of the source array to the corresponding
     elements of the destination array. The source and destination
     arrays must have the same dimensions, but not necessarily the 					same
     shape.

     The source and destination element types must be 					assignment
     compatible. Even so, precision maybe lost.

2.10 Eager Comprehensions
=========================

These are not part of the basic package. Be sure to `(use
array-lib-ec)' for access. Requires SRFI-42
(http://www.call-with-current-continuation.org/eggs/srfi-42.html).

 -- macro: array-ec
          (array-ec PROTOTYPE SHAPE/DIMENSIONS [QUALIFIER ...] EXPRESSION)

     Returns an array with specified `PROTOTYPE', and
     `SHAPE/DIMENSIONS'. Each element of the fresh array is
     produced by evaluating the `EXPRESSION' for every 					state generated
     by the set of `QUALIFIER'.

     Should more states be generated than elements of the array 					they
     are ignored.

 -- macro: :array
          (:array VARIABLE [(index INDEX-VARIABLE ...)] ARRAY ...)

     Generate each element of each `ARRAY', binding 					the element to
     `VARIABLE'. Should the indices be 					wanted there must be as many
     `INDEX-VARIABLE' items 					as the rank of greatest dimensioned
     array.

2.11 Prototypes
===============

 -- procedure: a:floc128b
          (a:floc128b [INITIAL <undefined>])

     Returns an inexact 128 bit flonum complex uniform-array
     prototype.

 -- procedure: a:floc64b
          (a:floc64b [INITIAL <undefined>])

     Returns an inexact 64 bit flonum complex uniform-array
     prototype.

 -- procedure: a:floc32b
          (a:floc32b [INITIAL <undefined>])

     Returns an inexact 32 bit flonum complex uniform-array
     prototype.

 -- procedure: a:floc16b
          (a:floc16b [INITIAL <undefined>])

     Returns an inexact 16 bit flonum complex uniform-array
     prototype.

 -- procedure: a:flor128b
          (a:flor128b [INITIAL <undefined>])

     Returns an inexact 128 bit flonum real uniform-array
     prototype.

 -- procedure: a:flor64b
          (a:flor64b [INITIAL <undefined>])

     Returns an inexact 64 bit flonum real uniform-array
     prototype.

 -- procedure: a:flor32b
          (a:flor32b [INITIAL <undefined>])

     Returns an inexact 32 bit flonum real uniform-array
     prototype.

 -- procedure: a:flor16b
          (a:flor16b [INITIAL <undefined>])

     Returns an inexact 16 bit flonum real uniform-array
     prototype.

 -- procedure: a:floq128b
          (a:floq128b [INITIAL <undefined>])

     Returns an exact 128 bit decimal flonum rational 					uniform-array
     prototype.

 -- procedure: a:floq64b
          (a:floq64b [INITIAL <undefined>])

     Returns an exact 64 bit decimal flonum rational 					uniform-array
     prototype.

 -- procedure: a:floq32b
          (a:floq32b [INITIAL <undefined>])

     Returns an exact 32 bit decimal flonum rational 					uniform-array
     prototype.

 -- procedure: a:fixz64b
          (a:fixz64b [INITIAL <undefined>])

     Returns an exact binary fixnum uniform-array prototype
     with at least 64 bits of precision.

 -- procedure: a:fixz32b
          (a:fixz32b [INITIAL <undefined>])

     Returns an exact binary fixnum uniform-array prototype
     with at least 32 bits of precision.

 -- procedure: a:fixz16b
          (a:fixz16b [INITIAL <undefined>])

     Returns an exact binary fixnum uniform-array prototype
     with at least 16 bits of precision.

 -- procedure: a:fixz8b
          (a:fixz8b [INITIAL <undefined>])

     Returns an exact binary fixnum uniform-array prototype
     with at least 8 bits of precision.

 -- procedure: a:fixn64b
          (a:fixn64b [INITIAL <undefined>])

     Returns an exact non-negative binary fixnum uniform-array
     prototype with at least 64 bits of precision.

 -- procedure: a:fixn32b
          (a:fixn32b [INITIAL <undefined>])

     Returns an exact non-negative binary fixnum uniform-array
     prototype with at least 32 bits of precision.

 -- procedure: a:fixn16b
          (a:fixn16b [INITIAL <undefined>])

     Returns an exact non-negative binary fixnum uniform-array
     prototype with at least 16 bits of precision.

 -- procedure: a:fixn8b
          (a:fixn8b [INITIAL <undefined>])

     Returns an exact non-negative binary fixnum uniform-array
     prototype with at least 8 bits of precision.

 -- procedure: a:bool
          (a:bool [INITIAL <undefined>])

     Returns a boolean uniform-array prototype.

 -- procedure: ac64
          (ac64 [INITIAL <undefined>])

     Returns an inexact 64 bit flonum complex uniform-array
     prototype.

 -- procedure: ac32
          (ac32 [INITIAL <undefined>])

     Returns an inexact 32 bit flonum complex uniform-array
     prototype.

 -- procedure: ar64
          (ar64 [INITIAL <undefined>])

     Returns an inexact 64 bit flonum real uniform-array
     prototype.

 -- procedure: ar32
          (ar32 [INITIAL <undefined>])

     Returns an inexact 32 bit flonum real uniform-array
     prototype.

 -- procedure: as64
          (as64 [INITIAL <undefined>])

     Returns an exact binary fixnum uniform-array prototype
     with at least 64 bits of precision.

 -- procedure: as32
          (as32 [INITIAL <undefined>])

     Returns an exact binary fixnum uniform-array prototype
     with at least 32 bits of precision.

 -- procedure: as16
          (as16 [INITIAL <undefined>])

     Returns an exact binary fixnum uniform-array prototype
     with at least 16 bits of precision.

 -- procedure: as8
          (as8 [INITIAL <undefined>])

     Returns an exact binary fixnum uniform-array prototype
     with at least 8 bits of precision.

 -- procedure: au64
          (au64 [INITIAL <undefined>])

     Returns an exact non-negative binary fixnum uniform-array
     prototype with at least 64 bits of precision.

 -- procedure: au32
          (au32 [INITIAL <undefined>])

     Returns an exact non-negative binary fixnum uniform-array
     prototype with at least 32 bits of precision.

 -- procedure: au16
          (au16 [INITIAL <undefined>])

     Returns an exact non-negative binary fixnum uniform-array
     prototype with at least 16 bits of precision.

 -- procedure: au8
          (au8 [INITIAL <undefined>])

     Returns an exact non-negative binary fixnum uniform-array
     prototype with at least 8 bits of precision.

 -- procedure: at1
          (at1 [INITIAL <undefined>])

     Returns a boolean uniform-array prototype.

3 Issues
********

SRFI-25 indexing is 2.4 times faster! However, 'array-lib' has
faster indexing than the reference SRFI-63 implementation.

   Should signal specific conditions rather than an error.

   Array aggregate operations are implemented in an element by
element fashion.

   The SRFI-42 general dispatcher `(: ...)' does not 			recognize arrays.

   The 64-bit prototypes are currently implemented as unpacked
vectors.

   The prototypes will play well with the 'numbers' egg.

   Needs a comprehensive test suite.

4 Examples
**********

(use array-lib)

(current-array-print-form 'A)

(array-dimensions (make-array '#() 3 5))
=> (3 5)

(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

(list->array 2 '#() '((1 2) (3 4)))
=> #A2((1 2) (3 4))
(list->array 0 '#() 3)
=> #A0 3

(array->list (array '#() '(2 3) 'ho 'ho 'ho 'ho 'oh 'oh))
=> ((ho ho ho) (ho oh oh))
(array->list (array '#() 0 'ho))
=> ho

(vector->array (vector 1 2 3 4) '#() 2 2)
=> #A2((1 2) (3 4))
(vector->array '#(3) '#())
=> #A0 3

(array->vector (array '#() (make-array-shape 0 2 0 2) 1 2 3 4))
=> #(1 2 3 4)
(array->vector (array '#() 0 'ho))
=> #(ho)

;;
;; See "array-lib-test.scm" in the unpacked egg for more examples.
;;

5 License
*********

Copyright (c) 2006, Kon Lovett.  All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the Software),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED ASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Does not supercede any restrictions found in the source code.