|
|
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: January 31, 1984 ! 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: January 31, 1984 ! 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: January 31, 1984 ! 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: January 31, 1984 ! 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: January 31, 1984 ! 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: January 31, 1984 ! 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: January 31, 1984 ! 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: January 31, 1984 ! 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: January 31, 1984 ! 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: January 31, 1984 ! 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: January 31, 1984 ! 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: January 31, 1984 ! 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: January 31, 1984 ! 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: January 31, 1984 ! 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: January 31, 1984 ! 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: January 31, 1984 ! 1322: ! 1323: ! 1324:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.