;; とりあえず質問者からの動作報告求む
(defun* co (x lst &optional (compare 'eq))
"COMPAREで比較関数を指定できるようにしてみた。
引数無しでは`eq'を使って比較する。"
(assert (listp lst))
(labels ((f (lst acc)
(let ((cur (car lst)))
(cond ((null cur) nil)
((and (atom cur)) (if (funcall compare x cur) (cons 'car acc)
(f (cdr lst) (cons 'cdr acc))))
((listp cur) (or (f (car lst) (cons 'car acc))
(f (cdr lst) (cons 'cdr acc))))
(t (error "unexpected lst: %s" cur))))))
(f lst '())))
;; てすけ
(expectations
(error (co 'a '()))
(expect (co 'not-found '()))
(expect (co 'a '(a)) '(car))
(expect (co 'b '(a b c)) '(car cdr))
(expect (co 'c '(a b c)) '(car cdr cdr))
(expect (co 'x '((x) a b c)) '(car car))
(expect (co 'x '((a b c x) d e f)) '(car cdr cdr cdr car))
(expect (co 'x '(a b (c x d) e f)) '(car cdr car cdr cdr))
(expect (co "foo" '("bar" "foo") 'string=) '(car cdr)))