4.1cBSD/usr/src/ucb/lisp/lisplib/manual/ch8.r








                         CCCCHHHHAAAAPPPPTTTTEEEERRRR  8888


                    FFFFuuuunnnnccccttttiiiioooonnnnssss aaaannnndddd MMMMaaaaccccrrrroooossss







8888....1111....  vvvvaaaalllliiiidddd ffffuuuunnnnccccttttiiiioooonnnn oooobbbbjjjjeeeeccccttttssss

     There are many different objects which can  occupy  the
function  field  of  a  symbol  object.  The following table
shows all of the possibilities, how to  recognize  them  and
where to look for documentation.


8_____________________________________________________________
  informal name           object type         documentation
8__________________________________________________________________________________________________________________________
   interpreted           list with _c_a_r             8.2
 lambda function         _e_q to lambda
8_____________________________________________________________
   interpreted           list with _c_a_r             8.2
 nlambda function        _e_q to nlambda
8_____________________________________________________________
   interpreted           list with _c_a_r             8.2
  lexpr function          _e_q to lexpr
8_____________________________________________________________
   interpreted           list with _c_a_r             8.3
      macro               _e_q to macro
8_____________________________________________________________
     compiled       binary with discipline         8.2
 lambda or lexpr         _e_q to lambda
     function
8_____________________________________________________________
     compiled       binary with discipline         8.2
 nlambda function        _e_q to nlambda
8_____________________________________________________________
     compiled       binary with discipline         8.3
      macro               _e_q to macro
8_____________________________________________________________
     foreign        binary with discipline         8.4
    subroutine         of "subroutine"[]
8_____________________________________________________________
     foreign        binary with discipline         8.4
     function           of "function"[]
8_____________________________________________________________
     foreign        binary with discipline         8.4
 integer function   of "integer-function"[]
8_____________________________________________________________
     foreign        binary with discipline         8.4
  real function      of "real-function"[]
8_____________________________________________________________
      array              array object               9
8_____________________________________________________________
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|





























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|





























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|





























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|































99

9FFFFuuuunnnnccccttttiiiioooonnnnssss aaaannnndddd MMMMaaaaccccrrrroooossss                                     8888----1111







FFFFuuuunnnnccccttttiiiioooonnnnssss aaaannnndddd MMMMaaaaccccrrrroooossss                                     8888----2222


8888....2222....  ffffuuuunnnnccccttttiiiioooonnnnssss

     The basic lisp function is the lambda function.  When a
lambda   function   is  called,  the  actual  arguments  are
evaluated from left to right and  are  lambda-bound  to  the
formal parameters of the lambda function.

     An nlambda function is usually used for functions which
are  invoked  by the user at top level.  Some built-in func-
tions which evaluate their arguments  in  special  ways  are
also  nlambdas (e.g _c_o_n_d, _d_o, _o_r).  When an nlambda function
is called, the list of unevaluated arguments is lambda bound
to the single formal parameter of the nlambda function.

     Some programmers will use an nlambda function when they
are  not  sure  how many arguments will be passed.  Then the
first thing the nlambda function does is map _e_v_a_l  over  the
list  of  unevaluated arguments it has been passed.  This is
usually the wrong thing to do as it won't work  compiled  if
any of the arguments are local variables. The solution is to
use a lexpr.  When a lexpr function is called, the arguments
are  evaluated  and  a  fixnum  whose value is the number of
arguments is lambda-bound to the single formal parameter  of
the  lexpr  function.  The lexpr then accesses the arguments
using the _a_r_g function.

     When a function is compiled, _s_p_e_c_i_a_l  declarations  may
be  needed  to  preserve  its  behavior.  An argument is not
lambda-bound to the name of the corresponding formal parame-
ter  unless  that formal parameter has been declared _s_p_e_c_i_a_l
(see 12.3.2.2).

     Lambda and lexpr functions both compile into  a  binary
object  with  a  discipline  of lambda.  However, a compiled
lexpr still acts like an interpreted lexpr.




8888....3333....  mmmmaaaaccccrrrroooossss

     An important features of Lisp is its ability to manipu-
