Previous: Raw data functions, Up: Declarations


8.6 Arguments/Values Passing

Function proclamations (function function-name (arg-type1 arg-type2 ...) return-type) or its equivalents give the compiler the chance to generate compiled code so that arguments to the named functions and resulting values of the named functions will be passed via the C stack, thus increasing the efficiency of calls to these functions. Such arguments/values passing via the C stack is possible only if the called function is also defined in the same source file. This is because the code for the called function must have two entries: One entry for C arguments/values passing and another for ordinary Lisp arguments/values passing. (An ordinary function has only the latter entry.) When the latter entry is used, the arguments are unboxed and passed to the former entry. On return from the function, the resulting value is cast into a Lisp data type.

A good example of this follows.

     (eval-when (compile)
       (proclaim '(function tak (fixnum fixnum fixnum) fixnum)))
     
     (defun tak (x y z)
       (declare (fixnum x y z))
       (if (not (< y x))
           z
           (tak (tak (1- x) y z)
                (tak (1- y) z x)
                (tak (1- z) x y))))
     
     ;;; Call (tak 18 12 6).

When tak is called with the arguments 18, 12, and 6, the raw fixnum data of the arguments are set to the parameters x, y, z. After that, only raw C data are used to perform the execution: No cell pointers are newly allocated nor even referenced. The built-in functions < and 1- directly operate on the raw data. Only at the return from the top-level call of tak, the resulting raw data value (which happens to be 7) is reallocated on the heap. Note that both the function proclamation and the local fixnum declaration are necessary to obtain the optimal code. The function proclamation is necessary for arguments/values passing via the C stack and the fixnum declaration is necessary to unbox the parameters into C variables.