LISP - :primary Method Combination
Lisp - Understanding Method Combination
Section titled “Lisp - Understanding Method Combination”In the Common Lisp Object System (CLOS), method combination defines the process by which all applicable methods for a generic function call are combined into one effective method. The Standard Method Combination is the default and most commonly used type. It orchestrates the execution of methods based on their roles, which are specified by qualifiers.
The most fundamental type of method is a primary method. These are methods defined without any qualifiers. In the standard combination, CLOS calls the single most specific primary method. This method is responsible for providing the main logic and returning the final value of the generic function call.
Key Concepts
Section titled “Key Concepts”- Generic Function (
defgeneric): Defines a function’s name and parameter list, acting as a dispatcher. It can also specify the method combination type, butstandardis the default. - Method (
defmethod): Provides a concrete implementation for a generic function for specific parameter types (classes). - Primary Method: A method with no qualifier. It forms the core logic. In the default
standardcombination, only the most specific one is executed. - Auxiliary Methods: Methods with qualifiers like
:before,:after, and:around. They augment the behavior of the primary method. This tutorial focuses only on primary methods.
Defining a Generic Function and Primary Methods
Section titled “Defining a Generic Function and Primary Methods”First, we define a generic function. Then, we provide different method implementations for different data types.
;; Define a generic function named 'combine' that accepts two arguments.;; By default, it uses the standard method combination.(defgeneric combine (x y))
;; Define a primary method for the 'combine' generic function.;; This method specializes on 'x' and 'y' both being of type 'number'.(defmethod combine ((x number) (y number)) "This primary method handles the case where both arguments are numbers." (+ x y))
;; Define another primary method for 'string' types.(defmethod combine ((x string) (y string)) "This primary method handles the case where both arguments are strings." (concatenate 'string x y))When combine is called, CLOS inspects the types of the arguments and dispatches the call to the most specific matching method.
Practical Example
Section titled “Practical Example”Let’s create a complete, runnable example that demonstrates how different primary methods are invoked based on argument types.
main.lisp
Section titled “main.lisp”;; Modern Lisp development often starts with defining a package.(defpackage #:method-combination-example (:use #:cl))(in-package #:method-combination-example)
;; 1. Define a generic function.(defgeneric combine (x y) (:documentation "Combines two objects based on their type."))
;; 2. Define a primary method for numbers.(defmethod combine ((x number) (y number)) "When combining two numbers, return their sum." (+ x y))
;; 3. Define a primary method for strings.(defmethod combine ((x string) (y string)) "When combining two strings, return their concatenation." (concatenate 'string x y))
;; 4. Define a primary method for lists.(defmethod combine ((x list) (y list)) "When combining two lists, append them." (append x y))
;; --- Demonstrate the dispatch ---(format t "Combining numbers 10 and 20: ~a~%" (combine 10 20))(format t "Combining strings \"Hello\" and \" World!\": ~a~%" (combine "Hello" " World!"))(format t "Combining lists '(1 2) and '(3 4): ~a~%" (combine '(1 2) '(3 4)))Output
Section titled “Output”Combining numbers 10 and 20: 30Combining strings "Hello" and " World!": Hello World!Combining lists '(1 2) and '(3 4): (1 2 3 4)Explanation
Section titled “Explanation”When the generic function combine is called, the Common Lisp runtime examines the types of the arguments provided and selects the most specific primary method to execute:
(combine 10 20): Both arguments arenumbers. The number-specialized method is invoked, returning their sum,30.(combine "Hello" " World!"): Both arguments arestrings. The string-specialized method is invoked, returning the concatenated string,"Hello World!".(combine '(1 2) '(3 4)): Both arguments arelists. The list-specialized method is invoked, returning the appended list,(1 2 3 4).
Further Learning
Section titled “Further Learning”While primary methods are the workhorses, the true power of method combination comes from using auxiliary methods (:before, :after, :around) to create sophisticated, layered behavior. For instance, you could add an :around method to log every call to combine regardless of the argument types.