Annotation of 43BSDTahoe/ucb/lisp/doc/ch8.n, revision 1.1.1.1

1.1       root        1: .\" Copyright (c) 1980 Regents of the University of California.
                      2: .\" All rights reserved.  The Berkeley software License Agreement
                      3: .\" specifies the terms and conditions for redistribution.
                      4: .\"
                      5: .\"    @(#)ch8.n       6.2 (Berkeley) 5/14/86
                      6: .\"
                      7: ." $Header: ch8.n,v 1.4 83/07/27 15:12:22 layer Exp $
                      8: .Lc Functions,\ Fclosures,\ and\ Macros 8
                      9: .sh 2 valid\ function\ objects \n(ch 1
                     10: .pp
                     11: There are many different objects which can occupy the function field of 
                     12: a symbol object.
                     13: Table 8.1, on the following page,
                     14: shows all of the possibilities, how to recognize them,
                     15: and where to look for documentation.
                     16: .(z
                     17: .sp 1v
                     18: .TS
                     19: box center ;
                     20: c | c | c .
                     21: informal name  object type     documentation 
                     22: =
                     23: interpreted    list with \fIcar\fP     8.2
                     24: lambda function        \fIeq\fP to lambda
                     25: _
                     26: interpreted    list with \fIcar\fP     8.2
                     27: nlambda function       \fIeq\fP to nlambda
                     28: _
                     29: interpreted    list with \fIcar\fP     8.2
                     30: lexpr function \fIeq\fP to lexpr
                     31: _
                     32: interpreted    list with \fIcar\fP     8.3
                     33: macro  \fIeq\fP to macro
                     34: _
                     35: fclosure       vector with \fIvprop\fP 8.4
                     36:        \fIeq\fP to fclosure
                     37: _
                     38: compiled       binary with discipline  8.2
                     39: lambda or lexpr        \fIeq\fP to lambda
                     40: function
                     41: _
                     42: compiled       binary with discipline  8.2
                     43: nlambda function       \fIeq\fP to nlambda
                     44: _
                     45: compiled       binary with discipline  8.3
                     46: macro  \fIeq\fP to macro
                     47: _
                     48: foreign        binary with discipline  8.5
                     49: subroutine     of \*(lqsubroutine\*(rq\*[\(dg\*]
                     50: _
                     51: foreign        binary with discipline  8.5
                     52: function       of \*(lqfunction\*(rq\*[\(dg\*]
                     53: _
                     54: foreign        binary with discipline  8.5
                     55: integer function       of \*(lqinteger-function\*(rq\*[\(dg\*]
                     56: _
                     57: foreign        binary with discipline  8.5
                     58: real function  of \*(lqreal-function\*(rq\*[\(dg\*]
                     59: _
                     60: foreign        binary with discipline  8.5
                     61: C function     of \*(lqc-function\*(rq\*[\(dg\*]
                     62: _
                     63: foreign        binary with discipline  8.5
                     64: double function        of \*(lqdouble-c-function\*(rq\*[\(dg\*]
                     65: _
                     66: foreign        binary with discipline  8.5
                     67: structure function     of \*(lqvector-c-function\*(rq\*[\(dg\*]
                     68: _
                     69: array  array object    9
                     70: .TE
                     71: .tl ''Table 8.1''
                     72: .(f
                     73: \*[\(dg\*]Only the first character of the string is significant (i.e \*(lqs\*(rq
                     74: is ok for \*(lqsubroutine\*(rq)
                     75: .)f
                     76: .)z
                     77: .br
                     78: .sh 2 functions
                     79: .pp
                     80: The basic Lisp function is the lambda function.
                     81: When a lambda function is called, the actual arguments are
                     82: evaluated from left to right and are lambda-bound to the
                     83: formal parameters of the lambda function.
                     84: .pp
                     85: An nlambda function is usually used for functions which are invoked
                     86: by the user at top level.
                     87: Some built-in functions which evaluate their arguments in special ways are
                     88: also nlambdas (e.g \fIcond\fP, \fIdo\fP, \fIor\fP).
                     89: When an nlambda function is called, the list of unevaluated arguments
                     90: is lambda bound to the single formal parameter of the nlambda function.
                     91: .pp
                     92: Some programmers will use an nlambda function 
                     93: when they are not sure how many arguments
                     94: will be passed.
                     95: Then, the first thing the nlambda function does is map \fIeval\fP over
                     96: the list of unevaluated arguments it has been passed.
                     97: This is usually the wrong thing to do, as it will not work compiled if
                     98: any of the arguments are local variables. 
                     99: The solution is to use a lexpr.
                    100: When a lexpr function is called, the arguments
                    101: are evaluated and a fixnum whose value is
                    102: the number of arguments is lambda-bound to the single
                    103: formal parameter of the lexpr function.
                    104: The lexpr can then access the arguments using the \fIarg\fP function.
                    105: .pp
                    106: When a function is compiled,
                    107: .i special 
                    108: declarations may be needed to 
                    109: preserve its behavior.
                    110: An argument is not lambda-bound to the name of
                    111: the corresponding formal parameter 
                    112: unless that formal parameter has been declared 
                    113: .i special 
                    114: (see \(sc12.3.2.2).
                    115: .pp
                    116: Lambda and lexpr functions both compile into a binary object with
                    117: a discipline of lambda.
                    118: However, a compiled lexpr still acts like an interpreted lexpr.
                    119: .sh 2 macros
                    120: .pp
                    121: An important feature of Lisp 
                    122: is its ability to manipulate programs as data.
                    123: As a result of this, most Lisp implementations
                    124: have very powerful macro facilities.
                    125: The Lisp language's macro facility
                    126: can be used to incorporate popular features of the other
                    127: languages into Lisp.
                    128: For example, there are macro packages 
                    129: which allow one to create records (ala Pascal) 
                    130: and refer to elements of those records by the field names.
                    131: The 
                    132: .i struct
                    133: package imported from Maclisp does this.
                    134: Another popular use for macros is to create more readable control 
                    135: structures which expand into 
                    136: .i cond , 
                    137: .i or 
                    138: and 
                    139: .i and .
                    140: One such example is the If macro.
                    141: It allows you to write
                    142: .sp 1v
                    143: .nf
                    144: .ft I
                    145: (If (equal numb 0) then (print 'zero) (terpr)
                    146: \ elseif (equal numb 1) then (print 'one) (terpr)
                    147: \ else (print '|I give up|))
                    148: .ft P
                    149: .sp 1v
                    150: which expands to 
                    151: .sp 1v
                    152: .ft I
                    153: (cond 
                    154: \ \ \ \ ((equal numb 0) (print 'zero) (terpr))
                    155: \ \ \ \ ((equal numb 1) (print 'one) (terpr))
                    156: \ \ \ \ (t (print '|I give up|)))
                    157: .ft P
                    158: .sp 1v
                    159: .fi
                    160: .sh 3  macro\ forms
                    161: .pp
                    162: A macro is a function which accepts a Lisp expression as input and returns
                    163: another Lisp expression.
                    164: The action the macro takes is called macro expansion.
                    165: Here is a simple example:
                    166: .sp 1v
                    167: .nf
                    168: \-> \fI(def first (macro (x) (cons 'car (cdr x))))\fP
                    169: first
                    170: \-> \fI(first '(a b c))\fP
                    171: a
                    172: \-> \fI(apply 'first '(first '(a b c)))\fP
                    173: (car '(a b c))
                    174: .fi
                    175: .sp 1v
                    176: The first input line defines a macro called 
                    177: .i first .
                    178: Notice that the macro has one formal parameter, \fIx\fP.  
                    179: On the second input line, we ask the interpreter to evaluate
                    180: \fI(first\ '(a\ b\ c))\fP.
                    181: .i Eval 
                    182: sees that 
                    183: .i first
                    184: has a function definition of type macro, so it evaluates 
                    185: .i first 's 
                    186: definition,
                    187: passing to 
                    188: .i first ,
                    189: as an argument, the form 
                    190: .i eval 
                    191: itself
                    192: was trying to
                    193: evaluate: \fI(first\ '(a\ b\ c))\fP.
                    194: The 
                    195: .i first 
                    196: macro chops off the car of the argument with
                    197: .i cdr ,
                    198: cons' a 
                    199: .i car
                    200: at the beginning of the list and returns \fI(car\ '(a\ b\ c))\fP,
                    201: which
                    202: .i eval 
                    203: evaluates.
                    204: The value
                    205: .i a
                    206: is returned as the value of \fI(first\ '(a\ b\ c))\fP.
                    207: Thus whenever 
                    208: .i eval
                    209: tries to evaluate a list whose car has a macro definition
                    210: it ends up doing (at least) two operations, the first of which
                    211: is a call to the macro
                    212: to let it macro expand the form, and the other is the evaluation of the
                    213: result of the macro.
                    214: The result of the macro may be yet another call to a macro, so 
                    215: .i eval
                    216: may have to do even more evaluations until it can finally determine
                    217: the  value of an expression.
                    218: One way to see how a macro will expand is to use
                    219: .i apply
                    220: as shown on the third input line above.
                    221: .sh +0 defmacro
                    222: .pp
                    223: The macro 
                    224: .i defmacro
                    225: makes it easier to define macros because it allows you to name the arguments
                    226: to the macro call.
                    227: For example, suppose we find ourselves often writing code like
                    228: \fI(setq\ stack\ (cons\ newelt\ stack)\fP.
                    229: We could define a macro named \fIpush\fP to do this for us.
                    230: One way to define it is:
                    231: .nf
                    232: .sp 1v
                    233: \-> \fI(de\kAf push 
                    234: \h'|\nAu'(macro (x) (list 'setq (caddr x) (list 'cons (cadr x) (caddr x)))))\fP
                    235: push
                    236: .fi
                    237: .sp 1v
                    238: then \fI(push\ newelt\ stack)\fP will expand to the form mentioned above.
                    239: The same macro written using defmacro would be:
                    240: .nf
                    241: .sp 1v
                    242: \->\fI\kA (defmacro push (value stack)
                    243:   \h'|\nAu'(list 'setq ,stack (list 'cons ,value ,stack)))\fP
                    244: push
                    245: .fi
                    246: .sp 1v
                    247: Defmacro allows you to name the arguments of the macro call, and makes the 
                    248: macro definition look more like a function definition.
                    249: .sh +0 the\ backquote\ character\ macro
                    250: .pp
                    251: The default syntax for 
                    252: .Fr
                    253: has four characters with associated character macros.
                    254: One is semicolon for comments.
                    255: Two others are the backquote and comma which are
                    256: used by the backquote character
                    257: macro.
                    258: The fourth is the sharp sign macro described in the next section.
                    259: .pp
                    260: The backquote macro is used to create lists where many of the elements are
                    261: fixed (quoted). 
                    262: This makes it very useful for creating macro definitions.
                    263: In the simplest case, a backquote acts just like a single quote:
                    264: .sp 1v
                    265: .nf
                    266: \->\fI`(a b c d e)\fP
                    267: (a b c d e)
                    268: .fi
                    269: .sp 1v
                    270: If a comma precedes an element of a backquoted list then that element is
                    271: evaluated and its value is put in the list.
                    272: .sp 1v
                    273: .nf
                    274: \->\fI(setq d '(x y z))\fP
                    275: (x y z)
                    276: \->\fI`(a b c ,d e)\fP
                    277: (a b c (x y z) e)
                    278: .fi
                    279: .sp 1v
                    280: If a comma followed by an at sign precedes an element in a backquoted list,
                    281: then that element is evaluated and spliced into the list with 
                    282: .i append .
                    283: .nf
                    284: .sp 1v
                    285: \->\fI`(a b c ,@d e)\fP
                    286: (a b c x y z e)
                    287: .sp 1v
                    288: .fi
                    289: Once a list begins with a backquote, the commas may appear anywhere in the
                    290: list as this example shows:
                    291: .nf
                    292: .sp 1v
                    293: \->\fI`(a b (c d ,(cdr d)) (e f (g h ,@(cddr d) ,@d)))\fP
                    294: (a b (c d (y z)) (e f (g h z x y z)))
                    295: .sp 1v
                    296: .fi
                    297: It is also possible and sometimes even useful to use the 
                    298: backquote macro within itself.
                    299: As a final demonstration of the backquote macro, we shall define the 
                    300: first and push macros using all the power at our disposal: defmacro
                    301: and the backquote macro.
                    302: .sp 1v
                    303: .nf
                    304: \->\fI(defmacro first (list) `(car ,list))\fP
                    305: first
                    306: \->\fI(defmacro push (value stack) `(setq ,stack (cons ,value ,stack)))\fP
                    307: stack
                    308: .fi
                    309: .sh +0 sharp\ sign\ character\ macro
                    310: .pp
                    311: The sharp sign macro can perform a number of
                    312: different functions  at read time.
                    313: The character directly following the sharp sign determines which function
                    314: will be done, and following Lisp s-expressions may serve as arguments.
                    315: .sh +1 conditional\ inclusion
                    316: .lp
                    317: If you plan to run one source file in more than one environment then 
                    318: you may want to some pieces of code to be included  or not included
                    319: depending on the environment.  
                    320: The C language uses \*(lq#ifdef\*(lq and \*(lq#ifndef\*(rq for this 
                    321: purpose, and Lisp uses \*(lq#+\*(rq and \*(lq#\-\*(rq.
                    322: The environment that the sharp sign macro checks is the 
                    323: \fI(status\ features)\fP list which is initialized when the Lisp
                    324: system is built  and which may be  altered by 
                    325: \fI(sstatus\ feature\ foo)\fP and \fI(sstatus\ nofeature\ bar)\fP
                    326: The form  of conditional inclusion is
                    327: .br
                    328: .tl ''\fI#+when what\fP''
                    329: where 
                    330: .i when 
                    331: is either a symbol or an expression involving symbols and the functions
                    332: .i and ,
                    333: .i or ,
                    334: and
                    335: .i not .
                    336: The meaning is that 
                    337: .i what
                    338: will only be read in if  
                    339: .i when
                    340: is true.
                    341: A symbol in 
                    342: .i when
                    343: is true only if it appears in the 
                    344: .i (status\ features)
                    345: list.
                    346: .Eb
                    347: ; suppose we want to write a program which references a file
                    348: ; and which can run at ucb, ucsd and cmu where the file naming conventions
                    349: ; are different.
                    350: ;
                    351: \-> \fI(de\kAfun howold (name)
                    352:    \h'|\nAu'\kC(terpr)
                    353:    \h'|\nCu'\kB(load #\kA+(or ucb ucsd) "/usr/lib/lisp/ages.l"
                    354:           \h'|\nAu'#+cmu "/usr/lisp/doc/ages.l")
                    355:    \h'|\nBu'\kA(patom name)
                    356:    \h'|\nBu'\kA(patom " is ")
                    357:    \h'|\nAu'\kB(print (cdr (assoc name agefile)))
                    358:    \h'|\nBu'\kA(patom "years old")
                    359:    \h'|\nAu'(terpr))\fP
                    360: .Ee
                    361: The form
                    362: .br
                    363: .tl ''\fI#\-when what\fP''
                    364: is equivalent to
                    365: .br
                    366: .tl ''\fI#+(not when) what\fP''
                    367: .sh +0 fixnum\ character\ equivalents
                    368: .lp
                    369: When working with fixnum equivalents of characters, it is often hard to
                    370: remember the number corresponding to a character.
                    371: The form
                    372: .br
                    373: .tl ''\fI#/c\fP''
                    374: is equivalent to the fixnum representation of character c.
                    375: .Eb
                    376: ; a function which returns t if the user types y else it returns nil.
                    377: ;
                    378: \-> \fI(de\kBfun yesorno nil
                    379:    \h'|\nBu'(progn \kA(ans)
                    380:           \h'|\nAu'\kB(setq ans (tyi))
                    381:           \h'|\nBu'(cond \kA((equal ans #/y) t)
                    382:                 \h'|\nAu'(t nil))))\fP
                    383: .Ee
                    384: .sh +0 read\ time\ evaluation
                    385: .lp
                    386: Occasionally you want to express a constant as a Lisp expression, yet you
                    387: don't want to pay the penalty of evaluating this expression each time it
                    388: is referenced.
                    389: The form
                    390: .br
                    391: .tl ''\fI#.expression\fP''
                    392: evaluates the expression at read time and returns its value.
                    393: .Eb
                    394: ; a function to test if any of bits 1 3 or 12 are set in a fixnum.
                    395: ;
                    396: \-> \fI(de\kCfun testit (num)
                    397:    \h'|\nCu'(cond \kA(\kB(zerop (boole 1 num #.(+ (lsh 1 1) (lsh 1 3) (lsh 1 12))))
                    398:           \h'|\nBu'nil)
                    399:          \h'|\nAu'(t t)))\fP
                    400: .Ee
                    401: .sh 2 fclosures
                    402: .pp
                    403: Fclosures are a type of functional object.
                    404: The purpose is to remember the values of some variables 
                    405: between invocations of the functional object and to protect this
                    406: data from being inadvertently overwritten by other Lisp functions.
                    407: Fortran programs usually exhibit this behavior for their variables.
                    408: (In fact, some versions of Fortran would require the
                    409: variables to be in COMMON).
                    410: Thus it is easy to write a linear congruent random number generator
                    411: in Fortran, merely by keeping the seed as a variable in the function.
                    412: It is much more risky to do so in Lisp, since any special variable you
                    413: picked, might be used by some other function.
                    414: Fclosures are an attempt to provide most of the same functionality as
                    415: closures in Lisp Machine Lisp, to users of
                    416: .Fr .
                    417: Fclosures are related to closures in this way:
                    418: .br
                    419: (fclosure '(a b) 'foo) <==>
                    420: .br
                    421:        (let ((a a) (b b)) (closure '(a b) 'foo))
                    422: .sh 3 an\ example
                    423: .sp 1v
                    424: .in 0
                    425: .nf
                    426: .sz -2
                    427: .hl
                    428: % \fBlisp\fP
                    429: Franz Lisp, Opus 38.60
                    430: \->\fB(defun code (me count)
                    431:   (print (list 'in x))
                    432:   (setq x (+ 1 x))
                    433:   (cond ((greaterp count 1) (funcall me me (sub1 count))))
                    434:   (print (list 'out x)))\fP
                    435: code
                    436: \->\fB(defun tester (object count)
                    437:   (funcall object object count) (terpri))\fP
                    438: tester
                    439: \->\fB(setq x 0)\fP
                    440: 0
                    441: \->\fB(setq z (fclosure '(x) 'code))\fP
                    442: fclosure[8]
                    443: \->\fB (tester z 3)\fP
                    444: (in 0)(in 1)(in 2)(out 3)(out 3)(out 3)
                    445: nil
                    446: \->\fBx\fP
                    447: 0
                    448: .hl
                    449: .fi
                    450: .sz +2
                    451: .sp 3v
                    452: .pp
                    453: The function \fIfclosure\fP creates a new object
                    454: that we will call an fclosure,
                    455: (although it is actually a vector).
                    456: The fclosure contains a functional object, and a set of symbols and
                    457: values for the symbols.  In the above example, the fclosure functional
                    458: object is the function code.
                    459: The set of symbols and values just contains the symbol `x' and
                    460: zero, the value of `x' when the fclosure was created.
                    461: .lp
                    462: When an fclosure is funcall'ed:
                    463: .ip 1)
                    464: The Lisp system lambda binds the symbols in the fclosure to their values in the fclosure.
                    465: .ip 2)
                    466: It continues the funcall on the functional object of the fclosure.
                    467: .ip 3)
                    468: Finally, it un-lambda binds the symbols in the fclosure and at the
                    469: same time stores the current values of the symbols in the fclosure.
                    470: .sp 1v
                    471: .pp
                    472: Notice that the fclosure is saving the value of the symbol `x'.
                    473: Each time a fclosure is created, new space is allocated for saving
                    474: the values of the symbols. Thus if we execute fclosure again, over
                    475: the same function, we can have two independent counters:
                    476: .sp 1v
                    477: .in 0
                    478: .nf
                    479: .sz -2
                    480: .hl
                    481: \-> \fB(setq zz (fclosure '(x) 'code))\fP
                    482: fclosure[1]
                    483: \-> \fB(tester zz 2)\fP
                    484: (in 0)(in 1)(out 2)(out 2)
                    485: \-> \fB(tester zz 2)\fP
                    486: (in 2)(in 3)(out 4)(out 4)
                    487: \-> \fB(tester z 3)\fP
                    488: (in 3)(in 4)(in 5)(out 6)(out 6)(out 6)
                    489: .hl
                    490: .fi
                    491: .sz +2
                    492: .sp 3v
                    493: .sh 3 useful\ functions
                    494: .pp
                    495: Here are some quick some summaries of functions dealing with closures.
                    496: They are more formally defined in \(sc2.8.4.
                    497: To recap, fclosures are made by
                    498: \fI(fclosure 'l_vars 'g_funcobj)\fP.
                    499: l_vars is a list of symbols (not containing nil),
                    500: g_funcobj is any object that can be funcalled.
                    501: (Objects which can be funcalled, include compiled Lisp functions,
                    502: lambda expressions, symbols, foreign functions, etc.)
                    503: In general, if you want a compiled function to be closed over a
                    504: variable, you must declare the variable to be special within the function.
                    505: Another example would be:
                    506: .(l
                    507:        (fclosure '(a b) #'(lambda (x) (plus x a)))
                    508: .)l
                    509: Here, the #' construction will make the compiler compile the lambda expression.
                    510: .pp
                    511: There are times when you want to share variables between fclosures.
                    512: This can be done if the fclosures are created at the same time using
                    513: \fIfclosure-list\fP.
                    514: The function \fIfclosure-alist\fP returns an assoc list giving
                    515: the symbols and values in the fclosure.  The predicate
                    516: \fIfclosurep\fP returns t iff its argument is a fclosure.
                    517: Other functions imported from Lisp Machine Lisp are
                    518: .i symeval-in-fclosure,
                    519: .i let-fclosed,
                    520: and
                    521: .i set-in-fclosure.
                    522: Lastly, the function \fIfclosure-function\fP returns the function argument.
                    523: .sh 3 internal\ structure
                    524: .pp
                    525: Currently, closures are implemented as vectors, with property being the
                    526: symbol fclosure.  The functional object is the first entry.
                    527: The remaining entries are structures which point to the symbols
                    528: and values for the closure, (with a reference count to determine
                    529: if a recursive closure is active).
                    530: .sh 2 foreign\ subroutines\ and\ functions
                    531: .pp
                    532: .Fr 
                    533: has the ability to dynamically load object files produced by other compilers
                    534: and to call functions defined in those files.
                    535: These functions are called 
                    536: .i foreign
                    537: functions.*
                    538: .(f
                    539: *This topic is also discussed in Report PAM-124 of the Center for
                    540: Pure and Applied Mathematics, UCB, entitled ``Parlez-Vous Franz?
                    541: An Informal Introduction to Interfacing Foreign Functions to Franz LISP'',
                    542: by James R. Larus
                    543: .)f
                    544: There are seven types of foreign functions.
                    545: They are characterized by
                    546: the type of result they return, and by differences in the interpretation
                    547: of their arguments.
                    548: They come from two families: a group suited for languages which pass
                    549: arguments by reference (e.g. Fortran), and a group suited for languages
                    550: which pass arguments by value (e.g. C).
                    551: .sp 1v
                    552: .lp
                    553: There are four types in the first group:
                    554: .ip \fBsubroutine\fP
                    555: This does not return anything. 
                    556: The Lisp system
                    557: always returns t after calling a subroutine.
                    558: .ip \fBfunction\fP
                    559: This returns whatever the function returns.
                    560: This must be a valid Lisp object or it may cause the Lisp system to fail.
                    561: .ip \fBinteger-function\fP
                    562: This returns an integer which the Lisp system makes into a fixnum and returns.
                    563: .ip \fBreal-function\fP
                    564: This returns a double precision real number which the Lisp
                    565: system makes into a flonum and returns.
                    566: .sp 1v
                    567: .lp
                    568: There are three types in the second group:
                    569: .ip \fBc-function\fP
                    570: This is like an integer function, except for its different interpretation
                    571: of arguments.
                    572: .ip \fBdouble-c-function\fP
                    573: This is like a real-function.
                    574: .ip \fBvector-c-function\fP
                    575: This is for C functions which return a structure.
                    576: The first argument to such functions must be a vector (of type vectori),
                    577: into which the result is stored.
                    578: The second Lisp argument
                    579: becomes the first argument to the C function, and so on
                    580: .lp
                    581: A foreign function is accessed through a binary object just like a 
                    582: compiled Lisp function.
                    583: The difference is that the discipline field of a binary object
                    584: for a foreign function is a string 
                    585: whose first character is given in the following table:
                    586: .(b
                    587: .TS
                    588: box center ;
                    589: c | c .
                    590: letter type
                    591: =
                    592: s      subroutine
                    593: _
                    594: f      function
                    595: _
                    596: i      integer-function
                    597: _
                    598: r      real-function.
                    599: _
                    600: c      c-function
                    601: _
                    602: v      vector-c-function
                    603: _
                    604: d      double-c-function
                    605: _
                    606: .TE
                    607: .)b
                    608: Two functions are provided for setting-up foreign functions.
                    609: .i Cfasl
                    610: loads an object file into the Lisp system and sets up one foreign
                    611: function binary object.
                    612: If there are more than one function in an object file, 
                    613: .i getaddress
                    614: can be used to set up additional foreign function objects.
                    615: .pp
                    616: Foreign  functions are called just like other functions, e.g 
                    617: \fI(funname\ arg1\ arg2)\fP.
                    618: When a function in the Fortran group is called,
                    619: the arguments are evaluated and then examined.
                    620: List, hunk and symbol arguments are passed unchanged to 
                    621: the foreign function.
                    622: Fixnum and flonum arguments are copied into a temporary location and
                    623: a pointer to the value is passed (this is because Fortran uses call
                    624: by reference and it is dangerous to modify the contents of a fixnum
                    625: or flonum which something else might point to).
                    626: If the argument is an array object,
                    627: the data field of the array object is
                    628: passed to the foreign function
                    629: (This is the easiest way to send large
                    630: amounts of data to and receive large amounts of data from a foreign
                    631: function).
                    632: If a binary object is an argument, the entry field of that object is
                    633: passed to the foreign function (the entry field is the address of a function,
                    634: so this amounts to passing a function as an argument).
                    635: .pp
                    636: When a function in the C group is called,
                    637: fixnum and flownum arguments are passed by value.
                    638: For almost all other arguments,
                    639: the address is merely provided to the C routine.
                    640: The only exception arises when you want to invoke a C routine
                    641: which expects a ``structure'' argument.  Recall that a (rarely used)
                    642: feature of the C language is the ability to pass structures by value.
                    643: This copies the structure onto the stack.  Since the Franz's nearest
                    644: equivalent to a C structure is a vector, we provide an escape clause
                    645: to copy the contents of an immediate-type vector by value.  If the
                    646: property field of a vectori argument, is the symbol
                    647: \*(lqvalue-structure-argument\*(rq,
                    648: then the binary data of this immediate-type vector is copied
                    649: into the argument list of the C routine.
                    650: .pp
                    651: The method a foreign function uses to access the arguments provided 
                    652: by Lisp is dependent on the language of the foreign function.
                    653: The following scripts demonstrate how how Lisp can interact with three
                    654: languages: C, Pascal and Fortran.
                    655: C and Pascal have pointer types and the first script shows how to use
                    656: pointers to extract information from Lisp objects.
                    657: There are two functions defined for each language.
                    658: The first (cfoo in C, pfoo in Pascal) is given four arguments, a 
                    659: fixnum, a flonum-block array, a hunk of at least two
                    660: fixnums and a list of 
                    661: at least two fixnums.
                    662: To demonstrate that the values were passed, each ?foo function prints
                    663: its arguments (or parts of them).
                    664: The ?foo function then modifies the second element of 
                    665: the flonum-block array and returns a 3 to Lisp.
                    666: The second function (cmemq in C, pmemq in Pascal) acts just like the
                    667: Lisp
                    668: .i memq
                    669: function (except it won't work for fixnums whereas the lisp 
                    670: .i memq
                    671: will work for small fixnums).
                    672: In the script, typed input is in 
                    673: .b bold ,
                    674: computer output is in roman
                    675: and comments are in
                    676: .i italic.
                    677: .in 0
                    678: .nf
                    679: .sp 2v
                    680: .sz -2
                    681: .hl
                    682: \fIThese are the C coded functions  \fP
                    683: % \fBcat ch8auxc.c\fP
                    684: /* demonstration of c coded foreign integer-function */
                    685: 
                    686: /* the following will be used to extract fixnums out of a list of fixnums */
                    687: struct listoffixnumscell
                    688: {    struct listoffixnumscell *cdr;
                    689:      int *fixnum;
                    690: };
                    691: 
                    692: struct listcell
                    693: {      struct listcell *cdr;
                    694:        int car;
                    695: };
                    696: 
                    697: cfoo(a,b,c,d)
                    698: int *a;
                    699: double b[];
                    700: int *c[];
                    701: struct listoffixnumscell *d;
                    702: {
                    703:     printf("a: %d, b[0]: %f, b[1]: %f\n", *a, b[0], b[1]);
                    704:     printf(" c (first): %d   c (second): %d\n",
                    705:               *c[0],*c[1]);
                    706:     printf(" ( %d %d ... )\n ", *(d->fixnum), *(d->cdr->fixnum));
                    707:     b[1] = 3.1415926;
                    708:     return(3);
                    709: }
                    710: 
                    711: struct listcell *
                    712: cmemq(element,list)
                    713: int element;
                    714: struct listcell *list;
                    715: {   
                    716:    for( ; list && element != list->car ;  list = list->cdr);
                    717:    return(list);
                    718: }
                    719: .sp 2v
                    720: \fIThese are the Pascal coded functions \fP
                    721: % \fBcat ch8auxp.p\fP
                    722: type   pinteger = ^integer;
                    723:        realarray = array[0..10] of real;
                    724:        pintarray = array[0..10] of pinteger;
                    725:        listoffixnumscell = record  
                    726:                                cdr  : ^listoffixnumscell;
                    727:                                fixnum : pinteger;
                    728:                            end;
                    729:        plistcell = ^listcell;
                    730:        listcell = record
                    731:                      cdr : plistcell;
                    732:                      car : integer;
                    733:                   end;
                    734: 
                    735: function pfoo ( var a : integer ; 
                    736:                var b : realarray;
                    737:                var c : pintarray;
                    738:                var d : listoffixnumscell) : integer;
                    739: begin
                    740:    writeln(' a:',a, ' b[0]:', b[0], ' b[1]:', b[1]);
                    741:    writeln(' c (first):', c[0]^,' c (second):', c[1]^);
                    742:    writeln(' ( ', d.fixnum^, d.cdr^.fixnum^, ' ...) ');
                    743:    b[1] := 3.1415926;
                    744:    pfoo := 3
                    745: end ;
                    746: 
                    747: { the function pmemq looks for the Lisp pointer given as the first argument
                    748:   in the list pointed to by the second argument.
                    749:   Note that we declare " a : integer " instead of " var a : integer " since
                    750:   we are interested in the pointer value instead of what it points to (which
                    751:   could be any Lisp object)
                    752: }
                    753: function pmemq( a : integer; list : plistcell) : plistcell;
                    754: begin
                    755:  while (list <> nil) and (list^.car <> a) do list := list^.cdr;
                    756:  pmemq := list;
                    757: end ;
                    758: .sp 2v
                    759: \fIThe files are compiled\fP
                    760: % \fBcc -c ch8auxc.c\fP
                    761: 1.0u 1.2s 0:15 14% 30+39k 33+20io 147pf+0w
                    762: % \fBpc -c ch8auxp.p\fP
                    763: 3.0u 1.7s 0:37 12% 27+32k 53+32io 143pf+0w
                    764: .sp 2v
                    765: % \fBlisp\fP
                    766: Franz Lisp, Opus 38.60
                    767: .ft I
                    768: .fi
                    769: First the files are loaded and we set up one foreign function binary.
                    770: We have two functions in each file so we must choose one to tell cfasl about.
                    771: The choice is arbitrary.
                    772: .ft P
                    773: .br 
                    774: .nf
                    775: \->\fB (cfasl 'ch8auxc.o '_cfoo 'cfoo "integer-function")\fP
                    776: /usr/lib/lisp/nld -N -A /usr/local/lisp -T 63000 ch8auxc.o -e _cfoo -o /tmp/Li7055.0  -lc
                    777: #63000-"integer-function"
                    778: \->\fB (cfasl 'ch8auxp.o '_pfoo 'pfoo "integer-function" "-lpc")\fP
                    779: /usr/lib/lisp/nld -N -A /tmp/Li7055.0 -T 63200 ch8auxp.o -e _pfoo -o /tmp/Li7055.1 -lpc -lc
                    780: #63200-"integer-function"
                    781: .ft I
                    782: Here we set up the other foreign function binary objects
                    783: .ft P
                    784: \->\fB (getaddress '_cmemq 'cmemq "function" '_pmemq 'pmemq "function")\fP
                    785: #6306c-"function"
                    786: .ft I
                    787: .fi
                    788: We want to create and initialize an array to pass to the cfoo function.
                    789: In this case we create an unnamed array and store it in the value cell of
                    790: testarr. 
                    791: When we create an array to pass to the Pascal program we will use a named
                    792: array just to demonstrate the different way that named and unnamed arrays
                    793: are created and accessed.
                    794: .br
                    795: .nf
                    796: .ft P
                    797: \->\fB (setq testarr (array nil flonum-block 2))\fP
                    798: array[2]
                    799: \->\fB (store (funcall testarr 0) 1.234)\fP
                    800: 1.234
                    801: \->\fB (store (funcall testarr 1) 5.678)\fP
                    802: 5.678
                    803: \->\fB (cfoo 385 testarr (hunk 10 11 13 14) '(15 16 17))\fP
                    804: a: 385, b[0]: 1.234000, b[1]: 5.678000
                    805:  c (first): 10   c (second): 11
                    806:  ( 15 16 ... )
                    807:  3
                    808: .ft I
                    809: .fi
                    810: Note that cfoo has returned 3 as it should.
                    811: It also had the side effect of changing the second value of the array to
                    812: 3.1415926  which check next.
                    813: .br
                    814: .nf
                    815: .ft P
                    816: \->\fB (funcall testarr 1)\fP
                    817: 3.1415926
                    818: .sp 2v
                    819: .fi
                    820: .ft I
                    821: In preparation for calling pfoo we create an array.
                    822: .ft P
                    823: .nf
                    824: \->\fB (array test flonum-block 2)\fP
                    825: array[2]
                    826: \->\fB (store (test 0) 1.234)\fP
                    827: 1.234
                    828: \->\fB (store (test 1) 5.678)\fP
                    829: 5.678
                    830: \->\fB (pfoo 385 (getd 'test) (hunk 10 11 13 14) '(15 16 17))\fP
                    831:  a:       385 b[0]:  1.23400000000000E+00 b[1]:  5.67800000000000E+00
                    832:  c (first):        10 c (second):        11
                    833:  (         15        16 ...) 
                    834: 3
                    835: \->\fB (test 1)\fP
                    836: 3.1415926
                    837: .sp 1v
                    838: \fI Now to test out the memq's
                    839: \-> \fB(cmemq 'a '(b c a d e f))\fP
                    840: (a d e f)
                    841: \-> \fB(pmemq 'e '(a d f g a x))\fP
                    842: nil
                    843: .hl
                    844: .fi
                    845: .sz +2
                    846: .sp 3v
                    847: .pp
                    848: The Fortran example will be much shorter since in Fortran 
                    849: you can't follow pointers
                    850: as you can in other languages.
                    851: The Fortran function ffoo is given three arguments: a fixnum, a 
                    852: fixnum-block array and a flonum.
                    853: These arguments are printed out to verify that they made it and
                    854: then the first value of the array is modified.
                    855: The function returns a double precision value which is converted to a flonum
                    856: by lisp and printed.
                    857: Note that the entry point corresponding to the Fortran function ffoo is
                    858: _ffoo_ as opposed to the C and Pascal convention of preceding the name with
                    859: an underscore.
                    860: .sp 1v
                    861: .in 0
                    862: .nf
                    863: .sz -2
                    864: .hl
                    865: 
                    866: % \fBcat ch8auxf.f\fP
                    867:        double precision function ffoo(a,b,c)
                    868:        integer a,b(10)
                    869:        double precision c
                    870:        print 2,a,b(1),b(2),c
                    871: 2      format(' a=',i4,', b(1)=',i5,', b(2)=',i5,' c=',f6.4)
                    872:        b(1) = 22
                    873:        ffoo = 1.23456
                    874:        return
                    875:        end
                    876: % \fBf77 -c ch8auxf.f\fP
                    877: ch8auxf.f:
                    878:    ffoo:
                    879: 0.9u 1.8s 0:12 22% 20+22k 54+48io 158pf+0w
                    880: % \fBlisp\fP
                    881: Franz Lisp, Opus 38.60
                    882: \-> \fB(cfasl 'ch8auxf.o '_ffoo_ 'ffoo "real-function" "-lF77 -lI77")\fP
                    883: /usr/lib/lisp/nld -N -A /usr/local/lisp -T 63000 ch8auxf.o -e _ffoo_ 
                    884: -o /tmp/Li11066.0 -lF77 -lI77 -lc
                    885: #6307c-"real-function"
                    886: .sp 1v
                    887: \-> \fB(array test fixnum-block 2)\fP
                    888: array[2]
                    889: \->\fB (store (test 0) 10)\fP
                    890: 10
                    891: \-> \fB(store (test 1) 11)\fP
                    892: 11
                    893: \-> \fB(ffoo 385 (getd 'test) 5.678)\fP
                    894:  a= 385, b(1)=   10, b(2)=   11 c=5.6780
                    895: 1.234559893608093
                    896: \-> \fB(test 0)\fP
                    897: 22
                    898: 
                    899: .hl

unix.superglobalmegacorp.com

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