[HARLEQUIN][Common Lisp HyperSpec (TM)] [Previous][Up][Next]


Issue AREF-1D Writeup

Issue:        AREF-1D

References: Arrays (pp286-298)

Category: ENHANCEMENT

Edit history: 22-Apr-87, Version 1 by Pitman

02-Jun-87, Version 2 by Pitman (ROW-MAJOR-AREF)

6-Jun-87, Versions 3, 4 by Masinter (editorial)

11-Jun-87, Version 5, to X3J13 (no changes)

6-Jul-87, Version 6, by Masinter

14-Nov-87, Version 7, by Masinter (update discussion)

Problem Description:

It's hard to write functions like Maclisp's LISTARRAY and FILLARRAY efficiently

in Common Lisp because they take arguments of varying rank. Currently, you have

to make a displaced array to work with temporarily and then throw away the

displaced array when you're done. In many cases, this is bothersome because

there is no a priori reason why they should have to cons at all.

Proposal (AREF-1D:ROW-MAJOR-AREF):

Introduce a new function ROW-MAJOR-AREF that allows one-dimensional access to

the storage backing up a given array assuming the normal row-major storage

layout.

ROW-MAJOR-AREF is valid for use with SETF.

row-major-aref array index [Function]

This accesses and returns the element of array specified by index when the

elements of array are considered in row-major order. Array may be an array of

any dimensionality. row-major-aref may be used with setf. For reference, the

following sets of expressions are equivalent:

(row-major-aref array index) ==

(aref (make-array (array-total-size array)

:displaced-to array

:element-type (array-element-type array))

index)

and

(aref array .. subscripts ..) ==

(row-major-aref array (array-row-major-index array .. subscripts ..))

Rationale:

Common Lisp requires row-major storage layout of arrays and has a number of

operators that allow users to exploit that order. ROW-MAJOR-AREF is a useful,

simple addition.

LISTARRAY and FILLARRAY, for example, could be trivially defined by loops that

had the following form:

(DOTIMES (I (ARRAY-TOTAL-SIZE ARRAY))

... (ROW-MAJOR-AREF ARRAY I) ...)

Currently, the only really efficient way to write this would involve something

like:

(ECASE (ARRAY-RANK ARRAY1)

((0) (SETF (AREF ARRAY1) (AREF ARRAY2)))

((1) (DOTIMES (I (ARRAY-DIMENSION ARRAY 0))

(SETF (AREF ARRAY1 I) (AREF ARRAY2 I))))

((2) (DOTIMES (I (ARRAY-DIMENSION ARRAY 0))

(DOTIMES (I (ARRAY-DIMENSION ARRAY 1))

(SETF (AREF ARRAY1 I J) (AREF ARRAY2 I J)))))

...some finite number of clauses...)

Current Practice:

Many implementations have this primitive under some other name for use

internally. In Symbolics systems, for example, it is SYS:%1D-AREF.

Adoption Cost:

This change is fairly localized. In implementations that already use this

primitive internally, it's little more than a matter of changing the name of or

otherwise releasing the existing primitive. In some implementations, it might

involve writing a small amount of code or compiler work to make ROW-MAJOR-AREF

work efficiently.

Benefits:

This gives users efficient access to something to which they already have

inefficient access.

Conversion Cost:

This is an upward-compatible change; the name ROW-MAJOR-AREF is unlikely to be

used by any current program.

Aesthetics:

This allows certain programs to be written in a more aesthetic way.

Discussion:

This issue was conditionally passed at X3J13/June 1987, pending clarification of

some details. Those clarifications have been made in this version.


[Starting Points][Contents][Index][Symbols][Glossary][Issues]
Copyright 1996, The Harlequin Group Limited. All Rights Reserved.