7 The Advice Facility

The advice facility provides a mechanism for altering the behavior of existing functions. As a simple application of this, you may supplement the original function definition by supplying additional actions to be performed before or after the function is called. Alternatively, you may replace the function with a new piece of code that has access to the original definition, but which is free to ignore it altogether and to process the arguments to the function and return the results from the function in any way you decide. The advice facility allows you to alter the behavior of functions in a very flexible manner, and may be used to engineer anything from a minor addition of a message, to a major modification of the interface to a function, to a complete change in the behavior of a function. This facility can be helpful when debugging, or when experimenting with new versions of functions, or when you wish to locally change some functionality without affecting the original definition.

Note: It can be very dangerous to put advice on functions defined by the system.

Each change that is required should be specified using the defadvice macro. This defines a new body of code to be used when the function is called; this piece of code is called a piece of advice. Consider the following example:

 CL-USER 71 > (defadvice
            (reverse print-advice :before)
            (format t 
              "~%** Calling reverse on ~S **" 
CL-USER 72 > (reverse '(l a m i n a))
** Calling reverse on (L A M I N A) ** 
(A N I M A L) 

In the above example you decided to print a message each time reverse is called. You called defadvice with a description of the function you wanted to alter, a name for the piece of advice, and the keyword :before to indicate that you want the code carried out before reverse is called. The rest of the call to defadvice specifies the additional behavior required, and consists of the lambda-list for the new piece of advice and its body (the lambda-list may specify keyword parameters and so forth). The advice facility arranges that print-advice is invoked whenever reverse is called, and that it receives the arguments to reverse , and that directly after this the original definition of reverse is called.

Pieces of advice may be given to be executed after the call by specifying :after instead of :before in the call to defadvice . So if you wished to add further code to be performed after reverse you could continue the session above as follows:

CL-USER 73 > (defadvice
              (reverse after-advice :after)
              (format t
            "~%** After calling reverse on ~S **"
CL-USER 74 > (reverse '("which" "way" "round"))
** Calling reverse on ("which" "way" "round") ** 
** After calling reverse on ("which" "way" "round") ** ("round" "way" "which") 
CL-USER 75 > 

Note that after-advice also receives the arguments to reverse when it is called.

7.1 Combining the advice

7.2 Removing advice

7.3 Advice for macros and methods

7.4 Examples

7.5 Advice functions and macros

LispWorks User Guide - 11 Mar 2008