common-lispon-lisp

Is this a good correction for "our-find-if" at Graham's OnLisp page 23 errata?


Paul Graham's 'On Lisp' errata page states:

p. 23. our-find-if would recurse infinitely if no element matches. Caught by Markus Triska.

The function definition as shown in the book is:

(defun our-find-if (fn lst)
    (if (funcall fn (car lst))
        (car lst)
        (our-find-if fn (cdr lst))))

And here is my probably poor fix for it:

(defun our-find-if (fn lst)
    (if (funcall fn (car lst))
        (car lst)
        (if (cdr lst)
            (our-find-if fn (cdr  lst))
            nil)))

Is this correct? Is my version of 'our-find-if' still tail recursive? (I think so...)

Better alternatives welcome.

TIA


Solution

  • It is OK, and it is tail recursive.

    I would propose the following changes, though:

    update: first test for end of list, thanks to Paulo Madeira

    It looks like this then:

    (defun our-find-if (predicate list)
      (cond ((endp list)
             nil)
            ((funcall predicate (car list))
             (car list))
            (t
             (our-find-if predicate (cdr list)))))