I am attempting to write a small recursive program that tests a list and returns t if every element is an atom. The problem I am having is that when the function receives an empty list, it returns t instead of the desired result of nil. I cannot come up with a way to have it return nil for an initially empty list and still function properly in a recursive manner.
(defun only-atoms (in)
(if (null in)
t
(and (atom (first in)) (only-atoms (cdr in)) )
)
)
The function can be implemented without recursion using e.g. every, as in:
(defun only-atoms (list)
(and list (every #'atom list)))
When it comes to your stated problem that the function returns T instead of the desired result of NIL when the function is called with an empty list:
Your recursive implementation explicitly returns T if (null in) is true, which explains your finding. Simply change it to the desired value NIL. Consider changing the if construct to and.
Only make the recursive call when the list has more than one item. A well placed test for (rest in) will do. Provide a true value instead of making the recursive call if the list is at its last item.
Carefully locate the only-atoms call to ensure that the function can be tail-recursive.
For example:
(defun only-atoms (list)
(and list
(atom (first list))
(or (null (rest list))
(only-atoms (rest list)))))
Use COND, which allows you to test for several cases:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With