Lisp - Method Combinations



Method Combination is a key mechanism of CLOS, a object oriented programming in LISP. Method combination refers to mechanism how to combine results of multiple methods while using generic functions. In this chapter, we'll explore various ways how to combine methods results.

Standard Method Combination

This is the most commonly used type for method combination. It involves following types of methods −

  • :before method − These methods are invoked before execution of primary method and are executed in most-specific-first order.

  • :primary method − A primary method defines the core functionality of a generic function. Most specific primary method is generally used.

  • :after method − These methods are invoked after execution of primary method and are executed in most-specific-last order.

  • :around method − These methods wraps around the entire generic funtion call. call-next-method order is used to decide the next applicable method.

Other Method Combination

In LISP, we've other inbuilt method combination types as well.

  • + − Using +, we can combine results of two functions by addition.

  • and − Using and, we can combine results of two functions by logical AND.

  • append − Using append, we can combine results of two functions by appending lists.

We can define custom combination types as well.

Key Considerations

  • Using method combination, we can customize behavior of generic function.

  • We can add pre processing and post processing behavior to generic function calls.

  • We can perform custom method combinations as well which makes LISP very flexible and customizable.

Example - Method Combination

main.lisp

; define a generic function
(defgeneric process-item (item))

; define before function to be called before generic function for item
(defmethod process-item :before ((item t))
  (format t "process-item is called: ~a~%" item))

; define generic method implementation for integer
(defmethod process-item ((item integer))
  (format t "Processing integer: ~a, result: ~a~%" item (* item 2)))

; define generic method implementation for string
(defmethod process-item ((item string))
  (format t "Processing string: ~a, result: ~a~%" item (concatenate 'string item " processed")))

; process number
(process-item 10)

; process string
(process-item "test")

Output

When you execute the code, it returns the following result −

process-item is called: 10
Processing integer: 10, result: 20
process-item is called: test
Processing string: test, result: test processed
Advertisements