elisp: Defining Functions

 
 12.4 Defining Functions
 =======================
 
 We usually give a name to a function when it is first created.  This is
 called “defining a function”, and it is done with the ‘defun’ macro.
 
  -- Macro: defun name args [doc] [declare] [interactive] body...
      ‘defun’ is the usual way to define new Lisp functions.  It defines
      the symbol NAME as a function with argument list ARGS and body
      forms given by BODY.  Neither NAME nor ARGS should be quoted.
 
      DOC, if present, should be a string specifying the function’s
      documentation string (SeeFunction Documentation).  DECLARE, if
      present, should be a ‘declare’ form specifying function metadata
      (SeeDeclare Form).  INTERACTIVE, if present, should be an
      ‘interactive’ form specifying how the function is to be called
      interactively (SeeInteractive Call).
 
      The return value of ‘defun’ is undefined.
 
      Here are some examples:
 
           (defun foo () 5)
           (foo)
                ⇒ 5
 
           (defun bar (a &optional b &rest c)
               (list a b c))
           (bar 1 2 3 4 5)
                ⇒ (1 2 (3 4 5))
           (bar 1)
                ⇒ (1 nil nil)
           (bar)
           error→ Wrong number of arguments.
 
           (defun capitalize-backwards ()
             "Upcase the last letter of the word at point."
             (interactive)
             (backward-word 1)
             (forward-word 1)
             (backward-char 1)
             (capitalize-word 1))
 
      Be careful not to redefine existing functions unintentionally.
      ‘defun’ redefines even primitive functions such as ‘car’ without
      any hesitation or notification.  Emacs does not prevent you from
      doing this, because redefining a function is sometimes done
      deliberately, and there is no way to distinguish deliberate
      redefinition from unintentional redefinition.
 
  -- Function: defalias name definition &optional doc
      This function defines the symbol NAME as a function, with
      definition DEFINITION (which can be any valid Lisp function).  Its
      return value is _undefined_.
 
      If DOC is non-‘nil’, it becomes the function documentation of NAME.
      Otherwise, any documentation provided by DEFINITION is used.
 
      Internally, ‘defalias’ normally uses ‘fset’ to set the definition.
      If NAME has a ‘defalias-fset-function’ property, however, the
      associated value is used as a function to call in place of ‘fset’.
 
      The proper place to use ‘defalias’ is where a specific function
      name is being defined—especially where that name appears explicitly
      in the source file being loaded.  This is because ‘defalias’
      records which file defined the function, just like ‘defun’ (See
      Unloading).
 
      By contrast, in programs that manipulate function definitions for
      other purposes, it is better to use ‘fset’, which does not keep
      such records.  SeeFunction Cells.
 
    You cannot create a new primitive function with ‘defun’ or
 ‘defalias’, but you can use them to change the function definition of
 any symbol, even one such as ‘car’ or ‘x-popup-menu’ whose normal
 definition is a primitive.  However, this is risky: for instance, it is
 next to impossible to redefine ‘car’ without breaking Lisp completely.
 Redefining an obscure function such as ‘x-popup-menu’ is less dangerous,
 but it still may not work as you expect.  If there are calls to the
 primitive from C code, they call the primitive’s C definition directly,
 so changing the symbol’s definition will have no effect on them.
 
    See also ‘defsubst’, which defines a function like ‘defun’ and tells
 the Lisp compiler to perform inline expansion on it.  SeeInline
 Functions.
 
    Alternatively, you can define a function by providing the code which
 will inline it as a compiler macro.  The following macros make this
 possible.
 
  -- Macro: define-inline name args [doc] [declare] body...
      Define a function NAME by providing code that does its inlining, as
      a compiler macro.  The function will accept the argument list ARGS
      and will have the specified BODY.
 
      If present, DOC should be the function’s documentation string
      (SeeFunction Documentation); DECLARE, if present, should be a
      ‘declare’ form (SeeDeclare Form) specifying the function’s
      metadata.
 
    Functions defined via ‘define-inline’ have several advantages with
 respect to macros defined by ‘defsubst’ or ‘defmacro’:
 
    − They can be passed to ‘mapcar’ (SeeMapping Functions).
 
    − They are more efficient.
 
    − They can be used as “place forms” to store values (See
      Generalized Variables).
 
    − They behave in a more predictable way than ‘cl-defsubst’ (See
      (cl)Argument Lists).
 
    Like ‘defmacro’, a function inlined with ‘define-inline’ inherits the
 scoping rules, either dynamic or lexical, from the call site.  See
 Variable Scoping.
 
    The following macros should be used in the body of a function defined
 by ‘define-inline’.
 
  -- Macro: inline-quote expression
      Quote EXPRESSION for ‘define-inline’.  This is similar to the
      backquote (SeeBackquote), but quotes code and accepts only
      ‘,’, not ‘,@’.
 
  -- Macro: inline-letevals (bindings...) body...
      This is is similar to ‘let’ (SeeLocal Variables): it sets up
      local variables as specified by BINDINGS, and then evaluates BODY
      with those bindings in effect.  Each element of BINDINGS should be
      either a symbol or a list of the form ‘(VAR EXPR)’; the result is
      to evaluate EXPR and bind VAR to the result.  The tail of BINDINGS
      can be either ‘nil’ or a symbol which should hold a list of
      arguments, in which case each argument is evaluated, and the symbol
      is bound to the resulting list.
 
  -- Macro: inline-const-p expression
      Return non-‘nil’ if the value of EXPRESSION is already known.
 
  -- Macro: inline-const-val expression
      Return the value of EXPRESSION.
 
  -- Macro: inline-error format &rest args
      Signal an error, formatting ARGS according to FORMAT.
 
    Here’s an example of using ‘define-inline’:
 
      (define-inline myaccessor (obj)
        (inline-letevals (obj)
          (inline-quote (if (foo-p ,obj) (aref (cdr ,obj) 3) (aref ,obj 2)))))
 
 This is equivalent to
 
      (defsubst myaccessor (obj)
        (if (foo-p obj) (aref (cdr obj) 3) (aref obj 2)))