> (subst 'a 'b '(a b c)) (A A C) > (subst 'a 'b '((a) (b) (c))) ((A) (A) (C)) > (subst 'a 'b '((a) (b) b ((c b) ((b) c d b)))) ((A) (A) A ((C A) ((A) C D A))) > (subst 'a '(b) '((a) (b) b ((c b) ((b) c d b)))) ((A) (B) B ((C B) ((B) C D B))) > (subst 'a '(b) '((a) (b) b ((c b) ((b) c d b))) :test #'equal) ((A) A B ((C . A) (A C D . A)))
(defun subst (new old data &key (test #'eq)) (cond ((atom data) (if (funcall test old data) new data)) ((funcall test old (car data)) (cons new (subst new old (cdr data) :test test))) (t (cons (subst new old (car data) :test test) (subst new old (cdr data) :test test)))))リスト全体をコピーする関数としてCommon Lispには,copy-list(トップレ ベルのみのコピー), copy-alist(トップレベルのコンスのみ), copy-tree(トップレベルだけでなく内部も)というものがあります.
(defun list-copy (sexp) (if (atom sexp) sexp (cons (list-copy (car sexp)) (list-copy (cdr sexp)))))という形に定義できますが,substで以下のように 定義もできます.
(defun list-copy (a) (subst t t a))