Circa 1984:
(defclass person ()
((name :initarg :name :accessor person-name)
(age :initarg :age :accessor person-age)))
(defmethod person-age :after ((someone person))
(let* ((age (person-age someone))
(category (if (< age 16)
:child
(if (>= age 66)
:senior
:adult))))
(values age category)))
Instead of having some outside "ticket" function to categorize the age of a person, you should just instrument the generated PERSON-AGE accessor to add the extra info you need. That way you don't need to modify the rest of your system to use this data in non-standard ways. The accounting module, for example, can take care of senior citizen and kid discounts of tickets without having to be told about it. The system would extensible, without rewrite, once you want to add seasonal discounts and other business-requirement unapparent during development. (Looking into ContextL and Context Oriented Programming.)Similary, print-name shouldn't exist as a standalone function for something so mundane. You should just augment the builtin PRINT-OBJECT method that specializes on the PERSON class to print suitable titles. You don't even have to instrument the main PRINT-OBJECT, just the one that prints the actual receipt to the paper-printing HARDCOPY stream.
(defmethod print-object :around ((someone person)
(stream hardcopy))
(when (next-method-p)
(let ((obj (call-next-method)))
...
...
(with-open-printer (lpr #p"/dev/printer")
(format lpr "..")))) ...
I mean, seriously; I hope we're not blogging back and forth about CLOS-101 applications of methods.