Title

Array Notation

Authors

Aubrey Jaffer and Radey Shouman

Status

This SRFI is currently in ``draft'' status. To see an explanation of each status that a SRFI can hold, see here. It will remain in draft status until 2005/01/26, or as amended. To provide input on this SRFI, please mailto:srfi-58@srfi.schemers.org. See instructions here to subscribe to the list. You can access previous messages via the archive of the mailing list.

Abstract

SRFI-47 provides both uniform-typed and heterogeneous multidimensional arrays which subsume Scheme vectors. The notation presented here builds upon Common-Lisp array sytnax to represent heterogeneous and uniform-typed arrays.

Issues

Original Proposal
prototype
procedure
exactness element type prefix
(rank = n)
vector any #nA
ac64 inexactIEEE 64.bit floating point complex#nAc64
ac32 inexactIEEE 32.bit floating point complex#nAc32
ar64 inexactIEEE 64.bit floating point real #nAr64
ar32 inexactIEEE 32.bit floating point real #nAr32
as64 exact 64.bit integer #nAs64
as32 exact 32.bit integer #nAs32
as16 exact 16.bit integer #nAs16
as8 exact 8.bit integer #nAs8
au64 exact 64.bit nonnegative integer #nAu64
au32 exact 32.bit nonnegative integer #nAu32
au16 exact 16.bit nonnegative integer #nAu16
au8 exact 8.bit nonnegative integer #nAu8
string char #nA\
at1 boolean #nAt

Rationale

SRFI-47, "Array", incorporates all the uniform vector types from SFRI-4 "Homogeneous numeric vector datatypes", and adds a boolean array type and array types of complex numbers composed of two IEEE 32.bit or two IEEE 64.bit floating-point numbers. Multi-dimensional arrays subsume homogeneous vectors as the one-dimensional case, obviating the need for SRFI-4.

Implementations are required to accept all of the type denotations. Those which the platform supports will have platform-dependent representations; the others will be represented as the next larger uniform-type implemented; defaulting to vector if there are none.

Aliases for the array-prototype-procedures of SRFI-47 are defined whose identifiers are the #nA:typename prefix sans the #n. Having the array-prototype-procedure names match the array prefixes reduces the memory load for users.

This arrangement has platforms supporting uniform array types using them, with less capable platforms using vectors; both from the same source code.

Specification

Syntax

The syntax for arrays is a prefix according to the type and rank of the array followed by the list-decomposition of an array. The prefix must be immediately followed by a delimiter. Upper and lower case forms of a letter are not distinguished in the prefix characters.

By list-decomposition is meant rank nestings of lists of the elements where the most nested list has length equal to the last dimension of the array and at top level has length equal to the first dimension of the array.

Rank 0 arrays have one element; that element appears after the prefix (perhaps with intervening whitespace) with no additional parenthesis.

Rank 1 heterogeneous arrays which are not subarrays write and display as Scheme vectors.

prototype
procedure
exactness element type prefix
(rank = n)
vector any #nA
A:complex-64inexactIEEE 64.bit floating point complex#nA:complex-64
A:complex-32inexactIEEE 32.bit floating point complex#nA:complex-32
A:real-64 inexactIEEE 64.bit floating point real #nA:real-64
A:real-32 inexactIEEE 32.bit floating point real #nA:real-32
A:integer-64exact 64.bit integer #nA:integer-64
A:integer-32exact 32.bit integer #nA:integer-32
A:integer-16exact 16.bit integer #nA:integer-16
A:integer-8 exact 8.bit integer #nA:integer-8
A:integer+64exact 64.bit nonnegative integer #nA:integer+64
A:integer+32exact 32.bit nonnegative integer #nA:integer+32
A:integer+16exact 16.bit nonnegative integer #nA:integer+16
A:integer+8 exact 8.bit nonnegative integer #nA:integer+8
A:boolean boolean #nA:boolean

A two-by-three array of nonnegative 16.bit integers is written:

