Function wrappers, fwrappers for short, are a facility for efficiently encapsulating functions3.
Functions in CMUCL are represented by
fdefn object contains a reference to its
function’s actual code, which we call the function’s primary function.
A function wrapper replaces the primary function in the
object with a function of its own, and records the original function
in an fwrapper object, a funcallable instance. Thus, when the
function is called, the fwrapper gets called, which in turn might call
the primary function, or a previously installed fwrapper that was
found in the
fdefn object when the second fwrapper was
(use-package :fwrappers) (define-fwrapper foo (x y) (format t "x = ~s, y = ~s, user-data = ~s~%" x y (fwrapper-user-data fwrapper)) (let ((value (call-next-function))) (format t "value = ~s~%" value) value)) (defun bar (x y) (+ x y)) (fwrap 'bar #'foo :type 'foo :user-data 42) (bar 1 2) => x = 1, y = 2, user-data = 42 value = 3 3
Fwrappers are used in the implementation of
Please note that
fdefinition always returns the primary
definition of a function; if a function is fwrapped,
fdefinition returns the primary function stored in the
innermost fwrapper object. Likewise, if a function is fwrapped,
(setf fdefinition) will set the primary function in the
This macro is like
defun, but defines a function named
name that can be used as an fwrapper definition.
In body, the symbol
fwrapper is bound to the current
call-next-function can be used to invoke the next
fwrapper, or the primary function that is being fwrapped. When
called with no arguments,
call-next-function invokes the next
function with the original arguments passed to the fwrapper, unless
you modify one of the parameters. When called with arguments,
call-next-function invokes the next function with the given
This function wraps function
function-name in an fwrapper
fwrapper which was defined with
The value of type, if supplied, is used as an identifying tag that can be used in various other operations.
The value of user-data is stored as user-supplied data in the
fwrapper object that is created for the function encapsulation.
User-data is accessible in the body of fwrappers defined with
Value is the fwrapper object created.
Remove fwrappers from the function named function-name. If
type is supplied, remove fwrappers whose type is
to type. If test is supplied, remove fwrappers
Find an fwrapper of function-name. If type is supplied,
find an fwrapper whose type is
equal to type. If
test is supplied, find an fwrapper satisfying test.
Update the funcallable instance function of the fwrapper object
fwrapper from the definition of its function that was
define-fwrapper. This can be used to update
fwrappers after changing a
Update fwrappers of function-name; see
If type is supplied, update fwrappers whose type is
equal to type. If test is supplied, update fwrappers
Set function-names’s fwrappers to elements of the list fwrappers, which is assumed to be ordered from outermost to innermost. fwrappers null means remove all fwrappers.
Return a list of all fwrappers of function-name, ordered from outermost to innermost.
Prepend fwrapper fwrapper to the definition of function-name. Signal an error if function-name is an undefined function.
Remove fwrapper fwrapper from the definition of function-name. Signal an error if function-name is an undefined function.
&optionalresult) &body body
Evaluate body with var bound to consecutive fwrappers of
fdefn. Return result at the end. Note that fdefn
must be an
fdefn object. You can use
kernel:fdefn-or-lose, for instance, to get the
object from a function name.
This feature was independently developed, but the interface is modelled after a similar feature in Allegro. Some names, however, have been changed.