CommonLisp-Compatible Array FunctionsFile:CMLARRAY.ttyRevised:Feb 21, Jul 1, and Sep 28, 1983, by JonL WhiteThe following functions are based on the definitions in theCommonLisp community, and provide many features lacking in Interlisp'sARRAY support, in particular multi-dimensional arrays, shared arrays,and super-fast accessing ("open-coding" of access with "unsafe"primitives). These definitions follow those from the "Excelsior" editionof the CommonLisp manual (5 August 1983, copyright Guy L. Steele Jr.)and some of the prose below is reproduced from the aforesaid "Excelsior" edition by permission.Documentation TerminologyNot all options and features of the Common Lisp specifiction are implemented; descriptions of limitations are encolsed as notes within double square brackets. Furthermore, for the benefit of Interlisp-D users, some non-portable extensions have been made, and these are described as noted within single square brackets.A number of functions take arguments in "keyword" format; this meansthat the arglist, after some point, alternates between an argument whichnames the meaning of the next argument and the next "real" argument.E.g., suppose COLORMYWORLD is a function with conceptually dozensof parameters, but which is typically called with only one or two ofthem set to a non-default value. Then you might see(COLORMYWORLD SOMEBITMAP 'HUE BLUE 'DURATION 5HOURS)where the first argument is "required", but all the others are optionaland are obtained from the appropriate pair in the real arglist; in thisexample, one such "keyword" argument is called HUE, and it will be set to the value of the variable BLUE; also "coloring" will last for aduration of time found in the variable 5HOURS.As a general rule, any symbol ("litatom" in the Interlisp sense)which has a "-" in its name, will have those "-"'s removed in theInterlisp incarnation (because of weird potential interaction with CLISP). Thus, MAKE-ARRAY in the CommonLisp manual becomes MAKEARRAYin the Interlisp world. Also, since Interlisp doesn't have &optional,&rest, or &key argument spreading, then any function with such anargument spectrum will be implemented as a no-spread lambda; curlybrackets will enclose the name for a sequence of such arguments.Creation of ArraysAn array, for the purpose of this documentation, is an instance of anew datatype (called CMLARRAY), and is not related to the previously-documented Interlisp array facility. By convention, all indexing in theCommonLisp world is 0-origin.(MAKEARRAY ... {keyword-arguments} ... ) is a list of non-negative integers that are to bethe dimensions of the array; the length of the list will be the rank, orCMLARRAY.TTY 3-Oct-83 22:57:02Page 1la% ^l ]l. LV; UCF SE R)? PI OE MI KH LEA D4F BL AH ?$ L is NIL, then a zero-dimensional array is created. For convenience when making a one-dimensional array, the single dimension may be provided as an integer rather than a list of one integer. The keyword arguments are:ELEMENTTYPE- T, [or NIL, or POINTER] means that the elements are all generalLisp "pointers"; this is the default.- FIXNUM, [or FIXP, or CELL] for entries which are integers stored as 2's complement 32-bits [[31-bits in Interlisp/VAX, 36-bitsin Interlisp-10]]- FLONUM, [or FLOATP] entries are all 32-bit IEEE format floating-point[[36-bit pdp10 format for Interlisp-10]]The following type specifiers are sub-types of INTEGER for which theaccessing is much more efficient than for other random field sizes. - (MOD 65536) [or DOUBLEBYTE; or additionally, for Interlisp-D only,WORD or SMALLPOSP] for 16-bit non-negative integers.- (MOD 256) [or BYTE, or CHARACTER] for 8-bit non-negative integers.- (MOD 16) [or NIBBLE] for 4-bit non-negative integers.- (MOD 2), or BIT, for single-bit entries.[[In general, the CommonLisp type heirarchy isn't supported; thus onlythe explicit names above will work. However, for Interlisp-D, as of28-Sep-83, the type (MOD n) for any reasonable "n", is supported.]]INITIALELEMENT - Argument must be a quantity of the type specified by the ELEMENTTYPE argument, and is used to initalize all the entries of the array. Default is NIL for pointer type, and zero for numeric types.INITIALCONTENTS - If the array is zero-dimensional, the this specifies its contents;otherwise, it must be a sequence whose length is equal to the firstdimension, and each element thereof must be a nested structure for an array whose dimensions are the remaining dimensions, and so on.DISPLACEDTO- Argument will be an array whose linearized data segment will be shared with the one being "made"; see also the DISPLACEDOFFSET argument also. DISPLACEDINDEXOFFSET- When the data vector is being "shared", this specifies the offset from the origin of the data vector at which the new array will have its zero-origin.The implementational constraints, as specified by the symbolic constants ARRAY-RANK-LIMIT, ARRAY-DIMENSION-LIMIT, and ARRAY-TOTAL-SIZE-LIMIT are: Ranks up to 63 are supported; each individual dimension of an array is constrained only to be a FIXP; in Interlisp-D, the total storage for the data block of an array may not exceed (2^16-5)*2^5 bits, and since a pointer requires 32 bits, then an array may contain up to 2^16-5 pointer elements, or 2^18-20 byte elements; Interlisp/VAX and Interlisp-10 may have other constraints.[[The following limitations exist as of 28-Sep-83:(1) the :FILL-POINTER keyword argument is not implemented at all; (2) all arrays automatically have the :ADJUSTABLE property;(3) the "nested structures" used to specify the :INITIAL-CONTENTS may onlybe lists; ultimately, they could be lists, arrays, or whatever.(4) the symbolic constants ARRAY-RANK-LIMIT, ARRAY-DIMENSION-LIMIT, andARRAY-TOTAL-SIZE-LIMIT are not actually in the code. Just be awareof these limits by reading the documentation presented above.]]CMLARRAY.TTY 3-Oct-83 22:57:02Page 2 c8I aH `F ^$ [w LY X]C4V%UCD4S=4R)PH4O(MDKFJhE4H4GNEE9D4+BFAD?C L> ... {subscripts} ... )This returns the element of specified by the subscripts (which are all the remaining arguments after ), and each subscript must be a non-negative integer less than the corresponding array dimension.[The main primitive to change the contents of an array is called ASET (for"Array SET value of element"), modeled after the MIT Lisp Machine name.Ultimately, ASET will operate so as to translate into the same code thatSETF would have produced thus Interlisp users need not fear that such code won't run on a "by-the-book" CommonLisp implementation.(ASET ... {subscripts} ... )Changes the contents of the element of accessed by (AREF ... {subscripts} ... )to be .][[CommonLisp does not require separate names for the update functions; updating may always be specified by the SETF construct, which takes an access expression and a "new value" much the way Interlisp's CHANGE does.As of 28-Sep-83, there is no changetran entry for AREF, but it is expectedto be added someday.]]Informational Functions(ARRAYELEMENTTYPE )Returns a type specifier for the set of objects that can be stored in CMLARRAY.TTY 3-Oct-83 22:57:02Page 3 c8 LaA L`<^/ L]%[wDYDX]DV LUC, LS* R) P LOEMFKCJh7 GNJ EN D4I BJ AL ?J >D6?/ 3%D 1# .~$ L,G +dK )C &K %0G #H "K 7 L/ o; L$ U ;G G !I J  ` F LFh. "Et yA^f. This set may be larger than the set requested when was created; that is, (ARRAYELEMENTTYPE (MAKEARRAY 5 'ELEMENTTYPE '(MOD 8)))could be (MOD 8), or BYTE, or (MOD 256), etc., or even POINTER.[[as of 28-Sep-83, only the types enumerated above under MAKEARRAY are supported; there is no "coercion upwards" in order to find a type-specifier which could hold the elements of some non-enumerated type. Remember alsothat the Interlisp-D version supports (MOD n) for all integral n.]](ARRAYRANK )Returns the number of dimensions (axes) of ; to parallel theindexing range, this is a zero-origin number and thus will be a non-negative integer.(ARRAYDIMENSION )Returns the length of dimension number of [whichmay be any kind of array, i.e., any instance of the \CMLARRAY datatype]; should be a non-negative integer less than the rank of . (ARRAYDIMENSIONS )Returns a list whose elements are the dimensions of . [Thesecond argument, , is not a CommonLisp argument -- it is provided in Interlisp so that one may specify the NOCOPY option. Default action is to return a copy of the internal dimensions list.](ARRAYTOTALSIZE )Returns the total number of elements in , calculated as the productof all the dimensions. Roughly equivalent to (APPLY 'TIMES (ARRAYDIMENSIONS ))Note that the total size of a zero-dimensional array is 1. [The second argument, , is not a CommonLisp argument -- it is provided inInterlisp in order to find out how much space is actually occupied by thearray, including any gaps caused by the ALIGNMENT option.](ARRAYINBOUNDSP ... {subscripts} ... )This predicate checks whether the subscripts are all legal subscripts for and is true if they are; otherwise it is false. The subscripts must be integers. The number of subscripts supplied must equal the rank of the array. E.g., if HA is a three-dimensional array, then (ARRAYINBOUNDSP HA 4 25 62) makes the check such that (AREF HA 4 25 62) will not cause an illegal subscript error.(ARRAYROWMAJORINDEX ... {subscripts} ... )This function takes an array and valid subscripts for the array, andreturns a single non-negative integer less than the total size of the array that identifies the accessed element in the row-major ordering of the elements.The number of subscripts supplied must equal the rank of the arry. Eachsubscript must be a non-negative integer less than the corresponding arraydimension. For a one-dimensional array, the result of this function alwaysequals the supplied subscript. [However, if the ALIGNMENT option is used fora multi-dimensional array in Interlisp-D, then the maximum linearized index will exceed the value returned by ARRAYTOTALSIZE. In such a case, the valuereturned by (ARRAYTOTALSIZE T) will be the field size per elementtimes one plus the maximum linearized index. The quantity(fetch (CMLARRAY CMLIMAX) of )will always be this maximum linearized index.] CMLARRAY.TTY 3-Oct-83 22:57:02Page 4 c8I a L`6 ^? ]G [wL YI X]C UC LSC R)M P M& LKF JhH HN E& LD4C BN AK ?2 )Takes an array, and a list of dimensions just as with MAKEARRAY; thenumber of dimensions specified by must equal the rank of. Returns , whose components have been updated to conformto the new specifications (but if the new dimensions require more space inthe block data area, this will cause a copying into a newly allocated block,and will be DISPLACEDTO to this new block.)[[None of the keyword options mentioned in the CommonLisp manual are supportedas of 28-Sep-83.]]Extensions to the Interlisp CommonLisp Array FunctionsAlthough the following facilities aren't specified by the "Excelsior Edition",they may be quite useful in Interlisp-D systems programming:*) Filepkg com: CMLARRAYS is similar to the BITMAPS com -- namely(CMLARRAYS . . . )will save and restore the value of each global variable , assumingit holds a CMLARRAY.*) Additional ELEMENTTYPE values for MAKEARRAY:- XPOINTER is like POINTER, except that the entries aren't referencecounted for the garbage collector; beware, beware!- DISPLACEDTOBASE is like DISPLACEDTO except its value isjust a random pointer/address, rather than another CMLARRAY.This way, one can use the CommonLisp array functions to accessparts of Interlisp-D's memory such as the screen bitmap.- ALIGNMENT is for multi-dimensional arrays; each row may be required to begin a multiple of some integer, with nulls or zerosfilling any space between "rows". For example, it might be that a bitmap array must have the raster scans beginning on a wordboundary; since there are 16 bits/word, then an alignment of 16would be used.*) Functions Interfaceing to LISTPs:(LISTARRAY )The second and third arguments are optional, and have meaning similar to the corresponding arguments to SUBSTRING, but negative indiciesaren't allowed. Elements are selected from the in row-majororder, and CONS's up into a list.(FILLARRAY )Similar to LISTARRAY, except that the elements of the are stored into the corresponding parts of the . As a convenience,if isn't a LISTP, then it is converted into (LIST ); furthermore, if there aren't enough elements in to fill out therange specified by and , then the last element of is repeated until finished. Thus, for example, one could fill an array with a single value by a construct like (FILLARRAY SOMEARRAY (LIST THISVAL))*) "Fast" accessing functions:(PAREF ... {subscripts} ... )(NAREF ... {subscripts} ... )(LAREF ... {subscripts} ... )(16AREF ... {subscripts} ... )CMLARRAY.TTY 3-Oct-83 22:57:02Page 5\a# ^% L]D [wH YH X]J VM UC3 SN R)K6 HN GN< D4CB' LAH L? 3%81?0 A.~A,=+d@) &$%0+#F"B D!o2AUFB;FD!F< $  L `& L & L F& L&h. "Et yA^f(8AREF ... {subscripts} ... )(4AREF ... {subscripts} ... )(1AREF ... {subscripts} ... )These are essentially the same as AREF, but have a consequence that, forPAREF, must be a POINTER or T array; and correspondingly, forNAREF a FIXNUM array, for LAREF a FLONUM array, for 16AREF aDOUBLEBYTE or (MOD 65536) array, for 8AREF a BYTE or (MOD 256)array, for 4AREF a NIBBLE or (MOD 16) array, and for 1AREF a BIT or(MOD 2) array. Furthermore, when compiled, these functions will be compiled "open", with little or no error checking, realizing orders of magnitude speed-up over AREF; however, *** there is no certification as to what kind of valuewill be returned should the subscripts be "out of range". To aid indebugging, the run-time code actually toggles on the global variableAREFSissyFLG, and when the flg is non-NIL, will call the function AREF instead of the fast-but-unchecked "in-line" accessing.However, one may omit even these simple checks for "all out, no holds barred" code by prefixing a \ to these names (e.g. \PAREF ...)*) "Fast" setting functions:(PASET ... {subscripts} ... )(NASET ... {subscripts} ... )(LASET ... {subscripts} ... )(16ASET ... {subscripts} ... )(8ASET ... {subscripts} ... )(4ASET ... {subscripts} ... )(1ASET ... {subscripts} ... )These are essentially the same as ASET, but have a consequence that, forPASET, must be a POINTER or T array; and correspondingly, for NASET a FIXNUM array, for LAREF a FLONUM array, for 16ASET a DOUBLEBYTE or (MOD 65536) array, for 8ASET a BYTE or (MOD 256) array, for 4ASET a NIBBLE or (MOD 16) array, and for 1ASET a BIT or (MOD 2) array. Furthermore, when compiled, these functions will be compiled "open", with little or no error checking, realizing orders of magnitude speed-up overASET; although some checking is performed to insure memory systemintegrity (i.e. that the word modified will actually be within the datablock of the specified array), **** there is no certification as to which word will be clobbered should the subscripts be "out of range". Aswith AREF, the run-time code toggles on the global variable AREFSissyFLG,and will call the function ASET when the flg is non-NIL.However, one may omit even these simple checks for "all out, no holds barred" code by prefixing a \ to these names (e.g. \PASET ...). Ifyou use this option, there is no guarantee of memory integrity, andlikely no one will want to listen to reports of any "system" bugsencountered while such "unsafe" options were being exercised.CMLARRAY.TTY 3-Oct-83 22:57:02Page 6 Lc8& La& L`& L^I]E[w=Y>X]D$V LUCJSIR)FPEODMBK; LJhFH> E LD41 LB1 LA1 L?1 L>1 L