We wish to count the teeth in a gear train represented as an ordered list of ordered triples. Each triple represents a gear cluster, and consists of an identifier, an ordered list of integers (the "numerator" gears), and an equally long list of "denominator" gears. If the last n numerator gears coincide with the last n of some later cluster, then the last n+1 denominator gears coincide also, and these two clusters share those gears, and we want to count their teeth only once. (defun teeth (train) (loop for clusters on train sum (+ (toot clusters #'second) (toot clusters #'third)))) (defun toot (clusters accessor &aux (gears (funcall accessor (first clusters)))) (if (or (null gears) (some #'(lambda (cluster) (loop for cogs on (funcall accessor cluster) when (equal gears cogs) return 't)) (rest clusters))) 0 (+ (first gears) (toot clusters #'(lambda (cluster) (cdr (funcall accessor cluster))))))) toot counts the numerator or denominator teeth of a cluster, depending on the accessor. When it finds an unshared gear, it adds it to the count of the rest of its list. But the list per se is not a transmitted argument on which to recurse. So we put the CDR in accessor! Termination is not running out of clusters, but rather running out of gears in the first cluster. --rwg