Common Lisp does not have interfaces in the sense that some languages (e.g., Java) do, and there is less need for that type of interface given that Common Lisp supports multiple inheritance and generic functions. However, the same type of patterns can be realized easily using mixin classes. This example shows the specification of a collection interface with several corresponding generic functions.
;; Specification of the COLLECTION "interface"
(defclass collection () ()
(:documentation "A collection mixin."))
(defgeneric collection-elements (collection)
(:documentation "Returns a list of the elements in the collection."))
(defgeneric collection-add (collection element)
(:documentation "Adds an element to the collection."))
(defgeneric collection-remove (collection element)
(:documentation "Removes the element from the collection, if it is present."))
(defgeneric collection-empty-p (collection)
(:documentation "Returns whether the collection is empty or not."))
(defmethod collection-empty-p ((c collection))
"A 'default' implementation of COLLECTION-EMPTY-P that tests
whether the list returned by COLLECTION-ELEMENTS is the empty
list."
(endp (collection-elements c)))
An implementation of the interface is just a class that has the mixin as one of its super classes, and definitions of the appropriate generic functions. (At this point, notice that the mixin class is really only for signalling the intent that the class implements the "interface". This example would work just as well with a few generic functions and documentation that states that there are methods on the function for the class.)
;; Implementation of a sorted-set class
(defclass sorted-set (collection)
((predicate
:initarg :predicate
:reader sorted-set-predicate)
(test
:initarg :test
:initform 'eql
:reader sorted-set-test)
(elements
:initform '()
:accessor sorted-set-elements
;; We can "implement" the COLLECTION-ELEMENTS function, that is,
;; define a method on COLLECTION-ELEMENTS, simply by making it
;; a reader (or accessor) for the slot.
:reader collection-elements)))
(defmethod collection-add ((ss sorted-set) element)
(unless (member element (sorted-set-elements ss)
:test (sorted-set-test ss))
(setf (sorted-set-elements ss)
(merge 'list
(list element)
(sorted-set-elements ss)
(sorted-set-predicate ss)))))
(defmethod collection-remove ((ss sorted-set) element)
(setf (sorted-set-elements ss)
(delete element (sorted-set-elements ss))))
Finally, we can see what using an instance of the sorted-set class looks like when using the "interface" functions:
(let ((ss (make-instance 'sorted-set :predicate '<)))
(collection-add ss 3)
(collection-add ss 4)
(collection-add ss 5)
(collection-add ss 3)
(collection-remove ss 5)
(collection-elements ss))
;; => (3 4)