Generic functions in Lisp
One defgeneric, two defmethod bodies, and the argument's class picks which body runs.
;; One generic function, two methods, dispatch chosen by argument class.
(defclass document () ((title :initarg :title :accessor doc-title)))
(defclass invoice (document) ((total :initarg :total :accessor total-of)))
(defclass memo (document) ((body :initarg :body :accessor body-of)))
(defgeneric summarize (item)
(:documentation "Return a one-line summary string for ITEM."))
(defmethod summarize ((item invoice))
(format nil "~a: ~$ due" (doc-title item) (total-of item)))
(defmethod summarize ((item memo))
(format nil "~a: ~d characters" (doc-title item) (length (body-of item))))
(dolist (item (list (make-instance 'invoice :title "Q3" :total 240.5)
(make-instance 'memo :title "Standup" :body "ship it")))
(format t "~a~%" (summarize item)))
How it works
invoiceandmemoboth inherittitlefrom thedocumentbase class.defgeneric summarizedeclares the contract; each method specializes on(item invoice)or(item memo).- The closing
dolistcallssummarizeon one of each and gets different output per class.
Keywords and builtins used here
defclassdefgenericdefmethoddolistformatlengthlist
The run, in numbers
- Lines
- 18
- Characters to type
- 753
- Tokens
- 142
- Three-star pace
- 70 tpm
At the three-star pace of 70 tokens a minute, this run takes about 122 seconds.
Step 3 of 3 in Structures & CLOS, step 21 of 27 in Language basics.