Annotation of 42BSD/ucb/lisp/lisplib/manual/ch8.r, revision 1.1

1.1     ! root        1: 
        !             2: 
        !             3: 
        !             4: 
        !             5: 
        !             6: 
        !             7: 
        !             8:                          CHAPTER  8
        !             9: 
        !            10: 
        !            11:               Functions, Fclosures, and Macros
        !            12: 
        !            13: 
        !            14: 
        !            15: 
        !            16: 
        !            17: 
        !            18:    8.1.  valid function objects
        !            19: 
        !            20:            There are many different objects which can occupy
        !            21:       the  function field of a symbol object.  Table 8.1, on
        !            22:       the following page, shows all  of  the  possibilities,
        !            23:       how  to recognize them, and where to look for documen-
        !            24:       tation.
        !            25: 
        !            26: 
        !            27: 
        !            28:    8.2.  functions
        !            29: 
        !            30:            The basic Lisp function is the  lambda  function.
        !            31:       When a lambda function is called, the actual arguments
        !            32:       are evaluated from left to right and are  lambda-bound
        !            33:       to the formal parameters of the lambda function.
        !            34: 
        !            35:            An nlambda function is usually used for functions
        !            36:       which  are  invoked  by  the  user at top level.  Some
        !            37:       built-in functions which evaluate their  arguments  in
        !            38:       special  ways  are  also  nlambdas (e.g _c_o_n_d, _d_o, _o_r).
        !            39:       When an  nlambda  function  is  called,  the  list  of
        !            40:       unevaluated  arguments  is  lambda bound to the single
        !            41:       formal parameter of the nlambda function.
        !            42: 
        !            43:            Some programmers will  use  an  nlambda  function
        !            44:       when  they  are  not  sure  how many arguments will be
        !            45:       passed.  Then, the first thing  the  nlambda  function
        !            46:       does  is  map  _e_v_a_l over the list of unevaluated argu-
        !            47:       ments it has been passed.  This is usually  the  wrong
        !            48:       thing  to  do,  as it will not work compiled if any of
        !            49:       the arguments are local variables. The solution is  to
        !            50:       use  a  lexpr.   When  a lexpr function is called, the
        !            51:       arguments are evaluated and a fixnum  whose  value  is
        !            52:       the  number of arguments is lambda-bound to the single
        !            53:       formal parameter of the lexpr function.  The lexpr can
        !            54:       then access the arguments using the _a_r_g function.
        !            55: 
        !            56:            When a function is compiled, _s_p_e_c_i_a_l declarations
        !            57:       may  be  needed to preserve its behavior.  An argument
        !            58:       is not lambda-bound to the name of  the  corresponding
        !            59:       formal parameter unless that formal parameter has been
        !            60:       declared _s_p_e_c_i_a_l (see 12.3.2.2).
        !            61: 
        !            62: 
        !            63: Functions, Fclosures, and Macros                         8-1
        !            64: 
        !            65: 
        !            66: 
        !            67: 
        !            68: 
        !            69: 
        !            70: 
        !            71: Functions, Fclosures, and Macros                         8-2
        !            72: 
        !            73: 
        !            74: 
        !            75: 
        !            76: 
        !            77: 8________________________________________________________________
        !            78:    informal name            object type          documentation
        !            79: 8________________________________________________________________________________________________________________________________
        !            80:     interpreted            list with _c_a_r              8.2
        !            81:   lambda function           _e_q to lambda
        !            82: 8________________________________________________________________
        !            83:     interpreted            list with _c_a_r              8.2
        !            84:   nlambda function         _e_q to nlambda
        !            85: 8________________________________________________________________
        !            86:     interpreted            list with _c_a_r              8.2
        !            87:    lexpr function           _e_q to lexpr
        !            88: 8________________________________________________________________
        !            89:     interpreted            list with _c_a_r              8.3
        !            90:        macro                _e_q to macro
        !            91: 8________________________________________________________________
        !            92:       fclosure           vector with _v_p_r_o_p            8.4
        !            93:                            _e_q to fclosure
        !            94: 8________________________________________________________________
        !            95:       compiled         binary with discipline         8.2
        !            96:   lambda or lexpr           _e_q to lambda
        !            97:       function
        !            98: 8________________________________________________________________
        !            99:       compiled         binary with discipline         8.2
        !           100:   nlambda function         _e_q to nlambda
        !           101: 8________________________________________________________________
        !           102:       compiled         binary with discipline         8.3
        !           103:        macro                _e_q to macro
        !           104: 8________________________________________________________________
        !           105:       foreign          binary with discipline         8.5
        !           106:      subroutine          of "subroutine"[]
        !           107: 8________________________________________________________________
        !           108:       foreign          binary with discipline         8.5
        !           109:       function            of "function"[]
        !           110: 8________________________________________________________________
        !           111:       foreign          binary with discipline         8.5
        !           112:   integer function    of "integer-function"[]
        !           113: 8________________________________________________________________
        !           114:       foreign          binary with discipline         8.5
        !           115:    real function        of "real-function"[]
        !           116: 8________________________________________________________________
        !           117:       foreign          binary with discipline         8.5
        !           118:      C function          of "c-function"[]
        !           119: 8________________________________________________________________
        !           120:       foreign          binary with discipline         8.5
        !           121:   double function     of "double-c-function"[]
        !           122: 8________________________________________________________________
        !           123:       foreign          binary with discipline         8.5
        !           124:  structure function   of "vector-c-function"[]
        !           125: 8________________________________________________________________
        !           126:        array                array object               9
        !           127: 8________________________________________________________________
        !           128: 7|8|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|
        !           129: 
        !           130: 
        !           131: 
        !           132: 
        !           133: 
        !           134: 
        !           135: 
        !           136: 
        !           137: 
        !           138: 
        !           139: 
        !           140: 
        !           141: 
        !           142: 
        !           143: 
        !           144: 
        !           145: 
        !           146: 
        !           147: 
        !           148: 
        !           149: 
        !           150: 
        !           151: 
        !           152: 
        !           153: 
        !           154: 
        !           155: 
        !           156: 
        !           157: 
        !           158: 
        !           159: 
        !           160: 
        !           161: 
        !           162: 
        !           163: 
        !           164: 
        !           165: 
        !           166: 
        !           167: 
        !           168: 9                   |8|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|
        !           169: 
        !           170: 
        !           171: 
        !           172: 
        !           173: 
        !           174: 
        !           175: 
        !           176: 
        !           177: 
        !           178: 
        !           179: 
        !           180: 
        !           181: 
        !           182: 
        !           183: 
        !           184: 
        !           185: 
        !           186: 
        !           187: 
        !           188: 
        !           189: 
        !           190: 
        !           191: 
        !           192: 
        !           193: 
        !           194: 
        !           195: 
        !           196: 
        !           197: 
        !           198: 
        !           199: 
        !           200: 
        !           201: 
        !           202: 
        !           203: 
        !           204: 
        !           205: 
        !           206: 
        !           207: 
        !           208: 9                                              |8|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|
        !           209: 
        !           210: 
        !           211: 
        !           212: 
        !           213: 
        !           214: 
        !           215: 
        !           216: 
        !           217: 
        !           218: 
        !           219: 
        !           220: 
        !           221: 
        !           222: 
        !           223: 
        !           224: 
        !           225: 
        !           226: 
        !           227: 
        !           228: 
        !           229: 
        !           230: 
        !           231: 
        !           232: 
        !           233: 
        !           234: 
        !           235: 
        !           236: 
        !           237: 
        !           238: 
        !           239: 
        !           240: 
        !           241: 
        !           242: 
        !           243: 
        !           244: 
        !           245: 
        !           246: 
        !           247: 
        !           248: 9                                                               |8|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|
        !           249: 
        !           250: 
        !           251: 
        !           252: 
        !           253: 
        !           254: 
        !           255: 
        !           256: 
        !           257: 
        !           258: 
        !           259: 
        !           260: 
        !           261: 
        !           262: 
        !           263: 
        !           264: 
        !           265: 
        !           266: 
        !           267: 
        !           268: 
        !           269: 
        !           270: 
        !           271: 
        !           272: 
        !           273: 
        !           274: 
        !           275: 
        !           276: 
        !           277: 
        !           278: 
        !           279: 
        !           280: 
        !           281: 
        !           282: 
        !           283: 
        !           284: 
        !           285: 
        !           286: 
        !           287: 
        !           288: 
        !           289: 
        !           290: 9                         Table 8.1
        !           291: 
        !           292: ____________________
        !           293: 9   []Only the first character of the string is significant (i.e "s"
        !           294: is ok for "subroutine")
        !           295: 
        !           296: 
        !           297: 
        !           298: 9                                     Printed: August 5, 1983
        !           299: 
        !           300: 
        !           301: 
        !           302: 
        !           303: 
        !           304: 
        !           305: 
        !           306: Functions, Fclosures, and Macros                         8-3
        !           307: 
        !           308: 
        !           309:            Lambda and lexpr functions both  compile  into  a
        !           310:       binary object with a discipline of lambda.  However, a
        !           311:       compiled lexpr still acts like an interpreted lexpr.
        !           312: 
        !           313: 
        !           314: 
        !           315:    8.3.  macros
        !           316: 
        !           317:            An important feature of Lisp is  its  ability  to
        !           318:       manipulate  programs  as  data.   As a result of this,
        !           319:       most Lisp implementations  have  very  powerful  macro
        !           320:       facilities.  The Lisp language's macro facility can be
        !           321:       used to incorporate  popular  features  of  the  other
        !           322:       languages  into  Lisp.   For  example, there are macro
        !           323:       packages which allow one to create records  (ala  Pas-
        !           324:       cal)  and  refer  to  elements of those records by the
        !           325:       field names.  The _s_t_r_u_c_t package imported from Maclisp
        !           326:       does  this.   Another  popular  use  for  macros is to
        !           327:       create more readable control structures  which  expand
        !           328:       into  _c_o_n_d,  _o_r  and  _a_n_d.  One such example is the If
        !           329:       macro.  It allows you to write
        !           330: 
        !           331:       (_I_f (_e_q_u_a_l _n_u_m_b _0) _t_h_e_n (_p_r_i_n_t '_z_e_r_o) (_t_e_r_p_r)
        !           332:        _e_l_s_e_i_f (_e_q_u_a_l _n_u_m_b _1) _t_h_e_n (_p_r_i_n_t '_o_n_e) (_t_e_r_p_r)
        !           333:        _e_l_s_e (_p_r_i_n_t '|_I _g_i_v_e _u_p|))
        !           334: 
        !           335:       which expands to
        !           336: 
        !           337:       (_c_o_n_d
        !           338:           ((_e_q_u_a_l _n_u_m_b _0) (_p_r_i_n_t '_z_e_r_o) (_t_e_r_p_r))
        !           339:           ((_e_q_u_a_l _n_u_m_b _1) (_p_r_i_n_t '_o_n_e) (_t_e_r_p_r))
        !           340:           (_t (_p_r_i_n_t '|_I _g_i_v_e _u_p|)))
        !           341: 
        !           342: 
        !           343: 
        !           344: 
        !           345:       8.3.1.  macro forms
        !           346: 
        !           347:               A macro is a function  which  accepts  a  Lisp
        !           348:          expression   as  input  and  returns  another  Lisp
        !           349:          expression.  The action the macro takes  is  called
        !           350:          macro expansion.  Here is a simple example:
        !           351: 
        !           352:          -> (_d_e_f _f_i_r_s_t (_m_a_c_r_o (_x) (_c_o_n_s '_c_a_r (_c_d_r _x))))
        !           353:          first
        !           354:          -> (_f_i_r_s_t '(_a _b _c))
        !           355:          a
        !           356:          -> (_a_p_p_l_y '_f_i_r_s_t '(_f_i_r_s_t '(_a _b _c)))
        !           357:          (car '(a b c))
        !           358: 
        !           359:          The first input line defines a macro called  _f_i_r_s_t.
        !           360:          Notice  that the macro has one formal parameter, _x.
        !           361:          On the second input line, we ask the interpreter to
        !           362: 
        !           363: 
        !           364:                                      Printed: August 5, 1983
        !           365: 
        !           366: 
        !           367: 
        !           368: 
        !           369: 
        !           370: 
        !           371: 
        !           372: Functions, Fclosures, and Macros                         8-4
        !           373: 
        !           374: 
        !           375:          evaluate  (_f_i_r_s_t '(_a _b _c)).   _E_v_a_l  sees that _f_i_r_s_t
        !           376:          has a function definition  of  type  macro,  so  it
        !           377:          evaluates  _f_i_r_s_t's definition, passing to _f_i_r_s_t, as
        !           378:          an argument, the form _e_v_a_l  itself  was  trying  to
        !           379:          evaluate:  (_f_i_r_s_t '(_a _b _c)).  The _f_i_r_s_t macro chops
        !           380:          off the car of the argument with _c_d_r, cons'  a  _c_a_r
        !           381:          at   the   beginning   of   the  list  and  returns
        !           382:          (_c_a_r '(_a _b _c)), which _e_v_a_l evaluates.  The value  _a
        !           383:          is returned as the value of (_f_i_r_s_t '(_a _b _c)).  Thus
        !           384:          whenever _e_v_a_l tries to evaluate a  list  whose  car
        !           385:          has  a macro definition it ends up doing (at least)
        !           386:          two operations, the first of which is a call to the
        !           387:          macro  to  let  it  macro  expand the form, and the
        !           388:          other is the evaluation of the result of the macro.
        !           389:          The  result of the macro may be yet another call to
        !           390:          a macro, so _e_v_a_l may have to do even  more  evalua-
        !           391:          tions  until it can finally determine the  value of
        !           392:          an expression.  One way to see  how  a  macro  will
        !           393:          expand  is to use _a_p_p_l_y as shown on the third input
        !           394:          line above.
        !           395: 
        !           396: 
        !           397: 
        !           398:       8.3.2.  defmacro
        !           399: 
        !           400:               The macro _d_e_f_m_a_c_r_o makes it easier  to  define
        !           401:          macros  because it allows you to name the arguments
        !           402:          to the macro call.  For example,  suppose  we  find
        !           403:          ourselves      often      writing     code     like
        !           404:          (_s_e_t_q _s_t_a_c_k (_c_o_n_s _n_e_w_e_l_t _s_t_a_c_k).  We could define a
        !           405:          macro  named  _p_u_s_h  to  do this for us.  One way to
        !           406:          define it is:
        !           407: 
        !           408:          -> (_d_e_f _p_u_s_h
        !           409:                (_m_a_c_r_o (_x) (_l_i_s_t '_s_e_t_q (_c_a_d_d_r _x) (_l_i_s_t '_c_o_n_s (_c_a_d_r _x) (_c_a_d_d_r _x)))))
        !           410:          push
        !           411: 
        !           412:          then (_p_u_s_h _n_e_w_e_l_t _s_t_a_c_k) will expand  to  the  form
        !           413:          mentioned above.  The same macro written using def-
        !           414:          macro would be:
        !           415: 
        !           416:          -> (_d_e_f_m_a_c_r_o _p_u_s_h (_v_a_l_u_e _s_t_a_c_k)
        !           417:            (_l_i_s_t '_s_e_t_q ,_s_t_a_c_k (_l_i_s_t '_c_o_n_s ,_v_a_l_u_e ,_s_t_a_c_k)))
        !           418:          push
        !           419: 
        !           420:          Defmacro allows you to name the  arguments  of  the
        !           421:          macro  call,  and  makes  the macro definition look
        !           422:          more like a function definition.
        !           423: 
        !           424: 
        !           425: 
        !           426: 
        !           427: 9
        !           428: 
        !           429: 9                                     Printed: August 5, 1983
        !           430: 
        !           431: 
        !           432: 
        !           433: 
        !           434: 
        !           435: 
        !           436: 
        !           437: Functions, Fclosures, and Macros                         8-5
        !           438: 
        !           439: 
        !           440:       8.3.3.  the backquote character macro
        !           441: 
        !           442:               The default syntax for  FRANZ  LISP  has  four
        !           443:          characters  with  associated character macros.  One
        !           444:          is semicolon for  comments.   Two  others  are  the
        !           445:          backquote and comma which are used by the backquote
        !           446:          character macro.  The  fourth  is  the  sharp  sign
        !           447:          macro described in the next section.
        !           448: 
        !           449:               The backquote macro is used  to  create  lists
        !           450:          where many of the elements are fixed (quoted). This
        !           451:          makes it very useful  for  creating  macro  defini-
        !           452:          tions.  In the simplest case, a backquote acts just
        !           453:          like a single quote:
        !           454: 
        !           455:          ->`(_a _b _c _d _e)
        !           456:          (a b c d e)
        !           457: 
        !           458:          If a comma precedes an element of a backquoted list
        !           459:          then that element is evaluated and its value is put
        !           460:          in the list.
        !           461: 
        !           462:          ->(_s_e_t_q _d '(_x _y _z))
        !           463:          (x y z)
        !           464:          ->`(_a _b _c ,_d _e)
        !           465:          (a b c (x y z) e)
        !           466: 
        !           467:          If a comma followed by an at sign precedes an  ele-
        !           468:          ment  in  a  backquoted  list, then that element is
        !           469:          evaluated and spliced into the list with _a_p_p_e_n_d.
        !           470: 
        !           471:          ->`(_a _b _c ,@_d _e)
        !           472:          (a b c x y z e)
        !           473: 
        !           474:          Once a list begins with a backquote, the commas may
        !           475:          appear anywhere in the list as this example shows:
        !           476: 
        !           477:          ->`(_a _b (_c _d ,(_c_d_r _d)) (_e _f (_g _h ,@(_c_d_d_r _d) ,@_d)))
        !           478:          (a b (c d (y z)) (e f (g h z x y z)))
        !           479: 
        !           480:          It is also possible and sometimes  even  useful  to
        !           481:          use  the backquote macro within itself.  As a final
        !           482:          demonstration of  the  backquote  macro,  we  shall
        !           483:          define  the  first  and  push  macros using all the
        !           484:          power at our disposal: defmacro and  the  backquote
        !           485:          macro.
        !           486: 
        !           487:          ->(_d_e_f_m_a_c_r_o _f_i_r_s_t (_l_i_s_t) `(_c_a_r ,_l_i_s_t))
        !           488:          first
        !           489:          ->(_d_e_f_m_a_c_r_o _p_u_s_h (_v_a_l_u_e _s_t_a_c_k) `(_s_e_t_q ,_s_t_a_c_k (_c_o_n_s ,_v_a_l_u_e ,_s_t_a_c_k)))
        !           490:          stack
        !           491: 
        !           492: 9
        !           493: 
        !           494: 9                                     Printed: August 5, 1983
        !           495: 
        !           496: 
        !           497: 
        !           498: 
        !           499: 
        !           500: 
        !           501: 
        !           502: Functions, Fclosures, and Macros                         8-6
        !           503: 
        !           504: 
        !           505:       8.3.4.  sharp sign character macro
        !           506: 
        !           507:               The sharp sign macro can perform a  number  of
        !           508:          different  functions   at read time.  The character
        !           509:          directly following the sharp sign determines  which
        !           510:          function  will  be  done,  and  following  Lisp  s-
        !           511:          expressions may serve as arguments.
        !           512: 
        !           513: 
        !           514: 
        !           515:          8.3.4.1.  conditional inclusion
        !           516: 
        !           517:             If you plan to run one source file in more  than
        !           518:             one environment then you may want to some pieces
        !           519:             of code to be included  or not included  depend-
        !           520:             ing  on  the  environment.  The  C language uses
        !           521:             "#ifdef" and "#ifndef"  for  this  purpose,  and
        !           522:             Lisp  uses  "#+" and "#-".  The environment that
        !           523:             the   sharp   sign   macro   checks    is    the
        !           524:             (_s_t_a_t_u_s _f_e_a_t_u_r_e_s) list which is initialized when
        !           525:             the Lisp system  is  built   and  which  may  be
        !           526:             altered     by     (_s_s_t_a_t_u_s _f_e_a_t_u_r_e _f_o_o)     and
        !           527:             (_s_s_t_a_t_u_s _n_o_f_e_a_t_u_r_e _b_a_r) The form  of conditional
        !           528:             inclusion is
        !           529:                         _#_+_w_h_e_n _w_h_a_t
        !           530:             where _w_h_e_n is either a symbol or  an  expression
        !           531:             involving symbols and the functions _a_n_d, _o_r, and
        !           532:             _n_o_t.  The meaning is that _w_h_a_t will only be read
        !           533:             in  if  _w_h_e_n  is true.  A symbol in _w_h_e_n is true
        !           534:             only if  it  appears  in  the  (_s_t_a_t_u_s _f_e_a_t_u_r_e_s)
        !           535:             list.
        !           536: 
        !           537: 
        !           538:     ____________________________________________________
        !           539: 
        !           540:     ; suppose we want to write a program which references a file
        !           541:     ; and which can run at ucb, ucsd and cmu where the file naming conventions
        !           542:     ; are different.
        !           543:     ;
        !           544:     -> (_d_e_f_u_n _h_o_w_o_l_d (_n_a_m_e)
        !           545:           (_t_e_r_p_r)
        !           546:           (_l_o_a_d #+(_o_r _u_c_b _u_c_s_d) "/_u_s_r/_l_i_b/_l_i_s_p/_a_g_e_s._l"
        !           547:                  #+_c_m_u "/_u_s_r/_l_i_s_p/_d_o_c/_a_g_e_s._l")
        !           548:           (_p_a_t_o_m _n_a_m_e)
        !           549:           (_p_a_t_o_m " _i_s ")
        !           550:           (_p_r_i_n_t (_c_d_r (_a_s_s_o_c _n_a_m_e _a_g_e_f_i_l_e)))
        !           551:           (_p_a_t_o_m "_y_e_a_r_s _o_l_d")
        !           552:           (_t_e_r_p_r))
        !           553:     ____________________________________________________
        !           554: 
        !           555: 
        !           556: 
        !           557: The form
        !           558: 
        !           559: 
        !           560:                                      Printed: August 5, 1983
        !           561: 
        !           562: 
        !           563: 
        !           564: 
        !           565: 
        !           566: 
        !           567: 
        !           568: Functions, Fclosures, and Macros                         8-7
        !           569: 
        !           570: 
        !           571:                         _#_-_w_h_e_n _w_h_a_t
        !           572: is equivalent to
        !           573:                      _#_+_(_n_o_t _w_h_e_n_) _w_h_a_t
        !           574: 
        !           575: 
        !           576: 
        !           577:          8.3.4.2.  fixnum character equivalents
        !           578: 
        !           579:             When working with fixnum equivalents of  charac-
        !           580:             ters,  it  is  often hard to remember the number
        !           581:             corresponding to a character.  The form
        !           582:                             _#_/_c
        !           583:             is equivalent to the  fixnum  representation  of
        !           584:             character c.
        !           585: 
        !           586: 
        !           587:     ____________________________________________________
        !           588: 
        !           589:     ; a function which returns t if the user types y else it returns nil.
        !           590:     ;
        !           591:     -> (_d_e_f_u_n _y_e_s_o_r_n_o _n_i_l
        !           592:           (_p_r_o_g_n (_a_n_s)
        !           593:                  (_s_e_t_q _a_n_s (_t_y_i))
        !           594:                  (_c_o_n_d ((_e_q_u_a_l _a_n_s #/_y) _t)
        !           595:                        (_t _n_i_l))))
        !           596:     ____________________________________________________
        !           597: 
        !           598: 
        !           599: 
        !           600: 
        !           601: 
        !           602: 
        !           603:          8.3.4.3.  read time evaluation
        !           604: 
        !           605:             Occasionally you want to express a constant as a
        !           606:             Lisp  expression,  yet you don't want to pay the
        !           607:             penalty of evaluating this expression each  time
        !           608:             it is referenced.  The form
        !           609:                         _#_._e_x_p_r_e_s_s_i_o_n
        !           610:             evaluates  the  expression  at  read  time   and
        !           611:             returns its value.
        !           612: 
        !           613: 
        !           614: 
        !           615: 
        !           616: 
        !           617: 
        !           618: 
        !           619: 
        !           620: 
        !           621: 
        !           622: 
        !           623: 9
        !           624: 
        !           625: 9                                     Printed: August 5, 1983
        !           626: 
        !           627: 
        !           628: 
        !           629: 
        !           630: 
        !           631: 
        !           632: 
        !           633: Functions, Fclosures, and Macros                         8-8
        !           634: 
        !           635: 
        !           636: 
        !           637:     ____________________________________________________
        !           638: 
        !           639:     ; a function to test if any of bits 1 3 or 12 are set in a fixnum.
        !           640:     ;
        !           641:     -> (_d_e_f_u_n _t_e_s_t_i_t (_n_u_m)
        !           642:           (_c_o_n_d ((_z_e_r_o_p (_b_o_o_l_e _1 _n_u_m #.(+ (_l_s_h _1 _1) (_l_s_h _1 _3) (_l_s_h _1 _1_2))))
        !           643:                  _n_i_l)
        !           644:                 (_t _t)))
        !           645:     ____________________________________________________
        !           646: 
        !           647: 
        !           648: 
        !           649: 
        !           650: 
        !           651: 
        !           652:    8.4.  fclosures
        !           653: 
        !           654:            Fclosures are a type of functional  object.   The
        !           655:       purpose  is  to  remember the values of some variables
        !           656:       between invocations of the functional  object  and  to
        !           657:       protect this data from being inadvertently overwritten
        !           658:       by other Lisp  functions.   Fortran  programs  usually
        !           659:       exhibit  this behavior for their variables.  (In fact,
        !           660:       some versions of Fortran would require  the  variables
        !           661:       to  be  in COMMON).  Thus it is easy to write a linear
        !           662:       congruent random number generator in  Fortran,  merely
        !           663:       by keeping the seed as a variable in the function.  It
        !           664:       is much more risky to do so in Lisp, since any special
        !           665:       variable you picked, might be used by some other func-
        !           666:       tion.  Fclosures are an attempt to provide most of the
        !           667:       same  functionality  as closures in Lisp Machine Lisp,
        !           668:       to users of FRANZ LISP.  Fclosures are related to clo-
        !           669:       sures in this way:
        !           670:       (fclosure '(a b) 'foo) <==>
        !           671:               (let ((a a) (b b)) (closure '(a b) 'foo))
        !           672: 
        !           673: 
        !           674: 
        !           675:       8.4.1.  an example
        !           676: 
        !           677: ____________________________________________________________
        !           678: 
        !           679: % lisp
        !           680: Franz Lisp, Opus 38.60
        !           681: ->(defun code (me count)
        !           682:   (print (list 'in x))
        !           683:   (setq x (+ 1 x))
        !           684:   (cond ((greaterp count 1) (funcall me me (sub1 count))))
        !           685:   (print (list 'out x)))
        !           686: code
        !           687: ->(defun tester (object count)
        !           688:   (funcall object object count) (terpri))
        !           689: 
        !           690: 
        !           691:                                      Printed: August 5, 1983
        !           692: 
        !           693: 
        !           694: 
        !           695: 
        !           696: 
        !           697: 
        !           698: 
        !           699: Functions, Fclosures, and Macros                         8-9
        !           700: 
        !           701: 
        !           702: tester
        !           703: ->(setq x 0)
        !           704: 0
        !           705: ->(setq z (fclosure '(x) 'code))
        !           706: fclosure[8]
        !           707: -> (tester z 3)
        !           708: (in 0)(in 1)(in 2)(out 3)(out 3)(out 3)
        !           709: nil
        !           710: ->x
        !           711: 0
        !           712: ____________________________________________________________
        !           713: 
        !           714: 
        !           715: 
        !           716: 
        !           717: 
        !           718:               The function _f_c_l_o_s_u_r_e  creates  a  new  object
        !           719:          that  we  will  call  an  fclosure, (although it is
        !           720:          actually a vector).  The fclosure contains a  func-
        !           721:          tional  object, and a set of symbols and values for
        !           722:          the symbols.  In the above  example,  the  fclosure
        !           723:          functional object is the function code.  The set of
        !           724:          symbols and values just contains the symbol `x' and
        !           725:          zero,  the  value  of  `x'  when  the  fclosure was
        !           726:          created.
        !           727: 
        !           728:          When an fclosure is funcall'ed:
        !           729: 
        !           730:          1)   The Lisp system lambda binds  the  symbols  in
        !           731:               the fclosure to their values in the fclosure.
        !           732: 
        !           733:          2)   It continues the  funcall  on  the  functional
        !           734:               object of the fclosure.
        !           735: 
        !           736:          3)   Finally, it un-lambda binds the symbols in the
        !           737:               fclosure  and  at  the  same  time  stores the
        !           738:               current values of the symbols in the fclosure.
        !           739: 
        !           740: 
        !           741:               Notice that the fclosure is saving  the  value
        !           742:          of  the  symbol  `x'.   Each  time  a  fclosure  is
        !           743:          created, new space  is  allocated  for  saving  the
        !           744:          values  of the symbols. Thus if we execute fclosure
        !           745:          again, over the same  function,  we  can  have  two
        !           746:          independent counters:
        !           747: 
        !           748: ____________________________________________________________
        !           749: 
        !           750: -> (setq zz (fclosure '(x) 'code))
        !           751: fclosure[1]
        !           752: -> (tester zz 2)
        !           753: (in 0)(in 1)(out 2)(out 2)
        !           754: -> (tester zz 2)
        !           755: 
        !           756: 
        !           757:                                      Printed: August 5, 1983
        !           758: 
        !           759: 
        !           760: 
        !           761: 
        !           762: 
        !           763: 
        !           764: 
        !           765: Functions, Fclosures, and Macros                        8-10
        !           766: 
        !           767: 
        !           768: (in 2)(in 3)(out 4)(out 4)
        !           769: -> (tester z 3)
        !           770: (in 3)(in 4)(in 5)(out 6)(out 6)(out 6)
        !           771: ____________________________________________________________
        !           772: 
        !           773: 
        !           774: 
        !           775: 
        !           776: 
        !           777: 
        !           778: 
        !           779:       8.4.2.  useful functions
        !           780: 
        !           781:               Here are some quick some  summaries  of  func-
        !           782:          tions  dealing  with  closures.  They are more for-
        !           783:          mally defined in 2.8.4.  To  recap,  fclosures  are
        !           784:          made by (_f_c_l_o_s_u_r_e '_l__v_a_r_s '_g__f_u_n_c_o_b_j).  l_vars is a
        !           785:          list of symbols (not containing nil), g_funcobj  is
        !           786:          any  object  that can be funcalled.  (Objects which
        !           787:          can be funcalled, include compiled Lisp  functions,
        !           788:          lambda  expressions,  symbols,  foreign  functions,
        !           789:          etc.) In general, if you want a  compiled  function
        !           790:          to  be closed over a variable, you must declare the
        !           791:          variable  to  be  special  within   the   function.
        !           792:          Another example would be:
        !           793: 
        !           794:                      (fclosure '(a b) #'(lambda (x) (plus x a)))
        !           795: 
        !           796:          Here, the #' construction will  make  the  compiler
        !           797:          compile the lambda expression.
        !           798: 
        !           799:               There are times when you want to  share  vari-
        !           800:          ables  between  fclosures.  This can be done if the
        !           801:          fclosures  are  created  at  the  same  time  using
        !           802:          _f_c_l_o_s_u_r_e-_l_i_s_t.  The function _f_c_l_o_s_u_r_e-_a_l_i_s_t returns
        !           803:          an assoc list giving the symbols and values in  the
        !           804:          fclosure.   The  predicate  _f_c_l_o_s_u_r_e_p returns t iff
        !           805:          its  argument  is  a  fclosure.   Other   functions
        !           806:          imported  from  Lisp  Machine  Lisp are _s_y_m_e_v_a_l-_i_n-
        !           807:          _f_c_l_o_s_u_r_e,   _l_e_t-_f_c_l_o_s_e_d,    and    _s_e_t-_i_n-_f_c_l_o_s_u_r_e.
        !           808:          Lastly,  the function _f_c_l_o_s_u_r_e-_f_u_n_c_t_i_o_n returns the
        !           809:          function argument.
        !           810: 
        !           811: 
        !           812: 
        !           813:       8.4.3.  internal structure
        !           814: 
        !           815:               Currently, closures are  implemented  as  vec-
        !           816:          tors, with property being the symbol fclosure.  The
        !           817:          functional object is the first entry.  The  remain-
        !           818:          ing  entries are structures which point to the sym-
        !           819:          bols and values for the closure, (with a  reference
        !           820:          count  to  determine  if  a  recursive  closure  is
        !           821: 
        !           822: 
        !           823:                                      Printed: August 5, 1983
        !           824: 
        !           825: 
        !           826: 
        !           827: 
        !           828: 
        !           829: 
        !           830: 
        !           831: Functions, Fclosures, and Macros                        8-11
        !           832: 
        !           833: 
        !           834:          active).
        !           835: 
        !           836: 
        !           837: 
        !           838:    8.5.  foreign subroutines and functions
        !           839: 
        !           840:            FRANZ LISP has the ability  to  dynamically  load
        !           841:       object  files  produced by other compilers and to call
        !           842:       functions defined in those files.  These functions are
        !           843:       called _f_o_r_e_i_g_n functions.* There are  seven  types  of
        !           844:       foreign functions.  They are characterized by the type
        !           845:       of result they  return,  and  by  differences  in  the
        !           846:       interpretation of their arguments.  They come from two
        !           847:       families: a group  suited  for  languages  which  pass
        !           848:       arguments  by  reference  (e.g.  Fortran), and a group
        !           849:       suited for languages which  pass  arguments  by  value
        !           850:       (e.g. C).
        !           851: 
        !           852: 
        !           853:       There are four types in the first group:
        !           854: 
        !           855:       subroutine
        !           856:            This does not return anything.  The  Lisp  system
        !           857:            always returns t after calling a subroutine.
        !           858: 
        !           859:       function
        !           860:            This returns whatever the function returns.  This
        !           861:            must  be  a valid Lisp object or it may cause the
        !           862:            Lisp system to fail.
        !           863: 
        !           864:       integer-function
        !           865:            This returns an integer  which  the  Lisp  system
        !           866:            makes into a fixnum and returns.
        !           867: 
        !           868:       real-function
        !           869:            This returns a double precision real number which
        !           870:            the Lisp system makes into a flonum and returns.
        !           871: 
        !           872: 
        !           873:       There are three types in the second group:
        !           874: 
        !           875:       c-function
        !           876:            This is like an integer function, except for  its
        !           877:            different interpretation of arguments.
        !           878: 
        !           879: 
        !           880: ____________________
        !           881: 9   *This topic is also discussed in Report  PAM-124  of  the
        !           882: Center  for  Pure  and  Applied  Mathematics,  UCB, entitled
        !           883: ``Parlez-Vous Franz?  An Informal Introduction to  Interfac-
        !           884: ing Foreign Functions to Franz LISP'', by James R. Larus
        !           885: 
        !           886: 
        !           887: 
        !           888: 9                                     Printed: August 5, 1983
        !           889: 
        !           890: 
        !           891: 
        !           892: 
        !           893: 
        !           894: 
        !           895: 
        !           896: Functions, Fclosures, and Macros                        8-12
        !           897: 
        !           898: 
        !           899:       double-c-function
        !           900:            This is like a real-function.
        !           901: 
        !           902:       vector-c-function
        !           903:            This is for C functions which return a structure.
        !           904:            The  first  argument  to such functions must be a
        !           905:            vector (of type vectori), into which  the  result
        !           906:            is  stored.  The second Lisp argument becomes the
        !           907:            first argument to the C function, and so on
        !           908: 
        !           909:       A foreign function is accessed through a binary object
        !           910:       just like a compiled Lisp function.  The difference is
        !           911:       that the discipline field of a  binary  object  for  a
        !           912:       foreign  function is a string whose first character is
        !           913:       given in the following table:
        !           914: 
        !           915: 
        !           916: 8                   ____________________________
        !           917:                     letter         type
        !           918: 8                   ________________________________________________________
        !           919:                       s         subroutine
        !           920: 8                   ____________________________
        !           921:                       f          function
        !           922: 8                   ____________________________
        !           923:                       i      integer-function
        !           924: 8                   ____________________________
        !           925:                       r       real-function.
        !           926: 8                   ____________________________
        !           927:                       c         c-function
        !           928: 8                   ____________________________
        !           929:                       v      vector-c-function
        !           930: 8                   ____________________________
        !           931:                       d      double-c-function
        !           932: 8                   ____________________________
        !           933: 7                  |7|7|7|7|7|7|7|7|7|7|7|
        !           934: 
        !           935: 
        !           936: 
        !           937: 
        !           938: 
        !           939: 
        !           940: 
        !           941: 
        !           942: 
        !           943: 
        !           944:                           |7|7|7|7|7|7|7|7|7|7|7|
        !           945: 
        !           946: 
        !           947: 
        !           948: 
        !           949: 
        !           950: 
        !           951: 
        !           952: 
        !           953: 
        !           954: 
        !           955:                                               |7|7|7|7|7|7|7|7|7|7|7|
        !           956: 
        !           957: 
        !           958: 
        !           959: 
        !           960: 
        !           961: 
        !           962: 
        !           963: 
        !           964: 
        !           965: 
        !           966: 
        !           967: 
        !           968:       Two functions  are  provided  for  setting-up  foreign
        !           969:       functions.   _C_f_a_s_l  loads an object file into the Lisp
        !           970:       system and sets up one foreign function binary object.
        !           971:       If there are more than one function in an object file,
        !           972:       _g_e_t_a_d_d_r_e_s_s can be used to set  up  additional  foreign
        !           973:       function objects.
        !           974: 
        !           975:            Foreign  functions are  called  just  like  other
        !           976:       functions,  e.g  (_f_u_n_n_a_m_e _a_r_g_1 _a_r_g_2).  When a function
        !           977:       in the Fortran group  is  called,  the  arguments  are
        !           978:       evaluated  and  then  examined.  List, hunk and symbol
        !           979:       arguments are passed unchanged to  the  foreign  func-
        !           980:       tion.   Fixnum  and flonum arguments are copied into a
        !           981:       temporary location and  a  pointer  to  the  value  is
        !           982:       passed (this is because Fortran uses call by reference
        !           983:       and it is dangerous to modify the contents of a fixnum
        !           984:       or  flonum  which  something else might point to).  If
        !           985:       the argument is an array object, the data field of the
        !           986:       array  object  is passed to the foreign function (This
        !           987:       is the easiest way to send large amounts  of  data  to
        !           988:       and receive large amounts of data from a foreign func-
        !           989:       tion).  If a binary object is an argument,  the  entry
        !           990: 
        !           991: 
        !           992: 9                                     Printed: August 5, 1983
        !           993: 
        !           994: 
        !           995: 
        !           996: 
        !           997: 
        !           998: 
        !           999: 
        !          1000: Functions, Fclosures, and Macros                        8-13
        !          1001: 
        !          1002: 
        !          1003:       field of that object is passed to the foreign function
        !          1004:       (the entry field is the address of a function, so this
        !          1005:       amounts to passing a function as an argument).
        !          1006: 
        !          1007:            When a function in the C group is called,  fixnum
        !          1008:       and flownum arguments are passed by value.  For almost
        !          1009:       all other arguments, the address is merely provided to
        !          1010:       the  C  routine.   The  only exception arises when you
        !          1011:       want to invoke a C routine which  expects  a  ``struc-
        !          1012:       ture''  argument.  Recall that a (rarely used) feature
        !          1013:       of the C language is the ability to pass structures by
        !          1014:       value.   This  copies  the  structure  onto the stack.
        !          1015:       Since the Franz's nearest equivalent to a C  structure
        !          1016:       is  a  vector, we provide an escape clause to copy the
        !          1017:       contents of an immediate-type vector by value.  If the
        !          1018:       property  field  of  a vectori argument, is the symbol
        !          1019:       "value-structure-argument", then the  binary  data  of
        !          1020:       this immediate-type vector is copied into the argument
        !          1021:       list of the C routine.
        !          1022: 
        !          1023:            The method a foreign function uses to access  the
        !          1024:       arguments   provided  by  Lisp  is  dependent  on  the
        !          1025:       language  of  the  foreign  function.   The  following
        !          1026:       scripts  demonstrate  how  how  Lisp can interact with
        !          1027:       three languages: C, Pascal and Fortran.  C and  Pascal
        !          1028:       have  pointer  types and the first script shows how to
        !          1029:       use pointers to extract information from Lisp objects.
        !          1030:       There  are  two  functions  defined for each language.
        !          1031:       The first (cfoo in C, pfoo in Pascal)  is  given  four
        !          1032:       arguments,  a  fixnum, a flonum-block array, a hunk of
        !          1033:       at least two fixnums and a list of at least  two  fix-
        !          1034:       nums.   To  demonstrate  that  the values were passed,
        !          1035:       each ?foo function prints its arguments (or  parts  of
        !          1036:       them).   The  ?foo  function  then modifies the second
        !          1037:       element of the flonum-block array and returns a  3  to
        !          1038:       Lisp.   The second function (cmemq in C, pmemq in Pas-
        !          1039:       cal) acts just like the Lisp _m_e_m_q function (except  it
        !          1040:       won't work for fixnums whereas the lisp _m_e_m_q will work
        !          1041:       for small fixnums).  In the script, typed input is  in
        !          1042:       bold,  computer output is in roman and comments are in
        !          1043:       _i_t_a_l_i_c.
        !          1044: 
        !          1045: 
        !          1046: ____________________________________________________________
        !          1047: 
        !          1048: _T_h_e_s_e _a_r_e _t_h_e _C _c_o_d_e_d _f_u_n_c_t_i_o_n_s
        !          1049: % cat ch8auxc.c
        !          1050: /* demonstration of c coded foreign integer-function */
        !          1051: 
        !          1052: /* the following will be used to extract fixnums out of a list of fixnums */
        !          1053: struct listoffixnumscell
        !          1054: {    struct listoffixnumscell *cdr;
        !          1055:      int *fixnum;
        !          1056: 
        !          1057: 
        !          1058:                                      Printed: August 5, 1983
        !          1059: 
        !          1060: 
        !          1061: 
        !          1062: 
        !          1063: 
        !          1064: 
        !          1065: 
        !          1066: Functions, Fclosures, and Macros                        8-14
        !          1067: 
        !          1068: 
        !          1069: };
        !          1070: 
        !          1071: struct listcell
        !          1072: {       struct listcell *cdr;
        !          1073:         int car;
        !          1074: };
        !          1075: 
        !          1076: cfoo(a,b,c,d)
        !          1077: int *a;
        !          1078: double b[];
        !          1079: int *c[];
        !          1080: struct listoffixnumscell *d;
        !          1081: {
        !          1082:     printf("a: %d, b[0]: %f, b[1]: %f0, *a, b[0], b[1]);
        !          1083:     printf(" c (first): %d   c (second): %d0,
        !          1084:                *c[0],*c[1]);
        !          1085:     printf(" ( %d %d ... ) ", *(d->fixnum), *(d->cdr->fixnum));
        !          1086:     b[1] = 3.1415926;
        !          1087:     return(3);
        !          1088: }
        !          1089: 
        !          1090: struct listcell *
        !          1091: cmemq(element,list)
        !          1092: int element;
        !          1093: struct listcell *list;
        !          1094: {
        !          1095:    for( ; list && element != list->car ;  list = list->cdr);
        !          1096:    return(list);
        !          1097: }
        !          1098: 
        !          1099: 
        !          1100: _T_h_e_s_e _a_r_e _t_h_e _P_a_s_c_a_l _c_o_d_e_d _f_u_n_c_t_i_o_n_s
        !          1101: % cat ch8auxp.p
        !          1102: type    pinteger = ^integer;
        !          1103:         realarray = array[0..10] of real;
        !          1104:         pintarray = array[0..10] of pinteger;
        !          1105:         listoffixnumscell = record
        !          1106:                                 cdr  : ^listoffixnumscell;
        !          1107:                                 fixnum : pinteger;
        !          1108:                             end;
        !          1109:         plistcell = ^listcell;
        !          1110:         listcell = record
        !          1111:                       cdr : plistcell;
        !          1112:                       car : integer;
        !          1113:                    end;
        !          1114: 
        !          1115: function pfoo ( var a : integer ;
        !          1116:                 var b : realarray;
        !          1117:                 var c : pintarray;
        !          1118:                 var d : listoffixnumscell) : integer;
        !          1119: begin
        !          1120:    writeln(' a:',a, ' b[0]:', b[0], ' b[1]:', b[1]);
        !          1121:    writeln(' c (first):', c[0]^,' c (second):', c[1]^);
        !          1122: 
        !          1123: 
        !          1124:                                      Printed: August 5, 1983
        !          1125: 
        !          1126: 
        !          1127: 
        !          1128: 
        !          1129: 
        !          1130: 
        !          1131: 
        !          1132: Functions, Fclosures, and Macros                        8-15
        !          1133: 
        !          1134: 
        !          1135:    writeln(' ( ', d.fixnum^, d.cdr^.fixnum^, ' ...) ');
        !          1136:    b[1] := 3.1415926;
        !          1137:    pfoo := 3
        !          1138: end ;
        !          1139: 
        !          1140: { the function pmemq looks for the Lisp pointer given as the first argument
        !          1141:   in the list pointed to by the second argument.
        !          1142:   Note that we declare " a : integer " instead of " var a : integer " since
        !          1143:   we are interested in the pointer value instead of what it points to (which
        !          1144:   could be any Lisp object)
        !          1145: }
        !          1146: function pmemq( a : integer; list : plistcell) : plistcell;
        !          1147: begin
        !          1148:  while (list <> nil) and (list^.car <> a) do list := list^.cdr;
        !          1149:  pmemq := list;
        !          1150: end ;
        !          1151: 
        !          1152: 
        !          1153: _T_h_e _f_i_l_e_s _a_r_e _c_o_m_p_i_l_e_d
        !          1154: % cc -c ch8auxc.c
        !          1155: 1.0u 1.2s 0:15 14% 30+39k 33+20io 147pf+0w
        !          1156: % pc -c ch8auxp.p
        !          1157: 3.0u 1.7s 0:37 12% 27+32k 53+32io 143pf+0w
        !          1158: 
        !          1159: 
        !          1160: % lisp
        !          1161: Franz Lisp, Opus 38.60
        !          1162: _F_i_r_s_t _t_h_e _f_i_l_e_s _a_r_e _l_o_a_d_e_d _a_n_d _w_e _s_e_t _u_p _o_n_e  _f_o_r_e_i_g_n  _f_u_n_c_-
        !          1163: _t_i_o_n  _b_i_n_a_r_y.  _W_e _h_a_v_e _t_w_o _f_u_n_c_t_i_o_n_s _i_n _e_a_c_h _f_i_l_e _s_o _w_e _m_u_s_t
        !          1164: _c_h_o_o_s_e _o_n_e _t_o _t_e_l_l _c_f_a_s_l _a_b_o_u_t.  _T_h_e _c_h_o_i_c_e _i_s _a_r_b_i_t_r_a_r_y.
        !          1165: -> (cfasl 'ch8auxc.o '_cfoo 'cfoo "integer-function")
        !          1166: /usr/lib/lisp/nld -N -A /usr/local/lisp -T 63000 ch8auxc.o -e _cfoo -o /tmp/Li7055.0  -lc
        !          1167: #63000-"integer-function"
        !          1168: -> (cfasl 'ch8auxp.o '_pfoo 'pfoo "integer-function" "-lpc")
        !          1169: /usr/lib/lisp/nld -N -A /tmp/Li7055.0 -T 63200 ch8auxp.o -e _pfoo -o /tmp/Li7055.1 -lpc -lc
        !          1170: #63200-"integer-function"
        !          1171: _H_e_r_e _w_e _s_e_t _u_p _t_h_e _o_t_h_e_r _f_o_r_e_i_g_n _f_u_n_c_t_i_o_n _b_i_n_a_r_y _o_b_j_e_c_t_s
        !          1172: -> (getaddress '_cmemq 'cmemq "function" '_pmemq 'pmemq "function")
        !          1173: #6306c-"function"
        !          1174: _W_e _w_a_n_t _t_o _c_r_e_a_t_e _a_n_d _i_n_i_t_i_a_l_i_z_e _a_n _a_r_r_a_y  _t_o  _p_a_s_s  _t_o  _t_h_e
        !          1175: _c_f_o_o  _f_u_n_c_t_i_o_n.  _I_n _t_h_i_s _c_a_s_e _w_e _c_r_e_a_t_e _a_n _u_n_n_a_m_e_d _a_r_r_a_y _a_n_d
        !          1176: _s_t_o_r_e _i_t _i_n _t_h_e _v_a_l_u_e _c_e_l_l _o_f _t_e_s_t_a_r_r.  _W_h_e_n  _w_e  _c_r_e_a_t_e  _a_n
        !          1177: _a_r_r_a_y  _t_o  _p_a_s_s  _t_o  _t_h_e  _P_a_s_c_a_l _p_r_o_g_r_a_m _w_e _w_i_l_l _u_s_e _a _n_a_m_e_d
        !          1178: _a_r_r_a_y _j_u_s_t _t_o _d_e_m_o_n_s_t_r_a_t_e _t_h_e _d_i_f_f_e_r_e_n_t _w_a_y _t_h_a_t  _n_a_m_e_d  _a_n_d
        !          1179: _u_n_n_a_m_e_d _a_r_r_a_y_s _a_r_e _c_r_e_a_t_e_d _a_n_d _a_c_c_e_s_s_e_d.
        !          1180: -> (setq testarr (array nil flonum-block 2))
        !          1181: array[2]
        !          1182: -> (store (funcall testarr 0) 1.234)
        !          1183: 1.234
        !          1184: -> (store (funcall testarr 1) 5.678)
        !          1185: 5.678
        !          1186: -> (cfoo 385 testarr (hunk 10 11 13 14) '(15 16 17))
        !          1187: a: 385, b[0]: 1.234000, b[1]: 5.678000
        !          1188: 
        !          1189: 
        !          1190:                                      Printed: August 5, 1983
        !          1191: 
        !          1192: 
        !          1193: 
        !          1194: 
        !          1195: 
        !          1196: 
        !          1197: 
        !          1198: Functions, Fclosures, and Macros                        8-16
        !          1199: 
        !          1200: 
        !          1201:  c (first): 10   c (second): 11
        !          1202:  ( 15 16 ... )
        !          1203:  3
        !          1204: _N_o_t_e _t_h_a_t _c_f_o_o _h_a_s _r_e_t_u_r_n_e_d _3 _a_s _i_t _s_h_o_u_l_d.  _I_t _a_l_s_o _h_a_d _t_h_e
        !          1205: _s_i_d_e  _e_f_f_e_c_t  _o_f  _c_h_a_n_g_i_n_g  _t_h_e _s_e_c_o_n_d _v_a_l_u_e _o_f _t_h_e _a_r_r_a_y _t_o
        !          1206: _3._1_4_1_5_9_2_6  _w_h_i_c_h _c_h_e_c_k _n_e_x_t.
        !          1207: -> (funcall testarr 1)
        !          1208: 3.1415926
        !          1209: 
        !          1210: 
        !          1211: _I_n _p_r_e_p_a_r_a_t_i_o_n _f_o_r _c_a_l_l_i_n_g _p_f_o_o _w_e _c_r_e_a_t_e _a_n _a_r_r_a_y.
        !          1212: -> (array test flonum-block 2)
        !          1213: array[2]
        !          1214: -> (store (test 0) 1.234)
        !          1215: 1.234
        !          1216: -> (store (test 1) 5.678)
        !          1217: 5.678
        !          1218: -> (pfoo 385 (getd 'test) (hunk 10 11 13 14) '(15 16 17))
        !          1219:  a:       385 b[0]:  1.23400000000000E+00 b[1]:  5.67800000000000E+00
        !          1220:  c (first):        10 c (second):        11
        !          1221:  (         15        16 ...)
        !          1222: 3
        !          1223: -> (test 1)
        !          1224: 3.1415926
        !          1225: 
        !          1226:  _N_o_w _t_o _t_e_s_t _o_u_t _t_h_e _m_e_m_q'_s
        !          1227: -> (cmemq 'a '(b c a d e f))
        !          1228: (_a _d _e _f)
        !          1229: -> (pmemq 'e '(a d f g a x))
        !          1230: _n_i_l
        !          1231: ____________________________________________________________
        !          1232: 
        !          1233: 
        !          1234: 
        !          1235: 
        !          1236: 
        !          1237:            The Fortran example will be much shorter since in
        !          1238:       Fortran  you can't follow pointers as you can in other
        !          1239:       languages.  The Fortran function ffoo is  given  three
        !          1240:       arguments:  a  fixnum, a fixnum-block array and a flo-
        !          1241:       num.  These arguments are printed out to  verify  that
        !          1242:       they  made it and then the first value of the array is
        !          1243:       modified.  The function  returns  a  double  precision
        !          1244:       value  which  is  converted  to  a  flonum by lisp and
        !          1245:       printed.  Note that the entry point  corresponding  to
        !          1246:       the  Fortran function ffoo is _ffoo_ as opposed to the
        !          1247:       C and Pascal convention of preceding the name with  an
        !          1248:       underscore.
        !          1249: 
        !          1250: ____________________________________________________________
        !          1251: 
        !          1252: 
        !          1253: % cat ch8auxf.f
        !          1254: 
        !          1255: 
        !          1256:                                      Printed: August 5, 1983
        !          1257: 
        !          1258: 
        !          1259: 
        !          1260: 
        !          1261: 
        !          1262: 
        !          1263: 
        !          1264: Functions, Fclosures, and Macros                        8-17
        !          1265: 
        !          1266: 
        !          1267:         double precision function ffoo(a,b,c)
        !          1268:         integer a,b(10)
        !          1269:         double precision c
        !          1270:         print 2,a,b(1),b(2),c
        !          1271: 2       format(' a=',i4,', b(1)=',i5,', b(2)=',i5,' c=',f6.4)
        !          1272:         b(1) = 22
        !          1273:         ffoo = 1.23456
        !          1274:         return
        !          1275:         end
        !          1276: % f77 -c ch8auxf.f
        !          1277: ch8auxf.f:
        !          1278:    ffoo:
        !          1279: 0.9u 1.8s 0:12 22% 20+22k 54+48io 158pf+0w
        !          1280: % lisp
        !          1281: Franz Lisp, Opus 38.60
        !          1282: -> (cfasl 'ch8auxf.o '_ffoo_ 'ffoo "real-function" "-lF77 -lI77")
        !          1283: /usr/lib/lisp/nld -N -A /usr/local/lisp -T 63000 ch8auxf.o -e _ffoo_
        !          1284: -o /tmp/Li11066.0 -lF77 -lI77 -lc
        !          1285: #6307c-"real-function"
        !          1286: 
        !          1287: -> (array test fixnum-block 2)
        !          1288: array[2]
        !          1289: -> (store (test 0) 10)
        !          1290: 10
        !          1291: -> (store (test 1) 11)
        !          1292: 11
        !          1293: -> (ffoo 385 (getd 'test) 5.678)
        !          1294:  a= 385, b(1)=   10, b(2)=   11 c=5.6780
        !          1295: 1.234559893608093
        !          1296: -> (test 0)
        !          1297: 22
        !          1298: 
        !          1299: ____________________________________________________________
        !          1300: 
        !          1301: 
        !          1302: 
        !          1303: 
        !          1304: 
        !          1305: 
        !          1306: 
        !          1307: 
        !          1308: 
        !          1309: 
        !          1310: 
        !          1311: 
        !          1312: 
        !          1313: 
        !          1314: 
        !          1315: 
        !          1316: 
        !          1317: 
        !          1318: 
        !          1319: 9
        !          1320: 
        !          1321: 9                                     Printed: August 5, 1983
        !          1322: 
        !          1323: 
        !          1324: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.