Forgetting to ensure class finalization seems to be quite common mistake when using MOP.
In lisp, classes are defined in two "phases":
- Direct class definition
- Effective class definition
Direct class definition is isomorphic to defclass
form. It has class name, names of superclasses, list of direct slots (i.e., slots defined on this particular class but on its superclasses).
Effective class definition contains all information needed for compiler/interpreter. It contains list of all class slots (including those defined on superclasses), class instance layout, references to accessor methods, etc.
Process of transforming direct class definition to effective class definition is called class finalization. Since CLOS supports redefining classes, finalization might be called multiple times for a class. One of the reasons why finalization is delayed is because class may be defined before its superclasses are defined.
Regarding your particular problem: is seems that optima:match
should ensure that class is finalized before trying to list its slots. This can be done with two functions: class-finalized-p
(to check whether class needs finalization) and finalize-inheritance
to actually perform finalization. Or you can use utility function closer-mop:ensure-finalized
. (closer-mop is a library for portable usage of CLOS MOP).
E.g.,:
(c2mop:ensure-finalized (find-class 'expression))