                                   CCHHAAPPTTEERR  22

                             DDaattaa SSttrruuccttuurree AAcccceessss

               The following functions allow one to create and manipu-
          late the various types of lisp data  structures.   Refer  to
          S1.2 for details of the data structures known to FRANZ LISP.

             22..11..  LLiissttss

                     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 nniill.  nniill  is  both  a
                symbol and a representation for the empty list ().

                22..11..11..  lliisstt ccrreeaattiioonn

          ((ccoonnss 'g_arg1 'g_arg2))

               RETURNS: a  new list cell whose car is g_arg1 and whose
                        cdr is g_arg2.

          ((xxccoonnss 'g_arg1 'g_arg2))

               EQUIVALENT TO: _(_c_o_n_s _'_g___a_r_g_2 _'_g___a_r_g_1_)

          ((nnccoonnss 'g_arg))

               EQUIVALENT TO: _(_c_o_n_s _'_g___a_r_g _n_i_l_)

          ((lliisstt ['g_arg1 ... ]))

               RETURNS: a list whose elements are the g_arg_i.

          DDaattaa SSttrruuccttuurree AAcccceessss                                    22--11

          DDaattaa SSttrruuccttuurree AAcccceessss                                    22--22

          ((aappppeenndd '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.

          ((aappppeenndd11 '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_)
              ________________________________________________________________________________________________________

          ((qquuoottee!!  [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 implic-
                     itly  _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: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                    22--33

                     `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
                     S 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_)_)
              ____________________________________________________

          ((bbiiggnnuumm--ttoo--lliisstt 'b_arg))

               RETURNS: A list of the fixnums which are used to repre-
                        sent the bignum.

               NOTE: the inverse of this function is _l_i_s_t_-_t_o_-_b_i_g_n_u_m_.

          ((lliisstt--ttoo--bbiiggnnuumm '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_.

                22..11..22..  lliisstt pprreeddiiccaatteess

          ((ddttpprr 'g_arg))

               RETURNS: t iff g_arg is a list cell.

               NOTE: that (dtpr '()) is nil.  The name ddttpprr is a  con-
                     traction for ``dotted pair''.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                    22--44

          ((lliissttpp 'g_arg))

               RETURNS: t iff g_arg is a list object or nil.

          ((ttaaiillpp '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)
              ____________________________________________________

          ((lleennggtthh 'l_arg))

               RETURNS: the  number  of  elements  in the top level of
                        list l_arg.

                22..11..33..  lliisstt aacccceessssiinngg

          ((ccaarr 'l_arg))
          ((ccddrr '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.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                    22--55

          ((cc....rr 'lh_arg))

               WHERE:   the .. represents any positive number  of  aa's
                        and dd's.

               RETURNS: the  result of accessing the list structure in
                        the way determined by the function name.   The
                        aa's  and  dd's are read from right to left, a dd
                        directing the access down the cdr part of  the
                        list cell and an aa 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  aa's
                     and  dd's,  but  these  functions are supported by
                     rapid accessing and open-compiling  (see  Chapter
                     12).

          ((nntthh '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.

          ((nntthhccddrr '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.

          ((nntthheelleemm '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.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                    22--66

          ((llaasstt '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)

          ((llddiiffff '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.

                22..11..44..  lliisstt mmaanniippuullaattiioonn

          ((rrppllaaccaa '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.

          ((rrppllaaccdd '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.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                    22--77

          ((aattttaacchh '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
                        original _(_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.

          ((ddeelleettee '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.

          ((ddeellqq 'g_val 'l_list ['x_count]))
          ((ddrreemmoovvee '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.

              ____________________________________________________

              ; 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!
              ____________________________________________________

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                    22--88

          ((rreemmqq 'g_x 'l_l ['x_count]))
          ((rreemmoovvee '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.

          ((iinnsseerrtt 'g_object 'l_list 'u_comparefn 'g_nodups))

               RETURNS: a list  consisting  of  l_list  with  g_object
                        destructively  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.

          ((mmeerrggee '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.

          ((ssuubbsstt 'g_x 'g_y 'l_s))
          ((ddssuubbsstt '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  compar-
                     isons.   The  function  _s_u_b_s_t does not modify l_s
                     but the function  _d_s_u_b_s_t  (destructive  substitu-
                     tion) does.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                    22--99

          ((llssuubbsstt '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))
              ____________________________________________________

          ((ssuubbppaaiirr '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_)

          ((nnccoonncc '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.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--1100

              ____________________________________________________

              ; _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
              ____________________________________________________

          ((rreevveerrssee 'l_arg))
          ((nnrreevveerrssee '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.

          ((nnrreeccoonncc '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_)

             22..22..  PPrreeddiiccaatteess

                     The following functions test  for  properties  of
                data  objects.   When the result of the test is either
                'false' or 'true',  then  nniill  will  be  returned  for
                'false' and something other than nniill (often tt) will be
                returned for 'true'.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--1111

          ((aarrrraayypp 'g_arg))

               RETURNS: t iff g_arg is of type array.

          ((aattoomm 'g_arg))

               RETURNS: t iff g_arg is not a list or hunk object.

               NOTE: _(_a_t_o_m _'_(_)_) returns t.

          ((bbccddpp '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.

          ((bbiiggpp 'g_arg))

               RETURNS: t iff g_arg is a bignum.

          ((ddttpprr 'g_arg))

               RETURNS: t iff g_arg is a list cell.

               NOTE: that (dtpr '()) is nil.

          ((hhuunnkkpp 'g_arg))

               RETURNS: t iff g_arg is a hunk.

          ((lliissttpp 'g_arg))

               RETURNS: t iff g_arg is a list object or nil.

          ((ssttrriinnggpp 'g_arg))

               RETURNS: t iff g_arg is a string.

          ((ssyymmbboollpp 'g_arg))

               RETURNS: t iff g_arg is a symbol.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--1122

          ((vvaalluueepp 'g_arg))

               RETURNS: t iff g_arg is a value cell

          ((vveeccttoorrpp 'v_vector))

               RETURNS: tt iff the argument is a vector.

          ((vveeccttoorriipp 'v_vector))

               RETURNS: tt iff the argument is an immediate-vector.

          ((ttyyppee 'g_arg))
          ((ttyyppeepp 'g_arg))

               RETURNS: a symbol whose pname  describes  the  type  of
                        g_arg.

          ((ssiiggnnpp 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.

                                   +--------------------+
                                   |s_test   tested     |
                                   |                    |
                                   +--------------------+
                                   |l        g_val < 0  |
                                   |le       g_val <= 0 |
                                   |e        g_val = 0  |
                                   |n        g_val != 0 |
                                   |ge       g_val >= 0 |
                                   |g        g_val > 0  |
                                   +--------------------+

          ((eeqq '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

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--1133

                     _u_c_o_n_c_a_t or _m_a_k_n_a_m) it will be interned.]

          ((nneeqq 'g_x 'g_y))

               RETURNS: t if g_x is not _e_q to g_y, otherwise nil.

          ((eeqquuaall 'g_arg1 'g_arg2))
          ((eeqqssttrr '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

                (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
              ____________________________________________________

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--1144

          ((nnoott 'g_arg))
          ((nnuullll 'g_arg))

               RETURNS: t iff g_arg is nil.

          ((mmeemmbbeerr 'g_arg1 'l_arg2))
          ((mmeemmqq '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.

             22..33..  SSyymmbboollss aanndd SSttrriinnggss

                     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
                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.

                22..33..11..  ssyymmbbooll aanndd ssttrriinngg ccrreeaattiioonn

          ((ccoonnccaatt ['stn_arg1 ... ]))
          ((uuccoonnccaatt ['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 cre-
                     ated on the oblist, the function _u_c_o_n_c_a_t does the

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--1155

                     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

          ((ccoonnccaattll 'l_arg))

               EQUIVALENT TO: _(_a_p_p_l_y _'_c_o_n_c_a_t _'_l___a_r_g_)

          ((iimmppllooddee 'l_arg))
          ((mmaakknnaamm '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 equiv-
                        alent  ascii  character.  In order to concate-
                        nate 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.

          ((ggeennssyymm ['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 num-
                     ber of times you have called gensym.

          ((ccooppyyssyymmbbooll '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.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--1166

          ((aasscciiii '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.

          ((iinntteerrnn 's_arg))

               RETURNS: s_arg

               SIDE EFFECT: s_arg is put on the oblist if  it  is  not
                            already there.

          ((rreemmoobb 's_symbol))

               RETURNS: s_symbol

               SIDE EFFECT: s_symbol is removed from the oblist.

          ((rreemmaattoomm '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!

                22..33..22..  ssttrriinngg aanndd ssyymmbbooll pprreeddiiccaatteess

          ((bboouunnddpp '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.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--1177

          ((aallpphhaalleesssspp '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.

                22..33..33..  ssyymmbbooll aanndd ssttrriinngg aacccceessssiinngg

          ((ssyymmeevvaall '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.

          ((ggeett__ppnnaammee 's_arg))

               RETURNS: the string which is the print name of s_arg.

          ((pplliisstt 's_arg))

               RETURNS: the property list of s_arg.

          ((ggeettdd '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.

          ((ggeettcchhaarr 's_arg 'x_index))
          ((nntthhcchhaarr 's_arg 'x_index))
          ((ggeettcchhaarrnn '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.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--1188

          ((ssuubbssttrriinngg 'st_string 'x_index ['x_length]))
          ((ssuubbssttrriinnggnn '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.

                22..33..44..  ssyymmbbooll aanndd ssttrriinngg mmaanniippuullaattiioonn

          ((sseett 's_arg1 'g_arg2))

               RETURNS: g_arg2.

               SIDE EFFECT: the value of s_arg1 is set to g_arg2.

          ((sseettqq 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.

          ((ddeesseettqq 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 )

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--1199

               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).

          ((sseettpplliisstt 's_atm 'l_plist))

               RETURNS: l_plist.

               SIDE EFFECT: the property  list  of  s_atm  is  set  to
                            l_plist.

          ((mmaakkuunnbboouunndd '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.

          ((aaeexxppllooddee 's_arg))
          ((eexxppllooddee 'g_arg))
          ((aaeexxppllooddeecc 's_arg))
          ((eexxppllooddeecc 'g_arg))
          ((aaeexxppllooddeenn 's_arg))
          ((eexxppllooddeenn '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
                     returned.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--2200

              ____________________________________________________

              -> _(_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)
              ____________________________________________________

             22..44..  VVeeccttoorrss

                     See Chapter 9 for a discussion of vectors.   They
                are  less efficient that hunks but more efficient than
                arrays.

                22..44..11..  vveeccttoorr ccrreeaattiioonn

          ((nneeww--vveeccttoorr 'x_size ['g_fill ['g_prop]]))

               RETURNS: A vveeccttoorr 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
                        property  is  set  to  g_prop,  or  to nil, by
                        default.

          ((nneeww--vveeccttoorrii--bbyyttee 'x_size ['g_fill ['g_prop]]))
          ((nneeww--vveeccttoorrii--wwoorrdd 'x_size ['g_fill ['g_prop]]))
          ((nneeww--vveeccttoorrii--lloonngg 'x_size ['g_fill ['g_prop]]))

               RETURNS: A vveeccttoorrii 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  initialized
                        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: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--2211

               Vectors  may  be created by specifying multiple initial
               values:

          ((vveeccttoorr ['g_val0 'g_val1 ...]))

               RETURNS: a vveeccttoorr, 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.

          ((vveeccttoorrii--bbyyttee ['x_val0 'x_val2 ...]))
          ((vveeccttoorrii--wwoorrdd ['x_val0 'x_val2 ...]))
          ((vveeccttoorrii--lloonngg ['x_val0 'x_val2 ...]))

               RETURNS: a vveeccttoorrii, 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  vec-
                        tori-word.   The  vector's  property  will  be
                        null.

                22..44..22..  vveeccttoorr rreeffeerreennccee

          ((vvrreeff 'v_vect 'x_index))
          ((vvrreeffii--bbyyttee 'V_vect 'x_bindex))
          ((vvrreeffii--wwoorrdd 'V_vect 'x_windex))
          ((vvrreeffii--lloonngg '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.

          ((vvpprroopp 'Vv_vect))

               RETURNS: The Lisp property associated with a vector.

          ((vvggeett 'Vv_vect 'g_ind))

               RETURNS: The value stored under g_ind if the Lisp prop-
                        erty associated with 'Vv_vect is a disembodied
                        property list.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--2222

          ((vvssiizzee 'Vv_vect))
          ((vvssiizzee--bbyyttee 'V_vect))
          ((vvssiizzee--wwoorrdd '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.

                22..44..33..  vveeccttoorr mmooddffiiccaattiioonn

          ((vvsseett 'v_vect 'x_index 'g_val))
          ((vvsseettii--bbyyttee 'V_vect 'x_bindex 'x_val))
          ((vvsseettii--wwoorrdd 'V_vect 'x_windex 'x_val))
          ((vvsseettii--lloonngg '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.

          ((vvsseettpprroopp '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.

          ((vvppuuttpprroopp '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.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--2233

             22..55..  AArrrraayyss

                     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.

                22..55..11..  aarrrraayy ccrreeaattiioonn

          ((mmaarrrraayy '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 S
                        1.2.10).

          ((**aarrrraayy 's_name 's_type 'x_dim1 ... 'x_dim_n))
          ((aarrrraayy 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,
                     fixnum and flonum are equivalent and the elements
                     of  these  arrays can be any type of lisp object.
                     Fixnum-block   and   flonum-block   arrays    are
                     restricted  to  fixnums  and flonums respectively
                     and are used mainly to communicate  with  foreign
                     functions (see S8.5).

               NOTE: _*_a_r_r_a_y evaluates its arguments, _a_r_r_a_y does not.

                22..55..22..  aarrrraayy pprreeddiiccaattee

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--2244

          ((aarrrraayypp 'g_arg))

               RETURNS: t iff g_arg is of type array.

                22..55..33..  aarrrraayy aacccceessssoorrss

          ((ggeettaacccceessss 'a_array))
          ((ggeettaauuxx 'a_array))
          ((ggeettddeellttaa 'a_array))
          ((ggeettddaattaa 'a_array))
          ((ggeettlleennggtthh 'a_array))

               RETURNS: the field of the array object a_array given by
                        the function name.

          ((aarrrraayyrreeff '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.

          ((aarrrraayyccaallll 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.

          ((aarrrraayyddiimmss 's_name))

               RETURNS: a list of the type and  bounds  of  the  array
                        s_name.

          ((lliissttaarrrraayy '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.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--2255

              ____________________________________________________

              ; 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))
              ____________________________________________________

                22..55..44..  aarrrraayy mmaanniippuullaattiioonn

          ((ppuuttaacccceessss 'a_array 'su_func))
          ((ppuuttaauuxx 'a_array 'g_aux))
          ((ppuuttddaattaa 'a_array 'g_arg))
          ((ppuuttddeellttaa 'a_array 'x_delta))
          ((ppuuttlleennggtthh '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.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--2266

          ((ssttoorree '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.

          ((ffiillllaarrrraayy '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.

             22..66..  HHuunnkkss

                     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  distin-
                guished  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.

                22..66..11..  hhuunnkk ccrreeaattiioonn

          ((hhuunnkk '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}

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--2277

          ((mmaakkhhuunnkk '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_}

          ((**mmaakkhhuunnkk 'x_arg))

               RETURNS: a hunk of size 2initialized 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.

                22..66..22..  hhuunnkk aacccceessssoorr

          ((ccxxrr 'x_ind 'h_hunk))

               RETURNS: element  x_ind (starting at 0) of hunk h_hunk.

          ((hhuunnkk--ttoo--lliisstt 'h_hunk))

               RETURNS: a list consisting of the elements of h_hunk.

                22..66..33..  hhuunnkk mmaanniippuullaattoorrss

          ((rrppllaaccxx 'x_ind 'h_hunk 'g_val))
          ((**rrppllaaccxx '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.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--2288

          ((hhuunnkkssiizzee '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

             22..77..  BBccddss

                     A bcd object contains a pointer to compiled  code
                and  to  the type of function object the compiled code
                represents.

          ((ggeettddiisscc 'y_bcd))
          ((ggeetteennttrryy 'y_bcd))

               RETURNS: the field of the bcd object given by the func-
                        tion name.

          ((ppuuttddiisscc 'y_func 's_discipline))

               RETURNS: s_discipline

               SIDE EFFECT: Sets  the  discipline  field  of y_func to
                            s_discipline.

             22..88..  SSttrruuccttuurreess

                     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.

                22..88..11..  aassssoocc lliisstt

                        An  `assoc  list'  (or alist) is a common lisp
                   data structure.  It has the form
                   ((key1 . value1) (key2 . value2)  (key3  .  value3)
                                  ... (keyn . valuen))

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--2299

          ((aassssoocc 'g_arg1 'l_arg2))
          ((aassssqq '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.

          ((ssaassssoocc '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.

          ((ssaassssqq '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)
              ____________________________________________________

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--3300

          ((ssuubblliiss '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.

                22..88..22..  pprrooppeerrttyy lliisstt

                        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 'disembod-
                   ied' property list if it contains an odd number  of
                   elements, the first of which is ignored.

          ((pplliisstt 's_name))

               RETURNS: the property list of s_name.

          ((sseettpplliisstt 's_atm 'l_plist))

               RETURNS: l_plist.

               SIDE EFFECT: the  property  list  of  s_atm  is  set to
                            l_plist.

          ((ggeett '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 prop-
                     erty 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.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--3311

          ((ggeettll '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.

          ((ppuuttpprroopp 'ls_name 'g_val 'g_ind))
          ((ddeeffpprroopp 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.

          ((rreemmpprroopp '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.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--3322

              ____________________________________________________

              -> _(_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
              ____________________________________________________

                22..88..33..  ttccoonncc ssttrruuccttuurree

                        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_.

          ((ttccoonncc 'l_ptr 'g_x))

               WHERE:   l_ptr is a tconc structure.

               RETURNS: l_ptr with g_x added to the end.

          ((llccoonncc 'l_ptr 'l_x))

               WHERE:   l_ptr is a tconc structure.

               RETURNS: l_ptr with the list l_x spliced in at the end.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--3333

              ____________________________________________________

              ; 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)
              ____________________________________________________

                22..88..44..  ffcclloossuurreess

                        An  fclosure  is  a  functional  object  which
                   admits some data manipulations.  They are discussed
                   in S8.4.  Internally,  they  are  constructed  from
                   vectors.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--3344

          ((ffcclloossuurree '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.

          ((ffcclloossuurree--aalliisstt '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.

          ((ffcclloossuurree--ffuunnccttiioonn 'v_fclosure))

               RETURNS: the functional object part of the fclosure.

          ((ffcclloossuurreepp 'v_fclosure))

               RETURNS: t iff the argument is an fclosure.

          ((ssyymmeevvaall--iinn--ffcclloossuurree 'v_fclosure 's_symbol))

               RETURNS: the current binding of a particular symbol  in
                        an fclosure.

          ((sseett--iinn--ffcclloossuurree 'v_fclosure 's_symbol 'g_newvalue))

               RETURNS: g_newvalue.

               SIDE EFFECT: The  variable  s_symbol  is  bound  in the
                            fclosure to g_newvalue.

             22..99..  RRaannddoomm ffuunnccttiioonnss

                     The following functions don't fall  into  any  of
                the classifications above.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--3355

          ((bbccddaadd '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.

          ((ccooppyy 'g_arg))

               RETURNS: A structure _e_q_u_a_l to g_arg but with  new  list
                        cells.

          ((ccooppyyiinntt** 'x_arg))

               RETURNS: a fixnum with the same value as x_arg but in a
                        freshly allocated cell.

          ((ccppyy11 'xvt_arg))

               RETURNS: a new cell of the same type  as  xvt_arg  with
                        the same value as xvt_arg.

          ((ggeettaaddddrreessss  '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.

          ((mmaaccrrooeexxppaanndd '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.

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--3366

          ((ppttrr 'g_arg))

               RETURNS: a value cell initialized to point to g_arg.

          ((qquuoottee g_arg))

               RETURNS: g_arg.

               NOTE: the reader allows you to abbreviate  (quote  foo)
                     as 'foo.

          ((kkwwoottee 'g_arg))

               RETURNS:  _(_l_i_s_t _(_q_u_o_t_e _q_u_o_t_e_) _g___a_r_g_).

          ((rreeppllaaccee '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: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--3377

                            be many other pointers to that box.

                            Another  problem with replacing fixnums is
                            that  some  boxes  are   read-only.    The
                            fixnums  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  descrip-
                            tion  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_)_).

          ((ssccoonnss '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.

          ((sseettff 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)
              ____________________________________________________

                                             Printed: October 16, 1993

          DDaattaa SSttrruuccttuurree AAcccceessss                                   22--3388

          ((ssoorrtt '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.

          ((ssoorrttccaarr '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.

                                             Printed: October 16, 1993


# HSR/NHANES/HSA7708_replication
script = 'HSA 7708 Replication Project\nhttps://doi.org/10.3945/jn.109.112573'

## Pull NHANES Data
Files = c('DEMO', 'DIQ', 'BPQ', 'BPX', 'FSQ', 'LAB13', 'LAB13AM', 'LAB10AM')
Cycles = c('1999-2000')
Descriptions = c('Demographic Variables and Sample Weights', 'Diabetes', 'Blood Pressure & Cholesterol', 'Blood Pressure', 'Food Security', 'Cholesterol - Total & HDL', 'Cholesterol - LDL & Triglycerides', 'Plasma Fasting Glucose, Serum C-peptide & Insulin')
df_NH1 = pull_stack(Files, Cycles, Descriptions)
df_NH1$FSDAD <- df_NH1$ADFDSEC
head(df_NH1)

## Pull NHANES Data
Files = c('DEMO', 'DIQ', 'BPQ', 'BPX', 'FSQ', 'L13', 'L13AM', 'L10AM')
Cycles = c('2001-2002')
Descriptions = c('Demographic Variables and Sample Weights', 'Diabetes', 'Blood Pressure & Cholesterol', 'Blood Pressure', 'Food Security', 'Cholesterol - Total & HDL', 'Cholesterol - LDL & Triglycerides', 'Plasma Fasting Glucose, Serum C-peptide & Insulin')
df_NH2 = pull_stack(Files, Cycles, Descriptions)
df_NH2$FSDAD <- df_NH2$ADFDSEC
head(df_NH2)

## Pull NHANES Data
Files = c('DEMO', 'DIQ', 'BPQ', 'BPX', 'FSQ', 'L13', 'L13AM', 'L10AM')
Cycles = c('2003-2004')
Descriptions = c('Demographic Variables and Sample Weights', 'Diabetes', 'Blood Pressure & Cholesterol', 'Blood Pressure', 'Food Security', 'Cholesterol - Total & HDL', 'Cholesterol - LDL & Triglycerides', 'Plasma Fasting Glucose, Serum C-peptide & Insulin')
df_NH3 = pull_stack(Files, Cycles, Descriptions)
head(df_NH3)

## Combine cycles
V = colnames(df_NH1)
df_V1 = as.data.frame(V)
df_V1$Cycle <- '1999-2000'
V = colnames(df_NH2)
df_V2 = as.data.frame(V)
df_V2$Cycle <- '2001-2002'
V = colnames(df_NH3)
df_V3 = as.data.frame(V)
df_V3$Cycle <- '2003-2004'
df_V = merge(df_V1, df_V2, by = 'V', how = 'inner')
df_V = merge(df_V, df_V3, by = 'V', how = 'inner')
vars = c(as.character(df_V$V))
df_NH = rbind(df_NH1[vars], df_NH2[vars], df_NH3[vars])
head(df_NH)

## Select variables
NHANES_Variables <- c('RIAGENDR',
                    'RIDAGEYR',
                    'RIDRETH1',
                    'DMDEDUC2',
                    'INDFMPIR',
                    'BPQ020',
                    'BPXSY1',
                    'BPXDI1',
                    'BPQ080',
                    'LBXTC',
                    'DIQ010',
                    'LBXGLU',
                    'FSDAD')
NHANES_Description <- c('Gender',
                    'Age at Screening',
                    'Race/Ethnicity',
                    'Education Level - Adults 20+',
                    'Family income to Poverty Ratio',
                    'Doctor told you that you have high blood pressure',
                    'Systolic Blood Pressure',
                    'Diastolic Blood Pressure',
                    'Doctor told you that you have high cholesterol',
                    'Total Cholesterol (mg/dL)',
                    'Doctor told you that you have diabetes',
                    'Glucose, plasma (mg/dL)',
                    'Adult food security category')
df_NHANES = data.frame(NHANES_Variables, NHANES_Description)

Study_Variables <- c('Gender',
                    'Age',
                    'Race',
                    'Education',
                    'Income',
                    'Hypertension',
                    'Hyperlipidemia',
                    'Diabetes',
                    'Food')
Study_Description <- c('Female Identifying (RIAGENDR == 2)',
                    'Age in years (18 to 65) (RIAGENDR = RIAGENDR)',
                    'Non-white or Hispanic (RIDRETH1 != 3)',
                    'High School Education or less (DMDEDUC2 < 3)',
                    'Income Relative to Poverty Line (above 200%)',
                    'Hypertension Diagnosed (BPQ020 = 1), Clinical (BPXDI1 > 140, BPXSY1 > 90)',
                    'Hyperlipidemia Diagnosed (BPQ080 = 1), Clinical (LBXTC > 200, LBDLDL > 160)',
                    'Diabetes Diagnosed (DQI010 = 1), Clinical (LBXGLU > 126)',
                    'Food Security Low or Very Low, (FSDAD >= 3)')
df_Study = data.frame(Study_Variables, Study_Description)

### Modify Variables
New = 'Gender'
Old = 'RIAGENDR'
Level = 2
df_NH[New] <- 0
df_NH[New][df_NH[Old] == Level] <- 1
summary(df_NH[New])
New = 'Age'
Old = 'RIDAGEYR'
df_NH[New] <- df_NH[Old]
summary(df_NH[New])
New = 'Race'
Old = 'RIDRETH1'
Level = 1
df_NH[New] <- 3
df_NH[New][df_NH[Old] != Level] <- 1
summary(df_NH[New])
New = 'Education'
Old = 'DMDEDUC2'
Level = 3
df_NH[New] <- 0
df_NH[New][df_NH[Old] < Level] <- 1
summary(df_NH[New])
New = 'Income'
Old = 'INDHHINC'
df_NH[New] <- df_NH[Old]
df_NH[New][df_NH[New] > 5] <- 5
summary(df_NH[New])
New = 'Hypertension'
Old = 'BPQ020'
Old2 = 'BPXDI1'
Old3 = 'BPXSY1'
Level = 1
Level2 = 140
Level3 = 90
df_NH[New] <- 0
df_NH[New][df_NH[Old] == Level] <- 1
df_NH[New][df_NH[Old2] > Level2] <- 1
df_NH[New][df_NH[Old3] > Level3] <- 1
summary(df_NH[New])
New = 'Hyperlipidemia'
Old = 'BPQ080'
Old2 = 'LBXTC'
Old3 = 'LBDLDL'
Level = 1
Level2 = 200
Level3 = 160
df_NH[New] <- 0
df_NH[New][df_NH[Old] == Level] <- 1
df_NH[New][df_NH[Old2] > Level2] <- 1
df_NH[New][df_NH[Old3] > Level3] <- 1
summary(df_NH[New])
New = 'Diabetes'
Old = 'DIQ010'
Old2 = 'LBXGLU'
Level = 1
Level2 = 126
df_NH[New] <- 0
df_NH[New][df_NH[Old] == Level] <- 1
df_NH[New][df_NH[Old2] > Level2] <- 1
summary(df_NH[New])
New = 'Food'
Old = 'FSDAD'
Level = 3
df_NH[New] <- 0
df_NH[New][df_NH[Old] >= Level] <- 1
summary(df_NH[New])

### Export to Summary File
options(width = 250)
sink(file = 'summary.txt', append = TRUE, type = 'output')
cat(script, '\n\n', file = 'summary.txt', append = TRUE)
cat('NHANES Cycles: ', Cycles, '\n')
cat('NHANES Files: ', Files, '\n')
cat('NHANES Variables:', '\n', file = 'summary.txt', append = TRUE)
summary(df_NH[NHANES_Variables])
cat('\n', file = 'summary.txt', append = TRUE)
cat('NHANES Descriptions:', '\n', file = 'summary.txt', append = TRUE)
df_NHANES
cat('\n', file = 'summary.txt', append = TRUE)
cat('Study Variables:', '\n', file = 'summary.txt', append = TRUE)
summary(df_NH[Study_Variables])
cat('\n', file = 'summary.txt', append = TRUE)
cat('Study Descriptions:', '\n', file = 'summary.txt', append = TRUE)
df_Study
cat('\n', file = 'summary.txt', append = TRUE)
cat(c('####################', '\n\n'), file = 'summary.txt', append = TRUE)
sink()

### Survey Weighted Generalizaed Reghression Models
D = df_NH[which(df_NH$INDFMPIR < 2 & df_NH$RIDAGEYR > 18 & df_NH$RIDAGEYR < 65), ]
S = nhanes_survey_design(D, weights_column = 'WTINT2YR')
X = 'Food'
A = c('Gender', 'Age', 'Race', 'Education', 'Income')
Y1 = 'Hypertension'
F1 = as.formula(paste(Y1, ' ~ ', paste(X, '+', paste(A, collapse = ' + ')), sep = ''))
M1 = svyglm(F1, design = S, data = D, family = poisson()) # Log link [Y = ln(DV)] (aka: Log-Linear) with poisson error (aka: Poisson regression)
Y2 = 'Hyperlipidemia'
F2 = as.formula(paste(Y2, ' ~ ', paste(X, '+', paste(A, collapse = ' + ')), sep = ''))
M2 = svyglm(F2, design = S, data = D, family = poisson()) # Log link [Y = ln(DV)] (aka: Log-Linear) with poisson error (aka: Poisson regression)
Y3 = 'Diabetes'
F3 = as.formula(paste(Y3, ' ~ ', paste(X, '+', paste(A, collapse = ' + ')), sep = ''))
M3 = svyglm(F3, design = S, data = D, family = poisson()) # Log link [Y = ln(DV)] (aka: Log-Linear) with poisson error (aka: Poisson regression)

### Export to Summary File
sink(file = 'summary.txt', append = TRUE, type = 'output')
cat('Generalized Regression Models using Survey Weights', '\n\n', file = 'summary.txt', append = TRUE)
cat('Title:\n', Y1, 'and', X, 'adjusted by', A, '\n', file = 'summary.txt', append = TRUE)
summary(M1)
cat('Odds Ratios: ', '\n', 'Intercept', X, A, '\n', exp(coef(M1)), '\n', file = 'summary.txt', append = TRUE)
cat('\n', file = 'summary.txt', append = TRUE)
cat('Title:\n', Y2, 'and', X, 'adjusted by', A, '\n', file = 'summary.txt', append = TRUE)
summary(M2)
cat('Odds Ratios: ', '\n', 'Intercept', X, A, '\n', exp(coef(M2)), '\n', file = 'summary.txt', append = TRUE)
cat('\n', file = 'summary.txt', append = TRUE)
cat('Title:\n', Y3, 'and', X, 'adjusted by', A, '\n', file = 'summary.txt', append = TRUE)
summary(M3)
cat('Odds Ratios: ', '\n', 'Intercept', X, A, '\n', exp(coef(M3)), '\n', file = 'summary.txt', append = TRUE)
cat('\n', file = 'summary.txt', append = TRUE)
cat(c('####################', '\n\n'), file = 'summary.txt', append = TRUE)
sink()