late  programs  as  data.   As  a  result of this, most Lisp
implementations have very powerful  macro  facilities.   The
Lisp  language's  macro  facility can be used to incorporate
popular features of the  other  languages  into  Lisp.   For
example,  there are macro packages which allow one to create
records (ala Pascal) and refer to elements of those  records
____________________
9   []Only the first character of the string  is  significant
(i.e "s" is ok for "subroutine")



9                                     Printed: March 23, 1982







FFFFuuuunnnnccccttttiiiioooonnnnssss aaaannnndddd MMMMaaaaccccrrrroooossss                                     8888----3333


by the key names.[] Another  popular use for  macros  is  to
create  more  readable  control structures which expand into
_c_o_n_d, _o_r and _a_n_d.  One such example is the If macro  in  the
jkfmacs.l package.  It allows you to write

(_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)
 _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)
 _e_l_s_e (_p_r_i_n_t '|_I _g_i_v_e _u_p|))

which expands to

(_c_o_n_d
    ((_e_q_u_a_l _n_u_m_b _0) (_p_r_i_n_t '_z_e_r_o) (_t_e_r_p_r))
    ((_e_q_u_a_l _n_u_m_b _1) (_p_r_i_n_t '_o_n_e) (_t_e_r_p_r))
    (_t (_p_r_i_n_t '|_I _g_i_v_e _u_p|)))





8888....3333....1111....  mmmmaaaaccccrrrroooo ffffoooorrrrmmmmssss

     A macro is a function which accepts a  Lisp  expression
as  input  and  returns another Lisp expression.  The action
the macro takes is called macro expansion.  Here is a simple
example:

-> (_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))))
first
-> (_f_i_r_s_t '(_a _b _c))
a
-> (_a_p_p_l_y '_f_i_r_s_t '(_f_i_r_s_t '(_a _b _c)))
(car '(a b c))

The first input line defines a macro called  _f_i_r_s_t.   Notice
that  the  macro  has one formal parameter, _x. On the second
input   line,   we   ask   the   interpreter   to   evaluate
(_f_i_r_s_t '(_a _b _c)).   _E_v_a_l  sees  that  _f_i_r_s_t  has  a function
definition of type macro  so it evaluates _f_i_r_s_t's definition
passing  to  _f_i_r_s_t  as  an argument the form _e_v_a_l itself was
trying to evaluate: (_f_i_r_s_t '(_a _b _c)).  The _f_i_r_s_t macro chops
off  the  car  of  the argument with _c_d_r, cons' a _c_a_r at the
beginning of the list and returns (_c_a_r '(_a _b _c)).  Now  _e_v_a_l
evaluates  that, and the value is _a which is returned as the
value of (_f_i_r_s_t '(_a _b _c)).   Thus  whenever  _e_v_a_l  tries  to
evaluate  a list whose car has a macro definition it ends up
doing (at least) two operations, one is a call to the  macro
____________________
9   []A record definition macro package especially suited for
FRANZ  LISP  is in the planning stages at Berkeley.  At this
time the Maclisp _s_t_r_u_c_t package can be used.



9                                     Printed: March 23, 1982







FFFFuuuunnnnccccttttiiiioooonnnnssss aaaannnndddd MMMMaaaaccccrrrroooossss                                     8888----4444


to let it macro expand  the  form,  and  the  other  is  the
evaluation  of  the  result of the macro.  The result of the
macro may be yet another call to a macro, so _e_v_a_l  may  have
to  do  even more evaluations until it can finally determine
the  value of an expression.  One way to  see  how  a  macro
will expand is to use _a_p_p_l_y as shown on the third input line
above.




8888....3333....2222....  ddddeeeeffffmmmmaaaaccccrrrroooo

     The macro _d_e_f_m_a_c_r_o makes it  easier  to  define  macros
because  it  allows  you  to name the arguments to the macro
call.  For example, suppose we find ourselves often  writing
code  like (_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 macro named _p_u_s_h to do this for us.  One way to define  it
is:

-> (_d_e_f _p_u_s_h
      (_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)))))
push

then (_p_u_s_h _n_e_w_e_l_t _s_t_a_c_k) will expand to the  form  mentioned
above.  The same macro written using defmacro would be:

-> (_d_e_f_m_a_c_r_o _p_u_s_h (_v_a_l_u_e _s_t_a_c_k) (_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))
push

Defmacro allows you to name the arguments of the macro call,
and  makes  the  macro  definition look more like a function
definition.




8888....3333....3333....  tttthhhheeee bbbbaaaacccckkkkqqqquuuuooootttteeee cccchhhhaaaarrrraaaacccctttteeeerrrr mmmmaaaaccccrrrroooo

     The default syntax for FRANZ LISP has four   characters
with associated character macros.  One is semicolon for com-
ments.  Two others are the backquote  and  comma  which  are
used  by  the  backquote character macro.  The fourth is the
sharp sign macro described in the next section.

     The backquote macro is used to create lists where  many
of  the elements are fixed (quoted). This makes it very use-
ful for creating macro definitions.  In the simplest case, a
backquote acts just like a single quote:

->`(_a _b _c _d _e)
(a b c d e)
9

9                                     Printed: March 23, 1982







FFFFuuuunnnnccccttttiiiioooonnnnssss aaaannnndddd MMMMaaaaccccrrrroooossss                                     8888----5555


If a comma precedes an element of  a  backquoted  list  then
that element is evaluated and its value is put in the list.

->(_s_e_t_q _d '(_x _y _z))
(x y z)
->`(_a _b _c ,_d _e)
(a b c (x y z) e)

If a comma followed by an at sign precedes an element  in  a
backquoted  list, then that element is evaluated and spliced
into the list with _a_p_p_e_n_d.

->`(_a _b _c ,@_d _e)
(a b c x y z e)

Once a list begins with a backquote, the commas  may  appear
anywhere in the list as this example shows:

->`(_a _b (_c _d ,(_c_d_r _d)) (_e _f (_g _h ,@(_c_d_d_r _d) ,@_d)))
(a b (c d (y z)) (e f (g h z x y z)))

It is also possible and sometimes even  useful  to  use  the
backquote  macro within itself.  As a final demonstration of
the backquote macro, we shall define the first and push mac-
ros  using  all  the power at our disposal, defmacro and the
backquote macro.

->(_d_e_f_m_a_c_r_o _f_i_r_s_t (_l_i_s_t) `(_c_a_r ,_l_i_s_t))
first
->(_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)))
stack




8888....3333....4444....  sssshhhhaaaarrrrpppp ssssiiiiggggnnnn cccchhhhaaaarrrraaaacccctttteeeerrrr mmmmaaaaccccrrrroooo

     The sharp sign macro can perform a number of  different
functions   at  read time.  The character directly following
the sharp sign determines which function will be  done,  and
following lisp s-expressions may serve as arguments.




8888....3333....4444....1111....  ccccoooonnnnddddiiiittttiiiioooonnnnaaaallll iiiinnnncccclllluuuussssiiiioooonnnn

If you plan to run one source file in more than one environ-
ment then you may want to some pieces of code to be included
or not included depending on the environment. The C language
uses  "#ifdef" and "#ifndef" for this purpose, and lisp uses
"#+" and "#-".  The environment that the  sharp  sign  macro
checks  is  the  (_s_t_a_t_u_s _f_e_a_t_u_r_e_s) list which is initialized


                                     Printed: March 23, 1982







FFFFuuuunnnnccccttttiiiioooonnnnssss aaaannnndddd MMMMaaaaccccrrrroooossss                                     8888----6666


when the Lisp system is built  and which may be  altered  by
(_s_s_t_a_t_u_s _f_e_a_t_u_r_e _f_o_o)  and  (_s_s_t_a_t_u_s _n_o_f_e_a_t_u_r_e _b_a_r) The form
of conditional inclusion is
                        _#_+_w_h_e_n _w_h_a_t
where _w_h_e_n is either a symbol  or  an  expression  involving
symbols  and the functions _a_n_d, _o_r, and _n_o_t.  The meaning is
that _w_h_a_t will only be read in if _w_h_e_n is true.  A symbol in
_w_h_e_n  is  true  only  if it appears in the (_s_t_a_t_u_s _f_e_a_t_u_r_e_s)
list.


    ____________________________________________________

    ; suppose we want to write a program which references a file
    ; and which can run at ucb, ucsd and cmu where the file naming conventions
    ; are different.
    ;
    -> (_d_e_f_u_n _h_o_w_o_l_d (_n_a_m_e)
          (_t_e_r_p_r)
          (_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"
                 #+_c_m_u "/_u_s_r/_l_i_s_p/_d_o_c/_a_g_e_s._l")
          (_p_a_t_o_m "_H_e _i_s ")
          (_p_r_i_n_t (_c_d_r (_a_s_s_o_c _n_a_m_e _a_g_e_f_i_l_e)))
          (_p_a_t_o_m "_y_e_a_r_s _o_l_d")
          (_t_e_r_p_r))
    ____________________________________________________



The form
                        _#_-_w_h_e_n _w_h_a_t
is equivalent to
                     _#_+_(_n_o_t _w_h_e_n_) _w_h_a_t




8888....3333....4444....2222....  ffffiiiixxxxnnnnuuuummmm cccchhhhaaaarrrraaaacccctttteeeerrrr eeeeqqqquuuuiiiivvvvaaaalllleeeennnnttttssss

When working with fixnum equivalents  of  characters  it  is
often hard to remember the number corresponding to a charac-
ter.  The form
                            _#_/_c
is equivalent to the fixnum representation of character c.








9

9                                     Printed: March 23, 1982







FFFFuuuunnnnccccttttiiiioooonnnnssss aaaannnndddd MMMMaaaaccccrrrroooossss                                     8888----7777



    ____________________________________________________

    ; a function  which returns t if the user types y else it returns nil.
    ;
    -> (_d_e_f_u_n _y_e_s_o_r_n_o _n_i_l
          (_p_r_o_g_n (_a_n_s)
                 (_s_e_t_q _a_n_s (_t_y_i))
                 (_c_o_n_d ((_e_q_u_a_l _a_n_s #/_y) _t)
                       (_t _n_i_l))))
    ____________________________________________________







8888....3333....4444....3333....  rrrreeeeaaaadddd ttttiiiimmmmeeee eeeevvvvaaaalllluuuuaaaattttiiiioooonnnn

Occasionally you want  to  express  a  constant  as  a  lisp
expression,  yet  you  don't  want  to  pay  the  penalty of
evaluating this expression each time it is referenced.   The
form
                        _#_._e_x_p_r_e_s_s_i_o_n
evaluates the expression at read time and returns its value.


    ____________________________________________________

    ; a function to test if any of bits 1 3 or 12 are set in a fixnum.
    ;
    -> (_d_e_f_u_n _t_e_s_t_i_t (_n_u_m)
          (_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))))
                 _n_i_l)
                (_t _t)))
    ____________________________________________________







8888....4444....  ffffoooorrrreeeeiiiiggggnnnn ssssuuuubbbbrrrroooouuuuttttiiiinnnneeeessss aaaannnndddd ffffuuuunnnnccccttttiiiioooonnnnssss

     FRANZ LISP has the ability to dynamically  load  object
files  produced  by  other compilers and then call functions
defined in those files.  These functions are called  _f_o_r_e_i_g_n
functions.   There  are  four types of foreign functions and
they are characterized by the type of result they return:

9

9                                     Printed: March 23, 1982







FFFFuuuunnnnccccttttiiiioooonnnnssss aaaannnndddd MMMMaaaaccccrrrroooossss                                     8888----8888


subroutine
     This does not return anything. The lisp  system  always
     returns t after calling a subroutine.

function
     This returns whatever the function returns.  This  must
     be  a valid lisp object or it may cause the lisp system
     to fail.

integer-function
     This returns an integer which  the  lisp  system  makes
     into a fixnum and returns.

real-function
     This returns a double precision real number  which  the
     lisp system makes into a flonum and returns.

A foreign function is accessed through a binary object  just
like  a  compiled lisp function.  The difference is that the
discipline field for a binary object of a  foreign  function
is  a string whose first character is either s for a subrou-
tine, f for a function, i for an integer-function or r for a
real-function.   Two  functions are provided for the setting
up of foreign functions.  _C_f_a_s_l loads an  object  file  into
the  lisp  system  and  sets  up one foreign function binary
object.  If there is more than one  function  in  an  object
file, _g_e_t_a_d_d_r_e_s_s can be used to set up further foreign func-
tion objects.

     Foreign  functions are called  just  like  other  func-
tions,  e.g  (_f_u_n_n_a_m_e _a_r_g_1 _a_r_g_2).   When  one is called, the
arguments are evaluated and then examined.  List,  hunk  and
symbol  arguments  are passed unchanged to the foreign func-
tion.  Fixnum and flonum arguments are copied  into  a  tem-
porary  location  and a pointer to the value is passed (this
is  because  Fortran  uses  call  by  reference  and  it  is
dangerous to modify the contents of a fixnum or flonum which
something else might point to).  If an array  object  is  an
argument  the  data  field of the array  object is passed to
the foreign function (this is the easiest way to send  large
amounts  of data to and receive large amounts of data from a
foreign function).  If a binary object is an  argument,  the
entry field of that object is passed to the foreign function
(the entry field is the  address  of  a  function,  so  this
amounts to passing a function as an argument).

     The method a foreign function uses to access the  argu-
ments  provided  by lisp is dependent on the language of the
foreign function.  The following scripts demonstrate how how
lisp  can  interact with three languages: C, Pascal and For-
tran.  C and Pascal have pointer types and the first  script
shows  how  to use pointers to extract information from lisp
objects.  There are two functions defined for each language.


                                     Printed: March 23, 1982







FFFFuuuunnnnccccttttiiiioooonnnnssss aaaannnndddd MMMMaaaaccccrrrroooossss                                     8888----9999


The  first  (cfoo  in C, pfoo in Pascal) is given four argu-
ments, a fixnum, a flonum-block array, a hunk  of  at  least
two  fixnums  and a list of at least two fixnums.  To demon-
strate that the  values  were  passed,  each  ?foo  function
prints  its arguments (or parts of them).  The ?foo function
then modifies the second element of the  flonum-block  array
and  returns  a 3 to lisp.  The second function (cmemq in C,
pmemq in Pascal) acts  just  like  the  lisp  _m_e_m_q  function
(except it won't work for fixnums whereas the lisp _m_e_m_q will
work for small fixnums).  In the script, typed input  is  in
bbbboooolllldddd,  computer  output  is  in  roman  and  comments are in
_i_t_a_l_i_c.


____________________________________________________________

_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
% ccccaaaatttt cccchhhh8888aaaauuuuxxxxcccc....cccc
/* demonstration of c coded foreign integer-function */

/* the following will be used to extract fixnums out of a list of fixnums */
struct listoffixnumscell
{    struct listoffixnumscell *cdr;
     int *fixnum;
};

struct listcell
{       struct listcell *cdr;
        int car;
};

cfoo(a,b,c,d)
int *a;
double b[];
int *c[];
struct listoffixnumscell *d;
{
    printf("a: %d, b[0]: %f, b[1]: %f0, *a, b[0], b[1]);
    printf(" c (first): %d   c (second): %d0,
               *c[0],*c[1]);
    printf(" ( %d %d ... ) ", *(d->fixnum), *(d->cdr->fixnum));
    b[1] = 3.1415926;
    return(3);
}

struct listcell *
cmemq(element,list)
int element;
struct listcell *list;
{
   for( ; list && element != list->car ;  list = list->cdr);
   return(list);
}


                                     Printed: March 23, 1982







FFFFuuuunnnnccccttttiiiioooonnnnssss aaaannnndddd MMMMaaaaccccrrrroooossss                                    8888----11110000


_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
% ccccaaaatttt cccchhhh8888aaaauuuuxxxxpppp....pppp
type    pinteger = ^integer;
        realarray = array[0..10] of real;
        pintarray = array[0..10] of pinteger;
        listoffixnumscell = record
                                cdr  : ^listoffixnumscell;
                                fixnum : pinteger;
                            end;
        plistcell = ^listcell;
        listcell = record
                      cdr : plistcell;
                      car : integer;
                   end;

function pfoo ( var a : integer ;
                var b : realarray;
                var c : pintarray;
                var d : listoffixnumscell) : integer;
begin
   writeln(' a:',a, ' b[0]:', b[0], ' b[1]:', b[1]);
   writeln(' c (first):', c[0]^,' c (second):', c[1]^);
   writeln(' ( ', d.fixnum^, d.cdr^.fixnum^, ' ...) ');
   b[1] := 3.1415926;
   pfoo := 3
end ;

{ the function pmemq looks for the lisp pointer given as the first argument
  in the list pointed to by the second argument.
  Note that we declare " a : integer " instead of " var a : integer " since
  we are interested in the pointer value instead of what it points to (which
  could be any lisp object)
}
function pmemq( a : integer; list : plistcell) : plistcell;
begin
 while (list <> nil) and (list^.car <> a) do list := list^.cdr;
 pmemq := list;
end ;


_T_h_e _f_i_l_e_s _a_r_e _c_o_m_p_i_l_e_d
% cccccccc ----cccc cccchhhh8888aaaauuuuxxxxcccc....cccc
1.0u 1.2s 0:15 14% 30+39k 33+20io 147pf+0w
% ppppcccc ----cccc cccchhhh8888aaaauuuuxxxxpppp....pppp
3.0u 1.7s 0:37 12% 27+32k 53+32io 143pf+0w


% lllliiiisssspppp
Franz Lisp, Opus 33b
_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_-
_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
_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.
-> ((((ccccffffaaaassssllll ''''cccchhhh8888aaaauuuuxxxxcccc....oooo ''''____ccccffffoooooooo ''''ccccffffoooooooo """"iiiinnnntttteeeeggggeeeerrrr----ffffuuuunnnnccccttttiiiioooonnnn""""))))


                                     Printed: March 23, 1982







FFFFuuuunnnnccccttttiiiioooonnnnssss aaaannnndddd MMMMaaaaccccrrrroooossss                                    8888----11111111


/usr/lib/lisp/nld -N -A /usr/local/lisp -T 63000 ch8auxc.o -e _cfoo -o /tmp/Li7055.0  -lc
#63000-"integer-function"
-> ((((ccccffffaaaassssllll ''''cccchhhh8888aaaauuuuxxxxpppp....oooo ''''____ppppffffoooooooo ''''ppppffffoooooooo """"iiiinnnntttteeeeggggeeeerrrr----ffffuuuunnnnccccttttiiiioooonnnn"""" """"----llllppppcccc""""))))
/usr/lib/lisp/nld -N -A /tmp/Li7055.0 -T 63200 ch8auxp.o -e _pfoo -o /tmp/Li7055.1 -lpc -lc
#63200-"integer-function"
_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
-> ((((ggggeeeettttaaaaddddddddrrrreeeessssssss ''''____ccccmmmmeeeemmmmqqqq ''''ccccmmmmeeeemmmmqqqq """"ffffuuuunnnnccccttttiiiioooonnnn"""" ''''____ppppmmmmeeeemmmmqqqq ''''ppppmmmmeeeemmmmqqqq """"ffffuuuunnnnccccttttiiiioooonnnn""""))))
#6306c-"function"
_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
_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
_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
_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
_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
_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.
-> ((((sssseeeettttqqqq tttteeeessssttttaaaarrrrrrrr ((((aaaarrrrrrrraaaayyyy nnnniiiillll fffflllloooonnnnuuuummmm----bbbblllloooocccckkkk 2222))))))))
array[2]
-> ((((ssssttttoooorrrreeee ((((ffffuuuunnnnccccaaaallllllll tttteeeessssttttaaaarrrrrrrr 0000)))) 1111....222233334444))))
1.234
-> ((((ssssttttoooorrrreeee ((((ffffuuuunnnnccccaaaallllllll tttteeeessssttttaaaarrrrrrrr 1111)))) 5555....666677778888))))
5.678
-> ((((ccccffffoooooooo 333388885555 tttteeeessssttttaaaarrrrrrrr ((((hhhhuuuunnnnkkkk 11110000 11111111 11113333 11114444)))) ''''((((11115555 11116666 11117777))))))))
a: 385, b[0]: 1.234000, b[1]: 5.678000
 c (first): 10   c (second): 11
 ( 15 16 ... )
 3
_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
_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
_3._1_4_1_5_9_2_6  _w_h_i_c_h _c_h_e_c_k _n_e_x_t.
-> ((((ffffuuuunnnnccccaaaallllllll tttteeeessssttttaaaarrrrrrrr 1111))))
3.1415926


_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.
-> ((((aaaarrrrrrrraaaayyyy tttteeeesssstttt fffflllloooonnnnuuuummmm----bbbblllloooocccckkkk 2222))))
array[2]
-> ((((ssssttttoooorrrreeee ((((tttteeeesssstttt 0000)))) 1111....222233334444))))
1.234
-> ((((ssssttttoooorrrreeee ((((tttteeeesssstttt 1111)))) 5555....666677778888))))
5.678
-> ((((ppppffffoooooooo 333388885555 ((((ggggeeeettttdddd ''''tttteeeesssstttt)))) ((((hhhhuuuunnnnkkkk 11110000 11111111 11113333 11114444)))) ''''((((11115555 11116666 11117777))))))))
 a:       385 b[0]:  1.23400000000000E+00 b[1]:  5.67800000000000E+00
 c (first):        10 c (second):        11
 (         15        16 ...)
3
-> ((((tttteeeesssstttt 1111))))
3.1415926

 _N_o_w _t_o _t_e_s_t _o_u_t _t_h_e _m_e_m_q'_s
-> ((((ccccmmmmeeeemmmmqqqq ''''aaaa ''''((((bbbb cccc aaaa dddd eeee ffff))))))))
(_a _d _e _f)
-> ((((ppppmmmmeeeemmmmqqqq ''''eeee ''''((((aaaa dddd ffff gggg aaaa xxxx))))))))
_n_i_l
____________________________________________________________


                                     Printed: March 23, 1982







FFFFuuuunnnnccccttttiiiioooonnnnssss aaaannnndddd MMMMaaaaccccrrrroooossss                                    8888----11112222


     The Fortran example will be much shorter since in  For-
tran   you  can't  follow  pointers  as  you  can  in  other
languages.  The Fortran function ffoo is given  three  argu-
ments:  a  fixnum, a fixnum-block array and a flonum.  These
arguments are printed out to verify that they  made  it  and
then the first value of the array is modified.  The function
returns a double precision value which  is  converted  to  a
flonum  by  lisp  and  printed.   Note  that the entry point
corresponding to the Fortran  function  ffoo  is  _ffoo_  as
opposed to the C and Pascal convention of preceding the name
with an underscore.

____________________________________________________________


% ccccaaaatttt cccchhhh8888aaaauuuuxxxxffff....ffff
        double precision function ffoo(a,b,c)
        integer a,b(10)
        double precision c
        print 2,a,b(1),b(2),c
2       format(' a=',i4,', b(1)=',i5,', b(2)=',i5,' c=',f6.4)
        b(1) = 22
        ffoo = 1.23456
        return
        end
% ffff77777777 ----cccc cccchhhh8888aaaauuuuxxxxffff....ffff
ch8auxf.f:
   ffoo:
0.9u 1.8s 0:12 22% 20+22k 54+48io 158pf+0w
% lllliiiisssspppp
Franz Lisp, Opus 33b
-> ((((ccccffffaaaassssllll ''''cccchhhh8888aaaauuuuxxxxffff....oooo ''''____ffffffffoooooooo____ ''''ffffffffoooooooo """"rrrreeeeaaaallll----ffffuuuunnnnccccttttiiiioooonnnn"""" """"----llllFFFF77777777 ----llllIIII77777777""""))))
/usr/lib/lisp/nld -N -A /usr/local/lisp -T 63000 ch8auxf.o -e _ffoo_
-o /tmp/Li11066.0 -lF77 -lI77 -lc
#6307c-"real-function"

-> ((((aaaarrrrrrrraaaayyyy tttteeeesssstttt ffffiiiixxxxnnnnuuuummmm----bbbblllloooocccckkkk 2222))))
array[2]
-> ((((ssssttttoooorrrreeee ((((tttteeeesssstttt 0000)))) 11110000))))
10
-> ((((ssssttttoooorrrreeee ((((tttteeeesssstttt 1111)))) 11111111))))
11
-> ((((ffffffffoooooooo 333388885555 ((((ggggeeeettttdddd ''''tttteeeesssstttt)))) 5555....666677778888))))
 a= 385, b(1)=   10, b(2)=   11 c=5.6780
1.234559893608093
-> ((((tttteeeesssstttt 0000))))
22

____________________________________________________________



9

9                                     Printed: March 23, 1982