CHAPTER 2 Data Structure Access The following functions allow one to create and manipu- late the various types of lisp data structures. Refer to 1.2 for details of the data structures known to FRANZ LISP. 2.1. Lists The following functions exist for the creation and manipulating of lists. Lists are composed of a linked list of objects called either 'list cells', 'cons cells' or 'dtpr cells'. Lists are normally ter- minated with the special symbol nil. nil is both a symbol and a representation for the empty list (). 2.1.1. list creation (cons 'g_arg1 'g_arg2) RETURNS: a new list cell whose car is g_arg1 and whose cdr is g_arg2. (xcons 'g_arg1 'g_arg2) EQUIVALENT TO: (_c_o_n_s '_g__a_r_g_2 '_g__a_r_g_1) (ncons 'g_arg) EQUIVALENT TO: (_c_o_n_s '_g__a_r_g _n_i_l) (list ['g_arg1 ... ]) RETURNS: a list whose elements are the g_arg_i. 9 9Data Structure Access 2-1 Data Structure Access 2-2 (append 'l_arg1 'l_arg2) RETURNS: a list containing the elements of l_arg1 fol- lowed by l_arg2. NOTE: To generate the result, the top level list cells of l_arg1 are duplicated and the cdr of the last list cell is set to point to l_arg2. Thus this is an expensive operation if l_arg1 is large. See the descriptions of _n_c_o_n_c and _t_c_o_n_c for cheaper ways of doing the _a_p_p_e_n_d if the list l_arg1 can be altered. (append1 'l_arg1 'g_arg2) RETURNS: a list like l_arg1 with g_arg2 as the last element. NOTE: this is equivalent to (append 'l_arg1 (list 'g_arg2)). ____________________________________________________ ; A common mistake is using append to add one element to the end of a list -> (_a_p_p_e_n_d '(_a _b _c _d) '_e) (a b c d . e) ; The user intended to say: -> (_a_p_p_e_n_d '(_a _b _c _d) '(_e)) (_a _b _c _d _e) ; _b_e_t_t_e_r _i_s _a_p_p_e_n_d_1 -> (_a_p_p_e_n_d_1 '(_a _b _c _d) '_e) (_a _b _c _d _e) ____________________________________________________ (quote! [g_qform_i] ...[! 'g_eform_i] ... [!! 'l_form_i] ...) RETURNS: The list resulting from the splicing and insertion process described below. NOTE: _q_u_o_t_e! is the complement of the _l_i_s_t function. _l_i_s_t forms a list by evaluating each for in the argument list; evaluation is suppressed if the form is _q_u_o_t_eed. In _q_u_o_t_e!, each form is impli- citly _q_u_o_t_eed. To be evaluated, a form must be preceded by one of the evaluate operations ! and !!. ! g_eform evaluates g_form and the value is inserted in the place of the call; !! l_form evaluates l_form and the value is spliced into the place of the call. Printed: January 31, 1984 Data Structure Access 2-3 `Splicing in' means that the parentheses sur- rounding the list are removed as the example below shows. Use of the evaluate operators can occur at any level in a form argument. Another way to get the effect of the _q_u_o_t_e! func- tion is to use the backquote character macro (see 8.3.3). ____________________________________________________ (_q_u_o_t_e! _c_o_n_s ! (_c_o_n_s _1 _2) _3) = (_c_o_n_s (_1 . _2) _3) (_q_u_o_t_e! _1 !! (_l_i_s_t _2 _3 _4) _5) = (_1 _2 _3 _4 _5) (_s_e_t_q _q_u_o_t_e_d '_e_v_a_l_e_d)(_q_u_o_t_e! ! ((_I _a_m ! _q_u_o_t_e_d))) = ((_I _a_m _e_v_a_l_e_d)) (_q_u_o_t_e! _t_r_y ! '(_t_h_i_s ! _o_n_e)) = (_t_r_y (_t_h_i_s ! _o_n_e)) ____________________________________________________ (bignum-to-list 'b_arg) RETURNS: A list of the fixnums which are used to represent the bignum. NOTE: the inverse of this function is _l_i_s_t-_t_o-_b_i_g_n_u_m. (list-to-bignum 'l_ints) WHERE: l_ints is a list of fixnums. RETURNS: a bignum constructed of the given fixnums. NOTE: the inverse of this function is _b_i_g_n_u_m-_t_o-_l_i_s_t. 2.1.2. list predicates 9 9 Printed: January 31, 1984 Data Structure Access 2-4 (dtpr 'g_arg) RETURNS: t iff g_arg is a list cell. NOTE: that (dtpr '()) is nil. The name dtpr is a con- traction for ``dotted pair''. (listp 'g_arg) RETURNS: t iff g_arg is a list object or nil. (tailp 'l_x 'l_y) RETURNS: l_x, if a list cell _e_q to l_x is found by _c_d_ring down l_y zero or more times, nil other- wise. ____________________________________________________ -> (_s_e_t_q _x '(_a _b _c _d) _y (_c_d_d_r _x)) (c d) -> (_a_n_d (_d_t_p_r _x) (_l_i_s_t_p _x)) ; x and y are dtprs and lists t -> (_d_t_p_r '()) ; () is the same as nil and is not a dtpr nil -> (_l_i_s_t_p '()) ; however it is a list t -> (_t_a_i_l_p _y _x) (c d) ____________________________________________________ (length 'l_arg) RETURNS: the number of elements in the top level of list l_arg. 2.1.3. list accessing 9 9 Printed: January 31, 1984 Data Structure Access 2-5 (car 'l_arg) (cdr 'l_arg) RETURNS: _c_o_n_s cell. (_c_a_r (_c_o_n_s x y)) is always x, (_c_d_r (_c_o_n_s x y)) is always y. In FRANZ LISP, the cdr portion is located first in memory. This is hardly noticeable, and we mention it pri- marily as a curiosity. (c..r 'lh_arg) WHERE: the .. represents any positive number of a's and d's. RETURNS: the result of accessing the list structure in the way determined by the function name. The a's and d's are read from right to left, a d directing the access down the cdr part of the list cell and an a down the car part. NOTE: lh_arg may also be nil, and it is guaranteed that the car and cdr of nil is nil. If lh_arg is a hunk, then (_c_a_r '_l_h__a_r_g) is the same as (_c_x_r _1 '_l_h__a_r_g) and (_c_d_r '_l_h__a_r_g) is the same as (_c_x_r _0 '_l_h__a_r_g). It is generally hard to read and understand the context of functions with large strings of a's and d's, but these functions are supported by rapid accessing and open-compiling (see Chapter 12). (nth 'x_index 'l_list) RETURNS: the nth element of l_list, assuming zero-based index. Thus (nth 0 l_list) is the same as (car l_list). _n_t_h is both a function, and a compiler macro, so that more efficient code might be generated than for _n_t_h_e_l_e_m (described below). NOTE: If x_arg1 is non-positive or greater than the length of the list, nil is returned. 9 9 Printed: January 31, 1984 Data Structure Access 2-6 (nthcdr 'x_index 'l_list) RETURNS: the result of _c_d_ring down the list l_list x_index times. NOTE: If x_index is less than 0, then (_c_o_n_s _n_i_l '_l__l_i_s_t) is returned. (nthelem 'x_arg1 'l_arg2) RETURNS: The x_arg1'_s_t element of the list l_arg2. NOTE: This function comes from the PDP-11 Lisp system. (last 'l_arg) RETURNS: the last list cell in the list l_arg. EXAMPLE: _l_a_s_t does NOT return the last element of a list! (_l_a_s_t '(_a _b)) = (b) (ldiff 'l_x 'l_y) RETURNS: a list of all elements in l_x but not in l_y , i.e., the list difference of l_x and l_y. NOTE: l_y must be a tail of l_x, i.e., _e_q to the result of applying some number of _c_d_r's to l_x. Note that the value of _l_d_i_f_f is always new list structure unless l_y is nil, in which case (_l_d_i_f_f _l__x _n_i_l) is l_x itself. If l_y is not a tail of l_x, _l_d_i_f_f generates an error. EXAMPLE: (_l_d_i_f_f '_l__x (_m_e_m_b_e_r '_g__f_o_o '_l__x)) gives all elements in l_x up to the first g_foo. 2.1.4. list manipulation (rplaca 'lh_arg1 'g_arg2) RETURNS: the modified lh_arg1. SIDE EFFECT: the car of lh_arg1 is set to g_arg2. If lh_arg1 is a hunk then the second element of the hunk is set to g_arg2. 9 9 Printed: January 31, 1984 Data Structure Access 2-7 (rplacd 'lh_arg1 'g_arg2) RETURNS: the modified lh_arg1. SIDE EFFECT: the cdr of lh_arg2 is set to g_arg2. If lh_arg1 is a hunk then the first element of the hunk is set to g_arg2. (attach 'g_x 'l_l) RETURNS: l_l whose _c_a_r is now g_x, whose _c_a_d_r is the original (_c_a_r _l__l), and whose _c_d_d_r is the ori- ginal (_c_d_r _l__l). NOTE: what happens is that g_x is added to the begin- ning of list l_l yet maintaining the same list cell at the beginning of the list. (delete 'g_val 'l_list ['x_count]) RETURNS: the result of splicing g_val from the top level of l_list no more than x_count times. NOTE: x_count defaults to a very large number, thus if x_count is not given, all occurrences of g_val are removed from the top level of l_list. g_val is compared with successive _c_a_r's of l_list using the function _e_q_u_a_l. SIDE EFFECT: l_list is modified using rplacd, no new list cells are used. (delq 'g_val 'l_list ['x_count]) (dremove 'g_val 'l_list ['x_count]) RETURNS: the result of splicing g_val from the top level of l_list no more than x_count times. NOTE: _d_e_l_q (and _d_r_e_m_o_v_e) are the same as _d_e_l_e_t_e except that _e_q is used for comparison instead of _e_q_u_a_l. 9 9 Printed: January 31, 1984 Data Structure Access 2-8 ____________________________________________________ ; note that you should use the value returned by _d_e_l_e_t_e or _d_e_l_q ; and not assume that g_val will always show the deletions. ; For example -> (_s_e_t_q _t_e_s_t '(_a _b _c _a _d _e)) (a b c a d e) -> (_d_e_l_e_t_e '_a _t_e_s_t) (b c d e) ; the value returned is what we would expect -> _t_e_s_t (a b c d e) ; but test still has the first a in the list! ____________________________________________________ (remq 'g_x 'l_l ['x_count]) (remove 'g_x 'l_l) RETURNS: a _c_o_p_y of l_l with all top level elements _e_q_u_a_l to g_x removed. _r_e_m_q uses _e_q instead of _e_q_u_a_l for comparisons. NOTE: remove does not modify its arguments like _d_e_l_e_t_e, and _d_e_l_q do. (insert 'g_object 'l_list 'u_comparefn 'g_nodups) RETURNS: a list consisting of l_list with g_object des- tructively inserted in a place determined by the ordering function u_comparefn. NOTE: (_c_o_m_p_a_r_e_f_n '_g__x '_g__y) should return something non-nil if g_x can precede g_y in sorted order, nil if g_y must precede g_x. If u_comparefn is nil, alphabetical order will be used. If g_nodups is non-nil, an element will not be inserted if an equal element is already in the list. _i_n_s_e_r_t does binary search to determine where to insert the new element. 9 9 Printed: January 31, 1984 Data Structure Access 2-9 (merge 'l_data1 'l_data2 'u_comparefn) RETURNS: the merged list of the two input sorted lists l_data1 and l_data1 using binary comparison function u_comparefn. NOTE: (_c_o_m_p_a_r_e_f_n '_g__x '_g__y) should return something non-nil if g_x can precede g_y in sorted order, nil if g_y must precede g_x. If u_comparefn is nil, alphabetical order will be used. u_comparefn should be thought of as "less than or equal". _m_e_r_g_e changes both of its data argu- ments. (subst 'g_x 'g_y 'l_s) (dsubst 'g_x 'g_y 'l_s) RETURNS: the result of substituting g_x for all _e_q_u_a_l occurrences of g_y at all levels in l_s. NOTE: If g_y is a symbol, _e_q will be used for comparis- ons. The function _s_u_b_s_t does not modify l_s but the function _d_s_u_b_s_t (destructive substitution) does. (lsubst 'l_x 'g_y 'l_s) RETURNS: a copy of l_s with l_x spliced in for every occurrence of of g_y at all levels. Splicing in means that the parentheses surrounding the list l_x are removed as the example below shows. ____________________________________________________ -> (_s_u_b_s_t '(_a _b _c) '_x '(_x _y _z (_x _y _z) (_x _y _z))) ((a b c) y z ((a b c) y z) ((a b c) y z)) -> (_l_s_u_b_s_t '(_a _b _c) '_x '(_x _y _z (_x _y _z) (_x _y _z))) (a b c y z (a b c y z) (a b c y z)) ____________________________________________________ 9 9 Printed: January 31, 1984 Data Structure Access 2-10 (subpair 'l_old 'l_new 'l_expr) WHERE: there are the same number of elements in l_old as l_new. RETURNS: the list l_expr with all occurrences of a object in l_old replaced by the corresponding one in l_new. When a substitution is made, a copy of the value to substitute in is not made. EXAMPLE: (_s_u_b_p_a_i_r '(_a _c)' (_x _y) '(_a _b _c _d)) = (_x _b _y _d) (nconc 'l_arg1 'l_arg2 ['l_arg3 ...]) RETURNS: A list consisting of the elements of l_arg1 followed by the elements of l_arg2 followed by l_arg3 and so on. NOTE: The _c_d_r of the last list cell of l_arg_i is changed to point to l_arg_i+_1. ____________________________________________________ ; _n_c_o_n_c is faster than _a_p_p_e_n_d because it doesn't allocate new list cells. -> (_s_e_t_q _l_i_s_1 '(_a _b _c)) (a b c) -> (_s_e_t_q _l_i_s_2 '(_d _e _f)) (d e f) -> (_a_p_p_e_n_d _l_i_s_1 _l_i_s_2) (a b c d e f) -> _l_i_s_1 (a b c) ; note that lis1 has not been changed by _a_p_p_e_n_d -> (_n_c_o_n_c _l_i_s_1 _l_i_s_2) (a b c d e f) ; _n_c_o_n_c returns the same value as _a_p_p_e_n_d -> _l_i_s_1 (a b c d e f) ; but in doing so alters lis1 ____________________________________________________ 9 9 Printed: January 31, 1984 Data Structure Access 2-11 (reverse 'l_arg) (nreverse 'l_arg) RETURNS: the list l_arg with the elements at the top level in reverse order. NOTE: The function _n_r_e_v_e_r_s_e does the reversal in place, that is the list structure is modified. (nreconc 'l_arg 'g_arg) EQUIVALENT TO: (_n_c_o_n_c (_n_r_e_v_e_r_s_e '_l__a_r_g) '_g__a_r_g) 2.2. Predicates The following functions test for properties of data objects. When the result of the test is either 'false' or 'true', then nil will be returned for 'false' and something other than nil (often t) will be returned for 'true'. (arrayp 'g_arg) RETURNS: t iff g_arg is of type array. (atom 'g_arg) RETURNS: t iff g_arg is not a list or hunk object. NOTE: (_a_t_o_m '()) returns t. (bcdp 'g_arg) RETURNS: t iff g_arg is a data object of type binary. NOTE: This function is a throwback to the PDP-11 Lisp system. The name stands for binary code predi- cate. 9 9 Printed: January 31, 1984 Data Structure Access 2-12 (bigp 'g_arg) RETURNS: t iff g_arg is a bignum. (dtpr 'g_arg) RETURNS: t iff g_arg is a list cell. NOTE: that (dtpr '()) is nil. (hunkp 'g_arg) RETURNS: t iff g_arg is a hunk. (listp 'g_arg) RETURNS: t iff g_arg is a list object or nil. (stringp 'g_arg) RETURNS: t iff g_arg is a string. (symbolp 'g_arg) RETURNS: t iff g_arg is a symbol. (valuep 'g_arg) RETURNS: t iff g_arg is a value cell (vectorp 'v_vector) RETURNS: t iff the argument is a vector. (vectorip 'v_vector) RETURNS: t iff the argument is an immediate-vector. (type 'g_arg) (typep 'g_arg) RETURNS: a symbol whose pname describes the type of g_arg. 9 9 Printed: January 31, 1984 Data Structure Access 2-13 (signp s_test 'g_val) RETURNS: t iff g_val is a number and the given test s_test on g_val returns true. NOTE: The fact that _s_i_g_n_p simply returns nil if g_val is not a number is probably the most important reason that _s_i_g_n_p is used. The permitted values for s_test and what they mean are given in this table. 8 ____________________ s_test tested 8 ________________________________________ l g_val < 0 le g_val <_ 0 e g_val = 0 n g_val =/ 0 ge g_val >_ 0 g g_val > 0 8 ____________________ 7 |7|7|7|7|7|7|7|7| |7|7|7|7|7|7|7|7| (eq 'g_arg1 'g_arg2) RETURNS: t if g_arg1 and g_arg2 are the exact same lisp object. NOTE: _E_q simply tests if g_arg1 and g_arg2 are located in the exact same place in memory. Lisp objects which print the same are not necessarily _e_q. The only objects guaranteed to be _e_q are interned symbols with the same print name. [Unless a sym- bol is created in a special way (such as with _u_c_o_n_c_a_t or _m_a_k_n_a_m) it will be interned.] (neq 'g_x 'g_y) RETURNS: t if g_x is not _e_q to g_y, otherwise nil. (equal 'g_arg1 'g_arg2) (eqstr 'g_arg1 'g_arg2) RETURNS: t iff g_arg1 and g_arg2 have the same struc- ture as described below. NOTE: g_arg and g_arg2 are _e_q_u_a_l if (1) they are _e_q. (2) they are both fixnums with the same value 9 Printed: January 31, 1984 Data Structure Access 2-14 (3) they are both flonums with the same value (4) they are both bignums with the same value (5) they are both strings and are identical. (6) they are both lists and their cars and cdrs are _e_q_u_a_l. ____________________________________________________ ; _e_q is much faster than _e_q_u_a_l, especially in compiled code, ; however you cannot use _e_q to test for equality of numbers outside ; of the range -1024 to 1023. _e_q_u_a_l will always work. -> (_e_q _1_0_2_3 _1_0_2_3) t -> (_e_q _1_0_2_4 _1_0_2_4) nil -> (_e_q_u_a_l _1_0_2_4 _1_0_2_4) t ____________________________________________________ (not 'g_arg) (null 'g_arg) RETURNS: t iff g_arg is nil. (member 'g_arg1 'l_arg2) (memq 'g_arg1 'l_arg2) RETURNS: that part of the l_arg2 beginning with the first occurrence of g_arg1. If g_arg1 is not in the top level of l_arg2, nil is returned. NOTE: _m_e_m_b_e_r tests for equality with _e_q_u_a_l, _m_e_m_q tests for equality with _e_q. 2.3. Symbols and Strings In many of the following functions the distinc- tion between symbols and strings is somewhat blurred. To remind ourselves of the difference, a string is a null terminated sequence of characters, stored as com- pactly as possible. Strings are used as constants in Printed: January 31, 1984 Data Structure Access 2-15 FRANZ LISP. They _e_v_a_l to themselves. A symbol has additional structure: a value, property list, function binding, as well as its external representation (or print-name). If a symbol is given to one of the string manipulation functions below, its print name will be used as the string. Another popular way to represent strings in Lisp is as a list of fixnums which represent characters. The suffix 'n' to a string manipulation function indi- cates that it returns a string in this form. 2.3.1. symbol and string creation (concat ['stn_arg1 ... ]) (uconcat ['stn_arg1 ... ]) RETURNS: a symbol whose print name is the result of concatenating the print names, string charac- ters or numerical representations of the sn_arg_i. NOTE: If no arguments are given, a symbol with a null pname is returned. _c_o_n_c_a_t places the symbol created on the oblist, the function _u_c_o_n_c_a_t does the same thing but does not place the new symbol on the oblist. EXAMPLE: (_c_o_n_c_a_t '_a_b_c (_a_d_d _3 _4) "_d_e_f") = abc7def (concatl 'l_arg) EQUIVALENT TO: (_a_p_p_l_y '_c_o_n_c_a_t '_l__a_r_g) (implode 'l_arg) (maknam 'l_arg) WHERE: l_arg is a list of symbols, strings and small fixnums. RETURNS: The symbol whose print name is the result of concatenating the first characters of the print names of the symbols and strings in the list. Any fixnums are converted to the equivalent ascii character. In order to con- catenate entire strings or print names, use the function _c_o_n_c_a_t. NOTE: _i_m_p_l_o_d_e interns the symbol it creates, _m_a_k_n_a_m does not. Printed: January 31, 1984 Data Structure Access 2-16 (gensym ['s_leader]) RETURNS: a new uninterned atom beginning with the first character of s_leader's pname, or beginning with g if s_leader is not given. NOTE: The symbol looks like x0nnnnn where x is s_leader's first character and nnnnn is the number of times you have called gensym. (copysymbol 's_arg 'g_pred) RETURNS: an uninterned symbol with the same print name as s_arg. If g_pred is non nil, then the value, function binding and property list of the new symbol are made _e_q to those of s_arg. (ascii 'x_charnum) WHERE: x_charnum is between 0 and 255. RETURNS: a symbol whose print name is the single char- acter whose fixnum representation is x_charnum. (intern 's_arg) RETURNS: s_arg SIDE EFFECT: s_arg is put on the oblist if it is not already there. (remob 's_symbol) RETURNS: s_symbol SIDE EFFECT: s_symbol is removed from the oblist. (rematom 's_arg) RETURNS: t if s_arg is indeed an atom. SIDE EFFECT: s_arg is put on the free atoms list, effectively reclaiming an atom cell. NOTE: This function does _n_o_t check to see if s_arg is on the oblist or is referenced anywhere. Thus calling _r_e_m_a_t_o_m on an atom in the oblist may result in disaster when that atom cell is reused! 9 9 Printed: January 31, 1984 Data Structure Access 2-17 2.3.2. string and symbol predicates (boundp 's_name) RETURNS: nil if s_name is unbound: that is, it has never been given a value. If x_name has the value g_val, then (nil . g_val) is returned. See also _m_a_k_u_n_b_o_u_n_d. (alphalessp 'st_arg1 'st_arg2) RETURNS: t iff the `name' of st_arg1 is alphabetically less than the name of st_arg2. If st_arg is a symbol then its `name' is its print name. If st_arg is a string, then its `name' is the string itself. 2.3.3. symbol and string accessing (symeval 's_arg) RETURNS: the value of symbol s_arg. NOTE: It is illegal to ask for the value of an unbound symbol. This function has the same effect as _e_v_a_l, but compiles into much more efficient code. (get_pname 's_arg) RETURNS: the string which is the print name of s_arg. (plist 's_arg) RETURNS: the property list of s_arg. (getd 's_arg) RETURNS: the function definition of s_arg or nil if there is no function definition. NOTE: the function definition may turn out to be an array header. 9 9 Printed: January 31, 1984 Data Structure Access 2-18 (getchar 's_arg 'x_index) (nthchar 's_arg 'x_index) (getcharn 's_arg 'x_index) RETURNS: the x_index_t_h character of the print name of s_arg or nil if x_index is less than 1 or greater than the length of s_arg's print name. NOTE: _g_e_t_c_h_a_r and _n_t_h_c_h_a_r return a symbol with a single character print name, _g_e_t_c_h_a_r_n returns the fixnum representation of the character. (substring 'st_string 'x_index ['x_length]) (substringn 'st_string 'x_index ['x_length]) RETURNS: a string of length at most x_length starting at x_index_t_h character in the string. NOTE: If x_length is not given, all of the characters for x_index to the end of the string are returned. If x_index is negative the string begins at the x_index_t_h character from the end. If x_index is out of bounds, nil is returned. NOTE: _s_u_b_s_t_r_i_n_g returns a list of symbols, _s_u_b_s_t_r_i_n_g_n returns a list of fixnums. If _s_u_b_s_t_r_i_n_g_n is given a 0 x_length argument then a single fixnum which is the x_index_t_h character is returned. 2.3.4. symbol and string manipulation (set 's_arg1 'g_arg2) RETURNS: g_arg2. SIDE EFFECT: the value of s_arg1 is set to g_arg2. (setq s_atm1 'g_val1 [ s_atm2 'g_val2 ... ... ]) WHERE: the arguments are pairs of atom names and expressions. RETURNS: the last g_val_i. SIDE EFFECT: each s_atm_i is set to have the value g_val_i. NOTE: _s_e_t evaluates all of its arguments, _s_e_t_q does not evaluate the s_atm_i. 9 9 Printed: January 31, 1984 Data Structure Access 2-19 (desetq sl_pattern1 'g_exp1 [... ...]) RETURNS: g_expn SIDE EFFECT: This acts just like _s_e_t_q if all the sl_pattern_i are symbols. If sl_pattern_i is a list then it is a template which should have the same structure as g_exp_i The symbols in sl_pattern are assigned to the corresponding parts of g_exp. (See also _s_e_t_f ) EXAMPLE: (_d_e_s_e_t_q (_a _b (_c . _d)) '(_1 _2 (_3 _4 _5))) sets a to 1, b to 2, c to 3, and d to (4 5). (setplist 's_atm 'l_plist) RETURNS: l_plist. SIDE EFFECT: the property list of s_atm is set to l_plist. (makunbound 's_arg) RETURNS: s_arg SIDE EFFECT: the value of s_arg is made `unbound'. If the interpreter attempts to evaluate s_arg before it is again given a value, an unbound variable error will occur. (aexplode 's_arg) (explode 'g_arg) (aexplodec 's_arg) (explodec 'g_arg) (aexploden 's_arg) (exploden 'g_arg) RETURNS: a list of the characters used to print out s_arg or g_arg. NOTE: The functions beginning with 'a' are internal functions which are limited to symbol arguments. The functions _a_e_x_p_l_o_d_e and _e_x_p_l_o_d_e return a list of characters which _p_r_i_n_t would use to print the argument. These characters include all necessary escape characters. Functions _a_e_x_p_l_o_d_e_c and _e_x_p_l_o_d_e_c return a list of characters which _p_a_t_o_m would use to print the argument (i.e. no escape characters). Functions _a_e_x_p_l_o_d_e_n and _e_x_p_l_o_d_e_n are similar to _a_e_x_p_l_o_d_e_c and _e_x_p_l_o_d_e_c except that a list of fixnum equivalents of characters are Printed: January 31, 1984 Data Structure Access 2-20 returned. ____________________________________________________ -> (_s_e_t_q _x '|_q_u_o_t_e _t_h_i_s _\| _o_k?|) |quote this \| ok?| -> (_e_x_p_l_o_d_e _x) (q u o t e |\\| | | t h i s |\\| | | |\\| |\|| |\\| | | o k ?) ; note that |\\| just means the single character: backslash. ; and |\|| just means the single character: vertical bar ; and | | means the single character: space -> (_e_x_p_l_o_d_e_c _x) (q u o t e | | t h i s | | |\|| | | o k ?) -> (_e_x_p_l_o_d_e_n _x) (113 117 111 116 101 32 116 104 105 115 32 124 32 111 107 63) ____________________________________________________ 2.4. Vectors See Chapter 9 for a discussion of vectors. They are less efficient that hunks but more efficient than arrays. 2.4.1. vector creation (new-vector 'x_size ['g_fill ['g_prop]]) RETURNS: A vector of length x_size. Each data entry is initialized to g_fill, or to nil, if the argu- ment g_fill is not present. The vector's pro- perty is set to g_prop, or to nil, by default. (new-vectori-byte 'x_size ['g_fill ['g_prop]]) (new-vectori-word 'x_size ['g_fill ['g_prop]]) (new-vectori-long 'x_size ['g_fill ['g_prop]]) RETURNS: A vectori with x_size elements in it. The actual memory requirement is two long words + x_size*(n bytes), where n is 1 for new- vector-byte, 2 for new-vector-word, or 4 for new-vectori-long. Each data entry is initial- ized to g_fill, or to zero, if the argument g_fill is not present. The vector's property is set to g_prop, or nil, by default. Printed: January 31, 1984 Data Structure Access 2-21 Vectors may be created by specifying multiple initial values: (vector ['g_val0 'g_val1 ...]) RETURNS: a vector, with as many data elements as there are arguments. It is quite possible to have a vector with no data elements. The vector's property will be a null list. (vectori-byte ['x_val0 'x_val2 ...]) (vectori-word ['x_val0 'x_val2 ...]) (vectori-long ['x_val0 'x_val2 ...]) RETURNS: a vectori, with as many data elements as there are arguments. The arguments are required to be fixnums. Only the low order byte or word is used in the case of vectori-byte and vectori-word. The vector's property will be null. 2.4.2. vector reference (vref 'v_vect 'x_index) (vrefi-byte 'V_vect 'x_bindex) (vrefi-word 'V_vect 'x_windex) (vrefi-long 'V_vect 'x_lindex) RETURNS: the desired data element from a vector. The indices must be fixnums. Indexing is zero- based. The vrefi functions sign extend the data. (vprop 'Vv_vect) RETURNS: The Lisp property associated with a vector. (vget 'Vv_vect 'g_ind) RETURNS: The value stored under g_ind if the Lisp pro- perty associated with 'Vv_vect is a disembo- died property list. 9 9 Printed: January 31, 1984 Data Structure Access 2-22 (vsize 'Vv_vect) (vsize-byte 'V_vect) (vsize-word 'V_vect) RETURNS: the number of data elements in the vector. For immediate-vectors, the functions vsize- byte and vsize-word return the number of data elements, if one thinks of the binary data as being comprised of bytes or words. 2.4.3. vector modfication (vset 'v_vect 'x_index 'g_val) (vseti-byte 'V_vect 'x_bindex 'x_val) (vseti-word 'V_vect 'x_windex 'x_val) (vseti-long 'V_vect 'x_lindex 'x_val) RETURNS: the datum. SIDE EFFECT: The indexed element of the vector is set to the value. As noted above, for vseti- word and vseti-byte, the index is con- strued as the number of the data element within the vector. It is not a byte address. Also, for those two functions, the low order byte or word of x_val is what is stored. (vsetprop 'Vv_vect 'g_value) RETURNS: g_value. This should be either a symbol or a disembodied property list whose _c_a_r is a sym- bol identifying the type of the vector. SIDE EFFECT: the property list of Vv_vect is set to g_value. (vputprop 'Vv_vect 'g_value 'g_ind) RETURNS: g_value. SIDE EFFECT: If the vector property of Vv_vect is a disembodied property list, then vputprop adds the value g_value under the indicator g_ind. Otherwise, the old vector property is made the first element of the list. 9 9 Printed: January 31, 1984 Data Structure Access 2-23 2.5. Arrays See Chapter 9 for a complete description of arrays. Some of these functions are part of a Maclisp array compatibility package representing only one sim- ple way of using the array structure of FRANZ LISP. 2.5.1. array creation (marray 'g_data 's_access 'g_aux 'x_length 'x_delta) RETURNS: an array type with the fields set up from the above arguments in the obvious way (see 1.2.10). (*array 's_name 's_type 'x_dim1 ... 'x_dim_n) (array s_name s_type x_dim1 ... x_dim_n) WHERE: s_type may be one of t, nil, fixnum, flonum, fixnum-block and flonum-block. RETURNS: an array of type s_type with n dimensions of extents given by the x_dim_i. SIDE EFFECT: If s_name is non nil, the function defini- tion of s_name is set to the array struc- ture returned. NOTE: These functions create a Maclisp compatible array. In FRANZ LISP arrays of type t, nil, fix- num and flonum are equivalent and the elements of these arrays can be any type of lisp object. Fixnum-block and flonum-block arrays are res- tricted to fixnums and flonums respectively and are used mainly to communicate with foreign func- tions (see 8.5). NOTE: *_a_r_r_a_y evaluates its arguments, _a_r_r_a_y does not. 2.5.2. array predicate 9 9 Printed: January 31, 1984 Data Structure Access 2-24 (arrayp 'g_arg) RETURNS: t iff g_arg is of type array. 2.5.3. array accessors (getaccess 'a_array) (getaux 'a_array) (getdelta 'a_array) (getdata 'a_array) (getlength 'a_array) RETURNS: the field of the array object a_array given by the function name. (arrayref 'a_name 'x_ind) RETURNS: the x_ind_t_h element of the array object a_name. x_ind of zero accesses the first ele- ment. NOTE: _a_r_r_a_y_r_e_f uses the data, length and delta fields of a_name to determine which object to return. (arraycall s_type 'as_array 'x_ind1 ... ) RETURNS: the element selected by the indices from the array a_array of type s_type. NOTE: If as_array is a symbol then the function binding of this symbol should contain an array object. s_type is ignored by _a_r_r_a_y_c_a_l_l but is included for compatibility with Maclisp. (arraydims 's_name) RETURNS: a list of the type and bounds of the array s_name. 9 9 Printed: January 31, 1984 Data Structure Access 2-25 (listarray 'sa_array ['x_elements]) RETURNS: a list of all of the elements in array sa_array. If x_elements is given, then only the first x_elements are returned. ____________________________________________________ ; We will create a 3 by 4 array of general lisp objects -> (_a_r_r_a_y _e_r_n_i_e _t _3 _4) array[12] ; the array header is stored in the function definition slot of the ; symbol ernie -> (_a_r_r_a_y_p (_g_e_t_d '_e_r_n_i_e)) t -> (_a_r_r_a_y_d_i_m_s (_g_e_t_d '_e_r_n_i_e)) (t 3 4) ; store in ernie[2][2] the list (test list) -> (_s_t_o_r_e (_e_r_n_i_e _2 _2) '(_t_e_s_t _l_i_s_t)) (test list) ; check to see if it is there -> (_e_r_n_i_e _2 _2) (test list) ; now use the low level function _a_r_r_a_y_r_e_f to find the same element ; arrays are 0 based and row-major (the last subscript varies the fastest) ; thus element [2][2] is the 10th element , (starting at 0). -> (_a_r_r_a_y_r_e_f (_g_e_t_d '_e_r_n_i_e) _1_0) (ptr to)(test list) ; the result is a value cell (thus the (ptr to)) ____________________________________________________ 2.5.4. array manipulation 9 9 Printed: January 31, 1984 Data Structure Access 2-26 (putaccess 'a_array 'su_func) (putaux 'a_array 'g_aux) (putdata 'a_array 'g_arg) (putdelta 'a_array 'x_delta) (putlength 'a_array 'x_length) RETURNS: the second argument to the function. SIDE EFFECT: The field of the array object given by the function name is replaced by the second argument to the function. (store 'l_arexp 'g_val) WHERE: l_arexp is an expression which references an array element. RETURNS: g_val SIDE EFFECT: the array location which contains the ele- ment which l_arexp references is changed to contain g_val. (fillarray 's_array 'l_itms) RETURNS: s_array SIDE EFFECT: the array s_array is filled with elements from l_itms. If there are not enough ele- ments in l_itms to fill the entire array, then the last element of l_itms is used to fill the remaining parts of the array. 2.6. Hunks Hunks are vector-like objects whose size can range from 1 to 128 elements. Internally, hunks are allocated in sizes which are powers of 2. In order to create hunks of a given size, a hunk with at least that many elements is allocated and a distinguished symbol EMPTY is placed in those elements not requested. Most hunk functions respect those dis- tinguished symbols, but there are two (*_m_a_k_h_u_n_k and *_r_p_l_a_c_x) which will overwrite the distinguished sym- bol. 9 9 Printed: January 31, 1984 Data Structure Access 2-27 2.6.1. hunk creation (hunk 'g_val1 ['g_val2 ... 'g_val_n]) RETURNS: a hunk of length n whose elements are initial- ized to the g_val_i. NOTE: the maximum size of a hunk is 128. EXAMPLE: (_h_u_n_k _4 '_s_h_a_r_p '_k_e_y_s) = {4 sharp keys} (makhunk 'xl_arg) RETURNS: a hunk of length xl_arg initialized to all nils if xl_arg is a fixnum. If xl_arg is a list, then we return a hunk of size (_l_e_n_g_t_h '_x_l__a_r_g) initialized to the elements in xl_arg. NOTE: (_m_a_k_h_u_n_k '(_a _b _c)) is equivalent to (_h_u_n_k '_a '_b '_c). EXAMPLE: (_m_a_k_h_u_n_k _4) = {_n_i_l _n_i_l _n_i_l _n_i_l} (*makhunk 'x_arg) RETURNS: a hunk of size 2[x_arg] initialized to EMPTY. NOTE: This is only to be used by such functions as _h_u_n_k and _m_a_k_h_u_n_k which create and initialize hunks for users. 2.6.2. hunk accessor (cxr 'x_ind 'h_hunk) RETURNS: element x_ind (starting at 0) of hunk h_hunk. (hunk-to-list 'h_hunk) RETURNS: a list consisting of the elements of h_hunk. 2.6.3. hunk manipulators 9 9 Printed: January 31, 1984 Data Structure Access 2-28 (rplacx 'x_ind 'h_hunk 'g_val) (*rplacx 'x_ind 'h_hunk 'g_val) RETURNS: h_hunk SIDE EFFECT: Element x_ind (starting at 0) of h_hunk is set to g_val. NOTE: _r_p_l_a_c_x will not modify one of the distinguished (EMPTY) elements whereas *_r_p_l_a_c_x will. (hunksize 'h_arg) RETURNS: the size of the hunk h_arg. EXAMPLE: (_h_u_n_k_s_i_z_e (_h_u_n_k _1 _2 _3)) = 3 2.7. Bcds A bcd object contains a pointer to compiled code and to the type of function object the compiled code represents. (getdisc 'y_bcd) (getentry 'y_bcd) RETURNS: the field of the bcd object given by the func- tion name. (putdisc 'y_func 's_discipline) RETURNS: s_discipline SIDE EFFECT: Sets the discipline field of y_func to s_discipline. 2.8. Structures There are three common structures constructed out of list cells: the assoc list, the property list and the tconc list. The functions below manipulate these structures. 2.8.1. assoc list An `assoc list' (or alist) is a common lisp data structure. It has the form Printed: January 31, 1984 Data Structure Access 2-29 ((key1 . value1) (key2 . value2) (key3 . value3) ... (keyn . valuen)) (assoc 'g_arg1 'l_arg2) (assq 'g_arg1 'l_arg2) RETURNS: the first top level element of l_arg2 whose _c_a_r is _e_q_u_a_l (with _a_s_s_o_c) or _e_q (with _a_s_s_q) to g_arg1. NOTE: Usually l_arg2 has an _a-_l_i_s_t structure and g_arg1 acts as key. (sassoc 'g_arg1 'l_arg2 'sl_func) RETURNS: the result of (_c_o_n_d ((_a_s_s_o_c '_g__a_r_g '_l__a_r_g_2) (_a_p_p_l_y '_s_l__f_u_n_c _n_i_l))) NOTE: sassoc is written as a macro. (sassq 'g_arg1 'l_arg2 'sl_func) RETURNS: the result of (_c_o_n_d ((_a_s_s_q '_g__a_r_g '_l__a_r_g_2) (_a_p_p_l_y '_s_l__f_u_n_c _n_i_l))) NOTE: sassq is written as a macro. ____________________________________________________ ; _a_s_s_o_c or _a_s_s_q is given a key and an assoc list and returns ; the key and value item if it exists, they differ only in how they test ; for equality of the keys. -> (_s_e_t_q _a_l_i_s_t '((_a_l_p_h_a . _a) ( (_c_o_m_p_l_e_x _k_e_y) . _b) (_j_u_n_k . _x))) ((alpha . a) ((complex key) . b) (junk . x)) ; we should use _a_s_s_q when the key is an atom -> (_a_s_s_q '_a_l_p_h_a _a_l_i_s_t) (alpha . a) ; but it may not work when the key is a list -> (_a_s_s_q '(_c_o_m_p_l_e_x _k_e_y) _a_l_i_s_t) nil ; however _a_s_s_o_c will always work -> (_a_s_s_o_c '(_c_o_m_p_l_e_x _k_e_y) _a_l_i_s_t) ((complex key) . b) ____________________________________________________ 9 9 Printed: January 31, 1984 Data Structure Access 2-30 (sublis 'l_alst 'l_exp) WHERE: l_alst is an _a-_l_i_s_t. RETURNS: the list l_exp with every occurrence of key_i replaced by val_i. NOTE: new list structure is returned to prevent modifi- cation of l_exp. When a substitution is made, a copy of the value to substitute in is not made. 2.8.2. property list A property list consists of an alternating sequence of keys and values. Normally a property list is stored on a symbol. A list is a 'disembo- died' property list if it contains an odd number of elements, the first of which is ignored. (plist 's_name) RETURNS: the property list of s_name. (setplist 's_atm 'l_plist) RETURNS: l_plist. SIDE EFFECT: the property list of s_atm is set to l_plist. (get 'ls_name 'g_ind) RETURNS: the value under indicator g_ind in ls_name's property list if ls_name is a symbol. NOTE: If there is no indicator g_ind in ls_name's pro- perty list nil is returned. If ls_name is a list of an odd number of elements then it is a disem- bodied property list. _g_e_t searches a disembodied property list by starting at its _c_d_r, and compar- ing every other element with g_ind, using _e_q. 9 9 Printed: January 31, 1984 Data Structure Access 2-31 (getl 'ls_name 'l_indicators) RETURNS: the property list ls_name beginning at the first indicator which is a member of the list l_indicators, or nil if none of the indicators in l_indicators are on ls_name's property list. NOTE: If ls_name is a list, then it is assumed to be a disembodied property list. (putprop 'ls_name 'g_val 'g_ind) (defprop ls_name g_val g_ind) RETURNS: g_val. SIDE EFFECT: Adds to the property list of ls_name the value g_val under the indicator g_ind. NOTE: _p_u_t_p_r_o_p evaluates it arguments, _d_e_f_p_r_o_p does not. ls_name may be a disembodied property list, see _g_e_t. (remprop 'ls_name 'g_ind) RETURNS: the portion of ls_name's property list begin- ning with the property under the indicator g_ind. If there is no g_ind indicator in ls_name's plist, nil is returned. SIDE EFFECT: the value under indicator g_ind and g_ind itself is removed from the property list of ls_name. NOTE: ls_name may be a disembodied property list, see _g_e_t. 9 9 Printed: January 31, 1984 Data Structure Access 2-32 ____________________________________________________ -> (_p_u_t_p_r_o_p '_x_l_a_t_e '_a '_a_l_p_h_a) a -> (_p_u_t_p_r_o_p '_x_l_a_t_e '_b '_b_e_t_a) b -> (_p_l_i_s_t '_x_l_a_t_e) (alpha a beta b) -> (_g_e_t '_x_l_a_t_e '_a_l_p_h_a) a ; use of a disembodied property list: -> (_g_e_t '(_n_i_l _f_a_t_e_m_a_n _r_j_f _s_k_l_o_w_e_r _k_l_s _f_o_d_e_r_a_r_o _j_k_f) '_s_k_l_o_w_e_r) kls ____________________________________________________ 2.8.3. tconc structure A tconc structure is a special type of list designed to make it easy to add objects to the end. It consists of a list cell whose _c_a_r points to a list of the elements added with _t_c_o_n_c or _l_c_o_n_c and whose _c_d_r points to the last list cell of the list pointed to by the _c_a_r. (tconc 'l_ptr 'g_x) WHERE: l_ptr is a tconc structure. RETURNS: l_ptr with g_x added to the end. (lconc 'l_ptr 'l_x) WHERE: l_ptr is a tconc structure. RETURNS: l_ptr with the list l_x spliced in at the end. 9 9 Printed: January 31, 1984 Data Structure Access 2-33 ____________________________________________________ ; A _t_c_o_n_c structure can be initialized in two ways. ; nil can be given to _t_c_o_n_c in which case _t_c_o_n_c will generate ; a _t_c_o_n_c structure. ->(_s_e_t_q _f_o_o (_t_c_o_n_c _n_i_l _1)) ((1) 1) ; Since _t_c_o_n_c destructively adds to ; the list, you can now add to foo without using _s_e_t_q again. ->(_t_c_o_n_c _f_o_o _2) ((1 2) 2) ->_f_o_o ((1 2) 2) ; Another way to create a null _t_c_o_n_c structure ; is to use (_n_c_o_n_s _n_i_l). ->(_s_e_t_q _f_o_o (_n_c_o_n_s _n_i_l)) (nil) ->(_t_c_o_n_c _f_o_o _1) ((1) 1) ; now see what _l_c_o_n_c can do -> (_l_c_o_n_c _f_o_o _n_i_l) ((1) 1) ; no change -> (_l_c_o_n_c _f_o_o '(_2 _3 _4)) ((1 2 3 4) 4) ____________________________________________________ 2.8.4. fclosures An fclosure is a functional object which admits some data manipulations. They are discussed in 8.4. Internally, they are constructed from vec- tors. 9 9 Printed: January 31, 1984 Data Structure Access 2-34 (fclosure 'l_vars 'g_funobj) WHERE: l_vars is a list of variables, g_funobj is any object that can be funcalled (including, fclo- sures). RETURNS: A vector which is the fclosure. (fclosure-alist 'v_fclosure) RETURNS: An association list representing the variables in the fclosure. This is a snapshot of the current state of the fclosure. If the bind- ings in the fclosure are changed, any previ- ously calculated results of _f_c_l_o_s_u_r_e-_a_l_i_s_t will not change. (fclosure-function 'v_fclosure) RETURNS: the functional object part of the fclosure. (fclosurep 'v_fclosure) RETURNS: t iff the argument is an fclosure. (symeval-in-fclosure 'v_fclosure 's_symbol) RETURNS: the current binding of a particular symbol in an fclosure. (set-in-fclosure 'v_fclosure 's_symbol 'g_newvalue) RETURNS: g_newvalue. SIDE EFFECT: The variable s_symbol is bound in the fclosure to g_newvalue. 2.9. Random functions The following functions don't fall into any of the classifications above. 9 9 Printed: January 31, 1984 Data Structure Access 2-35 (bcdad 's_funcname) RETURNS: a fixnum which is the address in memory where the function s_funcname begins. If s_funcname is not a machine coded function (binary) then _b_c_d_a_d returns nil. (copy 'g_arg) RETURNS: A structure _e_q_u_a_l to g_arg but with new list cells. (copyint* 'x_arg) RETURNS: a fixnum with the same value as x_arg but in a freshly allocated cell. (cpy1 'xvt_arg) RETURNS: a new cell of the same type as xvt_arg with the same value as xvt_arg. (getaddress 's_entry1 's_binder1 'st_discipline1 [... ... ...]) RETURNS: the binary object which s_binder1's function field is set to. NOTE: This looks in the running lisp's symbol table for a symbol with the same name as s_entry_i. It then creates a binary object whose entry field points to s_entry_i and whose discipline is st_discipline_i. This binary object is stored in the function field of s_binder_i. If st_discipline_i is nil, then "subroutine" is used by default. This is especially useful for _c_f_a_s_l users. (macroexpand 'g_form) RETURNS: g_form after all macros in it are expanded. NOTE: This function will only macroexpand expressions which could be evaluated and it does not know about the special nlambdas such as _c_o_n_d and _d_o, thus it misses many macro expansions. 9 9 Printed: January 31, 1984 Data Structure Access 2-36 (ptr 'g_arg) RETURNS: a value cell initialized to point to g_arg. (quote g_arg) RETURNS: g_arg. NOTE: the reader allows you to abbreviate (quote foo) as 'foo. (kwote 'g_arg) RETURNS: (_l_i_s_t (_q_u_o_t_e _q_u_o_t_e) _g__a_r_g). (replace 'g_arg1 'g_arg2) WHERE: g_arg1 and g_arg2 must be the same type of lispval and not symbols or hunks. RETURNS: g_arg2. SIDE EFFECT: The effect of _r_e_p_l_a_c_e is dependent on the type of the g_arg_i although one will notice a similarity in the effects. To understand what _r_e_p_l_a_c_e does to fixnum and flonum arguments, you must first under- stand that such numbers are `boxed' in FRANZ LISP. What this means is that if the symbol x has a value 32412, then in memory the value element of x's symbol structure contains the address of another word of memory (called a box) with 32412 in it. Thus, there are two ways of changing the value of x: the first is to change the value element of x's symbol structure to point to a word of memory with a different value. The second way is to change the value in the box which x points to. The former method is used almost all of the time, the latter is used very rarely and has the potential to cause great confu- sion. The function _r_e_p_l_a_c_e allows you to do the latter, i.e., to actually change the value in the box. You should watch out for these situations. If you do (_s_e_t_q _y _x), then both x and y will point to the same box. If you now (_r_e_p_l_a_c_e _x _1_2_3_4_5), then y will also have the value 12345. And, in fact, there may Printed: January 31, 1984 Data Structure Access 2-37 be many other pointers to that box. Another problem with replacing fixnums is that some boxes are read-only. The fix- nums between -1024 and 1023 are stored in a read-only area and attempts to replace them will result in an "Illegal memory reference" error (see the description of _c_o_p_y_i_n_t* for a way around this problem). For the other valid types, the effect of _r_e_p_l_a_c_e is easy to understand. The fields of g_val1's structure are made eq to the corresponding fields of g_val2's struc- ture. For example, if x and y have lists as values then the effect of (_r_e_p_l_a_c_e _x _y) is the same as (_r_p_l_a_c_a _x (_c_a_r _y)) and (_r_p_l_a_c_d _x (_c_d_r _y)). (scons 'x_arg 'bs_rest) WHERE: bs_rest is a bignum or nil. RETURNS: a bignum whose first bigit is x_arg and whose higher order bigits are bs_rest. (setf g_refexpr 'g_value) NOTE: _s_e_t_f is a generalization of setq. Information may be stored by binding variables, replacing entries of arrays, and vectors, or being put on property lists, among others. Setf will allow the user to store data into some location, by mentioning the operation used to refer to the location. Thus, the first argument may be par- tially evaluated, but only to the extent needed to calculate a reference. _s_e_t_f returns g_value. (Compare to _d_e_s_e_t_q ) ____________________________________________________ (setf x 3) = (setq x 3) (setf (car x) 3) = (rplaca x 3) (setf (get foo 'bar) 3) = (putprop foo 3 'bar) (setf (vref vector index) value) = (vset vector index value) ____________________________________________________ 9 9 Printed: January 31, 1984 Data Structure Access 2-38 (sort 'l_data 'u_comparefn) RETURNS: a list of the elements of l_data ordered by the comparison function u_comparefn. SIDE EFFECT: the list l_data is modified rather than allocated in new storage. NOTE: (_c_o_m_p_a_r_e_f_n '_g__x '_g__y) should return something non-nil if g_x can precede g_y in sorted order; nil if g_y must precede g_x. If u_comparefn is nil, alphabetical order will be used. (sortcar 'l_list 'u_comparefn) RETURNS: a list of the elements of l_list with the _c_a_r's ordered by the sort function u_comparefn. SIDE EFFECT: the list l_list is modified rather than copied. NOTE: Like _s_o_r_t, if u_comparefn is nil, alphabetical order will be used. 9 9 Printed: January 31, 1984