This SRFI is currently in final status. Here is an explanation of each status that a SRFI can hold. To provide input on this SRFI, please send email to srfi-58 @nospamsrfi.schemers.org
. To subscribe to the list, follow these instructions. You can access previous messages via the mailing list archive.
#nA
" followed by the list-decomposition of
the array, is the same as the Common-Lisp read-syntax for arrays.
#n(v1 v2
... vk)
creates a vector of size N, with the final
value, vk, repeated (N - K) times. It's an error if (K >
N) or if (K = 0 and N > 0). Examples:
#5(1 2) ==> #(1 2 2 2 2) #2(1 2) ==> #(1 2) #0() ==> #() #1(1 2) ==> error: too many values #5() ==> error: no values for non-empty array
The rank and dimension of the literal array can be specified several ways.
#
and A
;
*
after
A
; or
*
after
#
.
Both rank and dimensions can be supplied on opposite sides of
A
.
:
).
The names of the array-prototype-procedures of
SRFI-63
and aliases for the array-prototype-procedures of
SRFI-47
match these type denotations with A
prepended. Having
the array-prototype-procedure names match the array type denotations
reduces the memory load for users.
All implementations must accept all the type denotations, but need not implement all the homogeneous array types. Those homogeneous types which an implementation doesn't support it stores in next best homogeneous array type, defaulting to heterogeneous arrays in the worst case. The rules for casting unsupported types are given in SRFI-63.
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. Vectors may substitute for lists at any nesting depth.
Rank 0 arrays have one element; that element appears after the prefix (perhaps with intervening whitespace) with no additional parenthesis.
Rank 1 character arrays which are not subarrays are
write
n as Scheme strings; display
treats
rank 1 character arrays which are not subarrays identically with
strings.
Rank 1 heterogeneous arrays which are not subarrays
write
and display
as Scheme vectors.
The prefix syntax is:
array-prefix :: rank `A' [ dimensions ] [ `:' type-specifier ] | [ `A' ] dimensions [ `:' type-specifier ] dimensions :: dimension | dimensions `*' dimension dimension :: nonnegative-integer rank :: nonnegative-integer type-specifier :: `flo' { `C' | `R' } flowidth `b' | `fix' { `Z' | `N' } fixwidth `b' | `flo' `Q' decwidth `d' flowidth :: `16' | `32' | `64' | `128' fixwidth :: `8' | `16' | `32' | `64' decwidth :: `32' | `64' | `128'
prototype procedure | exactness | element type | type specifier |
---|---|---|---|
vector | any |
| |
A:floC128b | inexact | 128.bit binary flonum complex | floC128b
|
A:floC64b | inexact | 64.bit binary flonum complex | floC64b
|
A:floC32b | inexact | 32.bit binary flonum complex | floC32b
|
A:floC16b | inexact | 16.bit binary flonum complex | floC16b
|
A:floR128b | inexact | 128.bit binary flonum real | floR128b
|
A:floR64b | inexact | 64.bit binary flonum real | floR64b
|
A:floR32b | inexact | 32.bit binary flonum real | floR32b
|
A:floR16b | inexact | 16.bit binary flonum real | floR16b
|
A:floQ128d | exact | 128.bit decimal flonum rational | floQ128d
|
A:floQ64d | exact | 64.bit decimal flonum rational | floQ64d
|
A:floQ32d | exact | 32.bit decimal flonum rational | floQ32d
|
A:fixZ64b | exact | 64.bit binary fixnum | fixZ64b
|
A:fixZ32b | exact | 32.bit binary fixnum | fixZ32b
|
A:fixZ16b | exact | 16.bit binary fixnum | fixZ16b
|
A:fixZ8b | exact | 8.bit binary fixnum | fixZ8b
|
A:fixN64b | exact | 64.bit nonnegative binary fixnum | fixN64b
|
A:fixN32b | exact | 32.bit nonnegative binary fixnum | fixN32b
|
A:fixN16b | exact | 16.bit nonnegative binary fixnum | fixN16b
|
A:fixN8b | exact | 8.bit nonnegative binary fixnum | fixN8b
|
A:bool | boolean | bool
| |
string | char | char
|
A two-by-three array of nonnegative 16.bit integers can be written several ways:
#2A:fixN16b((0 1 2) (3 5 4)) #2A2*3:fixN16b((0 1 2) (3 5 4)) #A2*3:fixN16b((0 1 2) (3 5 4)) #2*3:fixN16b((0 1 2) (3 5 4))
Note that these are external representations of an array, not expressions evaluating to arrays. Like vector constants, array constants should be quoted:
'#2a:FIXN16b((0 1 2) (3 5 4)) ==> #2A:fixN16b((0 1 2) (3 5 4))
Rank 0 arrays:
#0a sym #0A:floR32b 237.0
Empty arrays:
#A0*2() #A2*0(() ()) #A2*0*3(() ()) #A2*3*0((() () ()) (() () ()))
(array-dimensions '#2A:fixN16b((0 1 2) (3 5 4))) ==> (2 3)
An equivalent array could have been created by
(define ra (make-array (A:fixN16b) 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) ra ==> #2A:fixN32b((0 1 2) (3 5 4))
In this example, the uniform type returned is wider than requested due to implementation restrictions.
It is an error for the rank specified in array syntax to be different from the number of dimensions when they are explicitly given.
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-63, which supersedes SRFI-47, already defines these array-prototype-procedures.
;; flonums (define A:floC128b ac64) (define A:floC64b ac64) (define A:floC32b ac32) (define A:floC16b ac32) (define A:floR128b ar64) (define A:floR64b ar64) (define A:floR32b ar32) (define A:floR16b ar32) ;; decimal flonums (define A:floQ128d ar64) (define A:floQ64d ar64) (define A:floQ32d ar32) ;; fixnums (define A:fixZ64b as64) (define A:fixZ32b as32) (define A:fixZ16b as16) (define A:fixZ8b as8) (define A:fixN64b au64) (define A:fixN32b au32) (define A:fixN16b au16) (define A:fixN8b au8) (define A:bool at1)
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).
;;; Read integer up to first non-digit (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-type port) (define (bomb pc wid) (error 'array 'syntax? (symbol-append "#" rank "A" pc wid))) (case (char-downcase (peek-char port)) ((#\:) (read-char port) (let ((typ (let loop ((arg '())) (if (= 4 (length arg)) (string->symbol (list->string (reverse arg))) (let ((c (read-char port))) (and (not (eof-object? c)) (loop (cons (char-downcase c) arg)))))))) (define wid (and typ (not (eq? 'bool typ)) (read:try-number port))) (define (check-suffix chrs) (define chr (read-char port)) (if (and (char? chr) (not (memv (char-downcase chr) chrs))) (error 'array-type? (symbol-append ":" typ wid chr)))) (define prot (assq typ '((floC (128 . +64.0i) (64 . +64.0i) (32 . +32.0i) (16 . +32.0i)) (floR (128 . 64.0) (64 . 64.0) (32 . 32.0) (16 . 32.0)) (fixZ (64 . -64) (32 . -32) (16 . -16) (8 . -8)) (fixN (64 . 64) (32 . 32) (16 . 16) (8 . 8)) (char . #\a) (bool . #t)))) (if prot (set! prot (cdr prot))) (cond ((pair? prot) (set! prot (assv wid (cdr prot))) (if (pair? prot) (set! prot (cdr prot))) (if wid (check-suffix (if (and (inexact? prot) (real? prot)) '(#\b #\d) '(#\b))))) (prot) (else (check-suffix '()))) prot)) (else #f))) ;;; We come into read:array with number or #f for RANK. (define (read:array rank dims port reader) ;ignore reader (let loop ((dims dims)) (define dim (read:try-number port)) (if dim (loop (cons dim dims)) (case (peek-char port) ((#\*) (read-char port) (loop dims)) ((#\:) (let ((typ (read-array-type port))) (list->uniform-array (or rank (length dims)) typ (read port)))) (else (list->uniform-array (or rank (length dims)) #f (read port))))))) (define (read:sharp c port read) (case c ((#\a #\A) (read:array #f '() port read)) ((#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9) (let* ((num (read:try-number port c)) (chr (peek-char port))) (case chr ((#\a #\A) (read-char port) (read:array num '() port read)) ((#\*) (read-char port) (read:array #f (list num) port read)) (else (read:array 1 (list num) port read))))) (else (error "unknown # object" c))))
Copyright (C) Aubrey Jaffer (2004, 2005). 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 "AS IS", 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.