mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-28 07:45:00 +00:00
Document cl-generic.el
* doc/lispref/functions.texi (Generic Functions): New section. (Bug#22336) (Functions): Update the chapter menu. * doc/lispref/elisp.texi: Update the master menu.
This commit is contained in:
parent
7c3d742c35
commit
849a314c7a
@ -536,6 +536,7 @@ Functions
|
||||
* Calling Functions:: How to use an existing function.
|
||||
* Mapping Functions:: Applying a function to each element of a list, etc.
|
||||
* Anonymous Functions:: Lambda expressions are functions with no names.
|
||||
* Generic Functions:: Polymorphism, Emacs-style.
|
||||
* Function Cells:: Accessing or setting the function definition
|
||||
of a symbol.
|
||||
* Closures:: Functions that enclose a lexical environment.
|
||||
|
@ -18,6 +18,7 @@ define them.
|
||||
* Calling Functions:: How to use an existing function.
|
||||
* Mapping Functions:: Applying a function to each element of a list, etc.
|
||||
* Anonymous Functions:: Lambda expressions are functions with no names.
|
||||
* Generic Functions:: Polymorphism, Emacs-style.
|
||||
* Function Cells:: Accessing or setting the function definition
|
||||
of a symbol.
|
||||
* Closures:: Functions that enclose a lexical environment.
|
||||
@ -1092,6 +1093,230 @@ the compiled code. The byte-compiler cannot assume this list is a
|
||||
function, even though it looks like one, since it does not know that
|
||||
@code{change-property} intends to use it as a function.
|
||||
|
||||
@node Generic Functions
|
||||
@section Generic Functions
|
||||
@cindex generic functions
|
||||
@cindex polymorphism
|
||||
|
||||
Functions defined using @code{defun} have a hard-coded set of
|
||||
assumptions about the types and expected values of their arguments.
|
||||
For example, a function that was designed to handle values of its
|
||||
argument that are either numbers or lists of numbers will fail or
|
||||
signal an error if called with a value of any other type, such as a
|
||||
vector or a string. This happens because the implementation of the
|
||||
function is not prepared to deal with types other than those assumed
|
||||
during the design.
|
||||
|
||||
By contrast, object-oriented programs use @dfn{polymorphic
|
||||
functions}: a set of specialized functions having the same name, each
|
||||
one of which was written for a certain specific set of argument types.
|
||||
Which of the functions is actually called is decided at run time based
|
||||
on the types of the actual arguments.
|
||||
|
||||
@cindex CLOS
|
||||
Emacs provides support for polymorphism. Like other Lisp
|
||||
environments, notably Common Lisp and its Common Lisp Object System
|
||||
(@acronym{CLOS}), this support is based on @dfn{generic functions}.
|
||||
The Emacs generic functions closely follow @acronym{CLOS}, including
|
||||
use of similar names, so if you have experience with @acronym{CLOS},
|
||||
the rest of this section will sound very familiar.
|
||||
|
||||
A generic function specifies an abstract operation, by defining its
|
||||
name and list of arguments, but (usually) no implementation. The
|
||||
actual implementation for several specific classes of arguments is
|
||||
provided by @dfn{methods}, which should be defined separately. Each
|
||||
method that implements a generic function has the same name as the
|
||||
generic function, but the method's definition indicates what kinds of
|
||||
arguments it can handle by @dfn{specializing} the arguments defined by
|
||||
the generic function. These @dfn{argument specializers} can be more
|
||||
or less specific; for example, a @code{string} type is more specific
|
||||
than a more general type, such as @code{sequence}.
|
||||
|
||||
Note that, unlike in message-based OO languages, such as C@t{++} and
|
||||
Simula, methods that implement generic functions don't belong to a
|
||||
class, they belong to the generic function they implement.
|
||||
|
||||
When a generic function is invoked, it selects the applicable
|
||||
methods by comparing the actual arguments passed by the caller with
|
||||
the argument specializers of each method. A method is applicable if
|
||||
the actual arguments of the call are compatible with the method's
|
||||
specializers. If more than one method is applicable, they are
|
||||
combined using certain rules, described below, and the combination
|
||||
then handles the call.
|
||||
|
||||
@defmac cl-defgeneric name arguments [documentation] [options-and-methods@dots{}] &rest body
|
||||
This macro defines a generic function with the specified @var{name}
|
||||
and @var{arguments}. If @var{body} is present, it provides the
|
||||
default implementation. If @var{documentation} is present (it should
|
||||
always be), it specifies the documentation string for the generic
|
||||
function, in the form @code{(:documentation @var{docstring})}. The
|
||||
optional @var{options-and-methods} can be one of the following forms:
|
||||
|
||||
@table @code
|
||||
@item (declare @var{declarations})
|
||||
A declare form, as described in @ref{Declare Form}.
|
||||
@item (:argument-precedence-order &rest @var{args})
|
||||
This form affects the sorting order for combining applicable methods.
|
||||
Normally, when two methods are compared during combination, method
|
||||
arguments are examined left to right, and the first method whose
|
||||
argument specializer is more specific will come before the other one.
|
||||
The order defined by this form overrides that, and the arguments are
|
||||
examined according to their order in this form, and not left to right.
|
||||
@item (:method [@var{qualifiers}@dots{}] args &rest body)
|
||||
This form defines a method like @code{cl-defmethod} does.
|
||||
@end table
|
||||
@end defmac
|
||||
|
||||
@defmac cl-defmethod name [qualifier] arguments &rest [docstring] body
|
||||
This macro defines a particular implementation for the generic
|
||||
function called @var{name}. The implementation code is given by
|
||||
@var{body}. If present, @var{docstring} is the documentation string
|
||||
for the method. The @var{arguments} list, which must be identical in
|
||||
all the methods that implement a generic function, and must match the
|
||||
argument list of that function, provides argument specializers of the
|
||||
form @code{(@var{arg} @var{spec})}, where @var{arg} is the argument
|
||||
name as specified in the @code{cl-defgeneric} call, and @var{spec} is
|
||||
one of the following specializer forms:
|
||||
|
||||
@table @code
|
||||
@item @var{type}
|
||||
This specializer requires the argument to be of the given @var{type},
|
||||
one of the types from the type hierarchy described below.
|
||||
@item (eql @var{object})
|
||||
This specializer requires the argument be @code{eql} to the given
|
||||
@var{object}.
|
||||
@item (head @var{object})
|
||||
The argument must be a cons cell whose @code{car} is @code{eql} to
|
||||
@var{object}.
|
||||
@item @var{struct-tag}
|
||||
The argument must be an instance of a class named @var{struct-tag}
|
||||
defined with @code{cl-defstruct} (@pxref{Structures,,, cl, Common Lisp
|
||||
Extensions for GNU Emacs Lisp}), or of one of its parent classes.
|
||||
@end table
|
||||
|
||||
Alternatively, the argument specializer can be of the form
|
||||
@code{&context (@var{expr} @var{spec})}, in which case the value of
|
||||
@var{expr} must be compatible with the specializer provided by
|
||||
@var{spec}; @var{spec} can be any of the forms described above. In
|
||||
other words, this form of specializer uses the value of @var{expr}
|
||||
instead of arguments for the decision whether the method is
|
||||
applicable. For example, @code{&context (overwrite-mode (eql t))}
|
||||
will make the method compatible only when @code{overwrite-mode} is
|
||||
turned on.
|
||||
|
||||
The type specializer, @code{(@var{arg} @var{type})}, can specify one
|
||||
of the @dfn{system types} in the following list. When a parent type
|
||||
is specified, an argument whose type is any of its more specific child
|
||||
types, as well as grand-children, grand-grand-children, etc. will also
|
||||
be compatible.
|
||||
|
||||
@table @code
|
||||
@item integer
|
||||
Parent type: @code{number}.
|
||||
@item number
|
||||
@item null
|
||||
Parent type: @code{symbol}
|
||||
@item symbol
|
||||
@item string
|
||||
Parent type: @code{array}.
|
||||
@item array
|
||||
Parent type: @code{sequence}.
|
||||
@item cons
|
||||
Parent type: @code{list}.
|
||||
@item list
|
||||
Parent type: @code{sequence}.
|
||||
@item marker
|
||||
@item overlay
|
||||
@item float
|
||||
Parent type: @code{number}.
|
||||
@item window-configuration
|
||||
@item process
|
||||
@item window
|
||||
@item subr
|
||||
@item compiled-function
|
||||
@item buffer
|
||||
@item char-table
|
||||
Parent type: @code{array}.
|
||||
@item bool-vector
|
||||
Parent type: @code{array}.
|
||||
@item vector
|
||||
Parent type: @code{array}.
|
||||
@item frame
|
||||
@item hash-table
|
||||
@item font-spec
|
||||
@item font-entity
|
||||
@item font-object
|
||||
@end table
|
||||
|
||||
The optional @var{qualifier} allows to combine several applicable
|
||||
methods. If it is not present, the defined method is a @dfn{primary}
|
||||
method, responsible for providing the primary implementation of the
|
||||
generic function for the specialized arguments. You can also define
|
||||
@dfn{auxiliary methods}, by using one of the following values as
|
||||
@var{qualifier}:
|
||||
|
||||
@table @code
|
||||
@item :before
|
||||
This auxiliary method will run before the primary method. More
|
||||
accurately, all the @code{:before} methods will run before the
|
||||
primary, in the most-specific-first order.
|
||||
@item :after
|
||||
This auxiliary method will run after the primary method. More
|
||||
accurately, all such methods will run after the primary, in the
|
||||
most-specific-last order.
|
||||
@item :around
|
||||
This auxiliary method will run @emph{instead} of the primary method.
|
||||
The most specific of such methods will be run before any other method.
|
||||
Such methods normally use @code{cl-call-next-method}, described below,
|
||||
to invoke the other auxiliary or primary methods.
|
||||
@item :extra @var{string}
|
||||
This allows to add more methods, distinguished by @var{string}, for
|
||||
the same specializers and qualifiers.
|
||||
@end table
|
||||
@end defmac
|
||||
|
||||
@cindex dispatch of methods for generic function
|
||||
@cindex multiple-dispatch methods
|
||||
Each time a generic function is called, it builds the @dfn{effective
|
||||
method} which will handle this invocation by combining the applicable
|
||||
methods defined for the function. The process of finding the
|
||||
applicable methods and producing the effective method is called
|
||||
@dfn{dispatch}. The applicable methods are those all of whose
|
||||
specializers are compatible with the actual arguments of the call.
|
||||
Since all of the arguments must be compatible with the specializers,
|
||||
they all determine whether a method is applicable. Methods that
|
||||
explicitly specialize more than one argument are called
|
||||
@dfn{multiple-dispatch methods}.
|
||||
|
||||
The applicable methods are sorted into the order in which they will be
|
||||
combined. The method whose left-most argument specializer is the most
|
||||
specific one will come first in the order. (Specifying
|
||||
@code{:argument-precedence-order} as part of @code{cl-defmethod}
|
||||
overrides that, as described above.) If the method body calls
|
||||
@code{cl-call-next-method}, the next most-specific method will run.
|
||||
If there are applicable @code{:around} methods, the most-specific of
|
||||
them will run first; it should call @code{cl-call-next-method} to run
|
||||
any of the less specific @code{:around} methods. Next, the
|
||||
@code{:before} methods run in the order of their specificity, followed
|
||||
by the primary method, and lastly the @code{:after} methods in the
|
||||
reverse order of their specificity.
|
||||
|
||||
@defun cl-call-next-method &rest args
|
||||
When invoked from within the lexical body of a primary or an
|
||||
@code{:around} auxiliary method, call the next applicable method for
|
||||
the same generic function. Normally, it is called with no arguments,
|
||||
which means to call the next applicable method with the same arguments
|
||||
that the calling method was invoked. Otherwise, the specified
|
||||
arguments are used instead.
|
||||
@end defun
|
||||
|
||||
@defun cl-next-method-p
|
||||
This function, when called from within the lexical body of a primary
|
||||
or an @code{:around} auxiliary method, returns non-@code{nil} if there
|
||||
is a next method to call.
|
||||
@end defun
|
||||
|
||||
|
||||
@node Function Cells
|
||||
@section Accessing Function Cell Contents
|
||||
|
||||
|
4
etc/NEWS
4
etc/NEWS
@ -520,6 +520,7 @@ If you need your objects to be named, do it by inheriting from `eieio-named'.
|
||||
+++
|
||||
*** The <initarg> variables are declared obsolete.
|
||||
*** defgeneric and defmethod are declared obsolete.
|
||||
Use the equivalent facilities from cl-generic.el instead.
|
||||
+++
|
||||
*** `constructor' is now an obsolete alias for `make-instance'.
|
||||
|
||||
@ -1177,7 +1178,10 @@ command is called from Emacs (i.e., INSIDE_EMACS environment variable
|
||||
is set). This feature requires newer versions of GnuPG (2.1.5 or
|
||||
later) and Pinentry (0.9.5 or later).
|
||||
|
||||
+++
|
||||
** cl-generic.el provides CLOS-style multiple-dispatch generic functions.
|
||||
The main entry points are `cl-defgeneric' and `cl-defmethod'. See the
|
||||
node "Generic Functions" in the Emacs Lisp manual for more details.
|
||||
|
||||
---
|
||||
** scss-mode (a minor variant of css-mode)
|
||||
|
Loading…
Reference in New Issue
Block a user