delete-1

さて、半年つんどくしていました「プログラミングGauche」。
続きからやろうと思ったら「今まで何やってたっけ?」っていう感じだったので、9章の始めからつらつらと読んでた。
で、つまずいてたdelete-1のnon-copyバージョンを書いてみると、割とすらすらと書けた。
たぶん、これはヒントの言い回しに惑わされていた気がする。

112ページのヒントを引用。

ヒント:再帰的に考えます。もしそれを実現するdelete-1が存在して、(cdr lis)に<要素>が含まれていないなら、(delete-1 elt (cdr lis))と(cdr lis)はeq?になるはず...

「もしそれを実現するdelete-1が存在して」なんて言い回し、なんでするのかな?
存在することが前提の問題だよね。
僕は頭が悪いので、他の人にとっては何でもなさそうな、こういう些細なことが気になって混乱させられるんだよなぁ。
ってことで、定義を書いてみる。

(define delete-1
  (lambda (elt lis . opt)
    (let-optionals* opt ((cmp-fn equal?))
      (define loop
        (lambda (l)
          (cond
           ((null? l) '())
           ((cmp-fn (car l) elt) (cdr l))
           (else
            (let ((rest (loop (cdr l))))
              (cond
               ((eq? (cdr l) rest) l)
               (else (cons (car l) rest))))))))
      (loop lis))))