Generate visitor functions across types using a visitor template.
To use defvisitors, first see defvisitor-template and defvisitor. Defvisitors automates the generation of several defvisitor forms that create a system of visitor functions that works on a nest of types.
For example, suppose we have the following types:
(defprod employee ((name stringp) (salary natp) (title stringp))) (deflist employees :elt-type employee) (defprod group ((lead employee) (members employees) (budget natp) (name stringp) (responsibilities string-listp))) (defprod division ((head employee) (operations group) (engineering group) (sales group) (service group) (black-ops group)))
Suppose we want to total up the salaries of all the employees in a division, including the division head, group leads, and group members. A visitor template for this operation might look like this:
(defvisitor-template salary-total ((x :object)) :returns (total (:join (+ total1 total) :tmp-var total1 :initial 0) natp :rule-classes :type-prescription "The total salary of all employees") :type-fns ((employee employee->salary)))
Now we need visitor functions for the employees, group, and division types, so we can do:
(defvisitor :type employees :template salary-total) (defvisitor :type group :template salary-total) (defvisitor :type division :template salary-total)
However, we can automate this more by using defvisitors instead of defvisitor. This doesn't seem worthwhile to get rid of just three defvisitor forms, but oftentimes the type hierarchy is much more specialized than this, and changes frequently. Using defvisitors can prevent the need to modify the code if you add a type to the hierarchy. To invoke it:
(defvisitors division-salary-total ;; optional event name :types (division) :template salary-total)
This searches over the field types of the
The options for