#2A:integer+16((0 1 2) (3 5 4))
Note that this is the external representation of an array, not an expression evaluating to a array. Like vector constants, array constants must be quoted:
'#2a:INTEGER+16((0 1 2) (3 5 4))
               ==> #2A:integer+16((0 1 2) (3 5 4))

Rank 0 arrays:

#0a sym
#0A:real-32 237.0

Semantics

(array-dimensions '#2A:integer+16((0 1 2) (3 5 4))) ==> (2 3)

An equivalent array could have been created by

(define ra (make-array (A:integer+16) 2 3))
(array-set! ra 0 0 0)
(array-set! ra 1 0 1)
(array-set! ra 2 0 2)
(array-set! ra 3 1 0)
(array-set! ra 5 1 1)
(array-set! ra 4 1 2)

Literal array constants are immutable objects. It is an error to attempt to store a new value into a location that is denoted by an immutable object.

The following equivalences will be defined to alias SRFI-47 names to the new ones. SRFI-47 should be amended or replaced to make these be the array-prototype-procedures:

(define A:complex-64 ac64)
(define A:complex-32 ac32)
(define A:real-64    ar64)
(define A:real-32    ar32)
(define A:integer-64 as64)
(define A:integer-32 as32)
(define A:integer-16 as16)
(define A:integer-8  as8)
(define A:integer+64 au64)
(define A:integer+32 au32)
(define A:integer+16 au16)
(define A:integer+8  au8)
(define A:boolean    at1)

Implementation

The following code from the SCM implementation ("Init5d9.scm") implements array read-syntax. read:sharp is called from read when a #\# is read. Its first argument is the character after #\#; the second argument is the input port; the third argument is the procedure to call for recursive reading.

list->uniform-array converts the list-decomposition returned by read into the uniform array of the specified type (or the next larger compatible type).

(define (read:sharp c port read)
  (case c
    ((#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9)
     (let* ((num (read:try-number port c))
            (c (peek-char port)))
       (cond ((memv c '(#\a #\A))
              (read-char port)
              (read:array num port read))
             (else (error "syntax? #" num c)))))
    (else (error "unknown # object" c))))

(define (read:try-number port . ic)
  (define chr0 (char->integer #\0))
  (let loop ((arg (and (not (null? ic))
                       (- (char->integer (car ic)) chr0))))
    (let ((c (peek-char port)))
      (cond ((eof-object? c) #f)
            ((char-numeric? c)
             (loop (+ (* 10 (or arg 0))
                      (- (char->integer (read-char port)) chr0))))
            (else arg)))))

(define (read:array rank port reader)   ;ignore reader
  (define (bomb pc wid)
    (error (string-append "array syntax? #"
                          (number->string rank)
                          "A" (string pc)
                          (if wid (number->string wid) ""))))
  (list->uniform-array
   rank
   (case (char-downcase (peek-char port))
     ((#\:)
      (read-char port)
      (let ((typ (read port)))
        (case typ
          ((complex-64) +64.0i)
          ((complex-32) +32.0i)
          ((real-64)     64.0)
          ((real-32)     32.0)
          ((integer-64) -64)
          ((integer-32) -32)
          ((integer-16) -16)
          ((integer-8)   -8)
          ((integer+64)  64)
          ((integer+32)  32)
          ((integer+16)  16)
          ((integer+8)    8)
          ((boolean)     #t))))
     (else #f))
   (read port)))

Copyright

Copyright (C) Aubrey Jaffer (2004, 2005). All Rights Reserved.

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Scheme Request For Implementation process or editors, except as needed for the purpose of developing SRFIs in which case the procedures for copyrights defined in the SRFI process must be followed, or as required to translate it into languages other than English.

The limited permissions granted above are perpetual and will not be revoked by the authors or their successors or assigns.

This document and the information contained herein is provided on an "AS IS" basis and THE AUTHOR AND THE SRFI EDITORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.


Editor: David Van Horn
Last modified: Wed Jan 5 11:47:26 EST 2005