elisp: Advising Named Functions

 
 12.11.2 Advising Named Functions
 --------------------------------
 
 A common use of advice is for named functions and macros.  You could
 just use ‘add-function’ as in:
 
      (add-function :around (symbol-function 'FUN) #'his-tracing-function)
 
    But you should use ‘advice-add’ and ‘advice-remove’ for that instead.
 This separate set of functions to manipulate pieces of advice applied to
 named functions, offers the following extra features compared to
 ‘add-function’: they know how to deal with macros and autoloaded
 functions, they let ‘describe-function’ preserve the original docstring
 as well as document the added advice, and they let you add and remove
 advice before a function is even defined.
 
    ‘advice-add’ can be useful for altering the behavior of existing
 calls to an existing function without having to redefine the whole
 function.  However, it can be a source of bugs, since existing callers
 to the function may assume the old behavior, and work incorrectly when
 the behavior is changed by advice.  Advice can also cause confusion in
 debugging, if the person doing the debugging does not notice or remember
 that the function has been modified by advice.
 
    For these reasons, advice should be reserved for the cases where you
 cannot modify a function’s behavior in any other way.  If it is possible
 to do the same thing via a hook, that is preferable (SeeHooks).  If
 you simply want to change what a particular key does, it may be better
 to write a new command, and remap the old command’s key bindings to the
 new one (SeeRemapping Commands).  In particular, Emacs’s own source
 files should not put advice on functions in Emacs.  (There are currently
 a few exceptions to this convention, but we aim to correct them.)
 
    Special forms (SeeSpecial Forms) cannot be advised, however
 macros can be advised, in much the same way as functions.  Of course,
 this will not affect code that has already been macro-expanded, so you
 need to make sure the advice is installed before the macro is expanded.
 
    It is possible to advise a primitive (SeeWhat Is a Function),
 but one should typically _not_ do so, for two reasons.  Firstly, some
 primitives are used by the advice mechanism, and advising them could
 cause an infinite recursion.  Secondly, many primitives are called
 directly from C, and such calls ignore advice; hence, one ends up in a
 confusing situation where some calls (occurring from Lisp code) obey the
 advice and other calls (from C code) do not.
 
  -- Macro: define-advice symbol (where lambda-list &optional name depth)
           &rest body
      This macro defines a piece of advice and adds it to the function
      named SYMBOL.  The advice is an anonymous function if NAME is nil
      or a function named ‘symbol@name’.  See ‘advice-add’ for
      explanation of other arguments.
 
  -- Function: advice-add symbol where function &optional props
      Add the advice FUNCTION to the named function SYMBOL.  WHERE and
      PROPS have the same meaning as for ‘add-function’ (SeeCore
      Advising Primitives).
 
  -- Function: advice-remove symbol function
      Remove the advice FUNCTION from the named function SYMBOL.
      FUNCTION can also be the ‘name’ of a piece of advice.
 
  -- Function: advice-member-p function symbol
      Return non-‘nil’ if the advice FUNCTION is already in the named
      function SYMBOL.  FUNCTION can also be the ‘name’ of a piece of
      advice.
 
  -- Function: advice-mapc function symbol
      Call FUNCTION for every piece of advice that was added to the named
      function SYMBOL.  FUNCTION is called with two arguments: the advice
      function and its properties.