Lisp - Class Precedence



Class precedence is a crucial concept of CLOS, Common LISP Object System. It refers to ordering of a class and its subclasses. Class precdence is very important in case of inheritance especially multiple inheritance.

Class precedence defines the inheritance hiearchy in a linear fashion even in case of complex multiple inheritance. In multiple inheritance, a class can inherit from multiple classes. In case a method with same name is getting inherited then to solve such ambiguity, class precedence plays an important role in resolving these conflicting by providing a clear precedence order.

How Class Precedence Works?

  • A class precedence list is prepared in order superclasses are defined in defclass form.

  • When a geric function is called, CLOS uses the class precedence list to determine which method to execute.

  • A most specific method is called on the basis of the class of the object used.

Example - primary Function

Following is the complete example of a primary function.

main.lisp

; define a class A
(defclass A () ())
; define a class B
(defclass B () ())
; define a class C inheriting A and B
(defclass C (A B) ())
; define a class D inheriting B and A
(defclass D (B A) ())

; A T
(print (class-precedence-list (find-class 'A))) 
(terpri)
; B T
(print (class-precedence-list (find-class 'B))) 
(terpri)
; C A B T
(print (class-precedence-list (find-class 'C))) 
(terpri)
; D B A T
(print (class-precedence-list (find-class 'D))) 

Output

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

(#<STANDARD-CLASS A> #<STANDARD-CLASS STANDARD-OBJECT> #<BUILT-IN-CLASS T>) 
(#<STANDARD-CLASS B> #<STANDARD-CLASS STANDARD-OBJECT> #<BUILT-IN-CLASS T>) 
(#<STANDARD-CLASS C> #<STANDARD-CLASS A> #<STANDARD-CLASS B> #<STANDARD-CLASS STANDARD-OBJECT> #<BUILT-IN-CLASS T>) 
(#<STANDARD-CLASS D> #<STANDARD-CLASS B> #<STANDARD-CLASS A> #<STANDARD-CLASS STANDARD-OBJECT> #<BUILT-IN-CLASS T>) 

Explanation

  • (defclass A () ()) (defclass B () ()) − Two base classes A and B are defined. As there is no superclasses, precedence list of A and B is simply themselves followed by T.

  • (defclass C (A B) ()) − C class inherits A and B, so precedence list maintains the order in which C inherits A and B. And precedence list of C comes as C A B followed by T.

  • (defclass D (B A) ()) − D class inherits B and A, as precedence list maintains the order in which D inherits B and A. And precedence list of D comes as D B A followed by T.

Key Considerations

  • Class precedence is dependent on the order in which superclasses are used in defclass.

  • CLOS ensures that in class precedence, a class appears before its superclasses.

  • CLOS ensures that there is no cyclic loop in class precedence list.

  • Class T is always present at the end of the precedence list.

  • When a class inherits multiple classes, class precedence list prefers local order of superclasses ensure that entire list is consistent.

Advertisements