User Tools

A PCRE internal error occured. This might be caused by a faulty plugin

====== Macro DEFMETHOD ====== ====Syntax==== * **defmethod** //function-name// {//method-qualifier//}''*'' //specialized-lambda-list//} ⟦{declaration}''*'' | //documentation//⟧ {//form//}''*'' → //new-method// <blockquote> function-name ::= {__symbol__ | ([[CL:Macros:setf]] __symbol__)} method-qualifier ::= __non-list__ specialized-lambda-list ::= ({//var// | (//var// __parameter-specializer-name__)}''*'' [**&optional** {//var// | (//var// __parameter-specializer-name__)}''*''] [**&rest** //var//] [**&key** {//var// | ({//var// | (__keyword__ //var//)} [//initform// [//supplied-p-parameter//]])}''*'' [**&allow-other-keys**]] [**&aux** {//var// | (//var// [//initform//])}''*'']) parameter-specializer-name ::= __symbol__ | ([[CL:Types:eql]] //eql-specializer-form//) </blockquote> ====Arguments and Values==== * //declaration// - a **[[CL:Symbols:declare]]** //[[CL:Glossary:expression]]//; not evaluated. * //documentation// - a //[[CL:Glossary:string]]//; not evaluated. * //var// - a //[[CL:Glossary:variable]]// //[[CL:Glossary:name]]//. * //eql-specializer-form// - a //[[CL:Glossary:form]]//. * //form// - a //[[CL:Glossary:form]]//. * //initform// - a //[[CL:Glossary:form]]//. * //supplied-p-parameter// - variable name. * //new-method// - the new //[[CL:Glossary:method]]// //[[CL:Glossary:object]]//. ====Description==== The macro **defmethod** defines a //[[CL:Glossary:method]]// on a //[[CL:Glossary:generic function]]//. If ''([[CL:Functions:fboundp]] //function-name//)]]'' is **[[CL:Constant Variables:nil]]**, a //[[CL:Glossary:generic function]]// is created with default values for the argument precedence order (each argument is more specific than the arguments to its right in the argument list), for the generic function class (the **[[CL:Types:standard-generic-function]]** //[[CL:Glossary:class]]//), for the method class (the **[[CL:Types:standard-method]]** //[[CL:Glossary:class]]//), and for the method combination type (the standard method combination type). The //[[CL:Glossary:lambda list]]// of the //[[CL:Glossary:generic function]]// is congruent with the //[[CL:Glossary:lambda list]]// of the //[[CL:Glossary:method]]// being defined; if the **defmethod** form mentions keyword arguments, the //[[CL:Glossary:lambda list]]// of the //[[CL:Glossary:generic function]]// will mention **'':&key''** (but no keyword arguments). If //function-name// names an //[[CL:Glossary:ordinary function]]//, a //[[CL:Glossary:macro]]//, or a //[[CL:Glossary:special operator]]//, an error is signaled. If a //[[CL:Glossary:generic function]]// is currently named by //function-name//, the //[[CL:Glossary:lambda list]]// of the //[[CL:Glossary:method]]// must be congruent with the //[[CL:Glossary:lambda list]]// of the //[[CL:Glossary:generic function]]//. If this condition does not hold, an error is signaled. For a definition of congruence in this context, see section {\secref\GFMethodLambdaListCongruency}. Each //method-qualifier// argument is an //[[CL:Glossary:object]]// that is used by method combination to identify the given //[[CL:Glossary:method]]//. The method combination type might further restrict what a method //[[CL:Glossary:qualifier]]// can be. The standard method combination type allows for //[[CL:Glossary:unqualified methods]]// and //[[CL:Glossary:method|methods]]// whose sole //[[CL:Glossary:qualifier]]// is one of the keywords **'':before''**, **'':after''**, or **'':around''**. The //specialized-lambda-list// argument is like an ordinary //[[CL:Glossary:lambda list]]// except that the //[[CL:Glossary:names]]// of required parameters can be replaced by specialized parameters. A specialized parameter is a list of the form ''(//var// //parameter-specializer-name//)''. Only required parameters can be specialized. If //parameter-specializer-name// is a //[[CL:Glossary:symbol]]// it names a //[[CL:Glossary:class]]//; if it is a //[[CL:Glossary:list]]//, it is of the form ''([[CL:Types:eql]] //eql-specializer-form//)''. The parameter specializer name ''([[CL:Types:eql]] //eql-specializer-form//)'' indicates that the corresponding argument must be **[[CL:Functions:eql]]** to the //[[CL:Glossary:object]]// that is the value of //eql-specializer-form// for the //[[CL:Glossary:method]]// to be applicable. The //eql-specializer-form// is evaluated at the time that the expansion of the **defmethod** macro is evaluated. If no //[[CL:Glossary:parameter specializer name]]// is specified for a given required parameter, the //[[CL:Glossary:parameter specializer]]// defaults to the **[[CL:Types:t]]** //[[CL:Glossary:class]]//. For further discussion, see section {\secref\IntroToMethods}. The //form// arguments specify the method body. The body of the //[[CL:Glossary:method]]// is enclosed in an //[[CL:Glossary:implicit block]]//. If //function-name// is a //[[CL:Glossary:symbol]]//, this block bears the same //[[CL:Glossary:name]]// as the //[[CL:Glossary:generic function]]//. If //function-name// is a //[[CL:Glossary:list]]// of the form ''([[CL:Macros:setf]] //symbol//)'', the //[[CL:Glossary:name]]// of the block is //symbol//. The //[[CL:Glossary:class]]// of the //[[CL:Glossary:method]]// //[[CL:Glossary:object]]// that is created is that given by the method class option of the //[[CL:Glossary:generic function]]// on which the //[[CL:Glossary:method]]// is defined. If the //[[CL:Glossary:generic function]]// already has a //[[CL:Glossary:method]]// that agrees with the //[[CL:Glossary:method]]// being defined on //[[CL:Glossary:parameter specializer|parameter specializers]]// and //[[CL:Glossary:qualifier|qualifiers]]//, **defmethod** replaces the existing //[[CL:Glossary:method]]// with the one now being defined. For a definition of agreement in this context. see section {\secref\SpecializerQualifierAgreement}. The //[[CL:Glossary:parameter specializer|parameter specializers]]// are derived from the //[[CL:Glossary:parameter specializer names]]// as described in \secref\IntroToMethods. The expansion of the **defmethod** macro "refers to" each specialized parameter (see the description of **[[CL:Declarations:ignore]]** within the description of **[[CL:Symbols:declare]]**). This includes parameters that have an explicit //[[CL:Glossary:parameter specializer name]]// of **[[CL:Types:t]]**. This means that a compiler warning does not occur if the body of the //[[CL:Glossary:method]]// does not refer to a specialized parameter, while a warning might occur if the body of the //[[CL:Glossary:method]]// does not refer to an unspecialized parameter. For this reason, a parameter that specializes on **[[CL:Types:t]]** is not quite synonymous with an unspecialized parameter in this context. Declarations at the head of the method body that apply to the method's //[[CL:Glossary:lambda variables]]// are treated as //[[CL:Glossary:bound declarations]]// whose //[[CL:Glossary:scope]]// is the same as the corresponding //[[CL:Glossary:bindings]]//. Declarations at the head of the method body that apply to the functional bindings of **[[CL:Functions:call-next-method]]** or **[[CL:Functions:next-method-p]]** apply to references to those functions within the method body //forms//. Any outer //[[CL:Glossary:bindings]]// of the //[[CL:Glossary:function names]]// **[[CL:Functions:call-next-method]]** and **[[CL:Functions:next-method-p]]**, and declarations associated with such //[[CL:Glossary:bindings]]// are //[[CL:Glossary:shadowed]]// within the method body //forms//. The //[[CL:Glossary:scope]]// of //[[CL:Glossary:free declarations]]// at the head of the method body is the entire method body, which includes any implicit local function definitions but excludes //[[CL:Glossary:initialization form|initialization forms]]// for the //[[CL:Glossary:lambda variables]]//. **defmethod** is not required to perform any compile-time side effects. In particular, the //[[CL:Glossary:method|methods]]// are not installed for invocation during compilation. An //[[CL:Glossary:implementation]]// may choose to store information about the //[[CL:Glossary:generic function]]// for the purposes of compile-time error-checking (such as checking the number of arguments on calls, or noting that a definition for the function name has been seen). //Documentation// is attached as a //[[CL:Glossary:documentation string]]// to the //[[CL:Glossary:method]]// //[[CL:Glossary:object]]//. ====Examples==== None. ====Affected By==== The definition of the referenced //[[CL:Glossary:generic function]]//. ====Exceptional Situations==== If //function-name// names an //[[CL:Glossary:ordinary function]]//, a //[[CL:Glossary:macro]]//, or a //[[CL:Glossary:special operator]]//, an error of type **[[CL:Types:error]]** is signaled. If a //[[CL:Glossary:generic function]]// is currently named by //function-name//, the //[[CL:Glossary:lambda list]]// of the //[[CL:Glossary:method]]// must be congruent with the //[[CL:Glossary:lambda list]]// of the //[[CL:Glossary:generic function]]//, or an error of type **[[CL:Types:error]]** is signaled. ====See Also==== * **[[CL:Macros:defgeneric|Macro DEFGENERIC]]** * **[[CL:Functions:documentation|Generic Function DOCUMENTATION]]** * {\secref\IntroToMethods} * {\secref\GFMethodLambdaListCongruency} * {\secref\SpecializerQualifierAgreement} * {\secref\DocVsDecls} ====Notes==== None. \issue{DECLS-AND-DOC} \issue{DEFMETHOD-DECLARATION-SCOPE:CORRESPONDS-TO-BINDINGS} \issue{COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY} \issue{DOCUMENTATION-FUNCTION-BUGS:FIX}