So I'm coding in Lisp and I came up with a function that counts the number of atoms in a list (with no sub-lists). so the code is this:
(defun num-atoms (list)
(cond
((null list) 0)
((atom list) 1)
(t (+ (num-atoms (car list))
(num-atoms (cdr list))))))
and this works and makes sense to me. So if I call this function with the list (1 2 3) in argument it should go as follows:
- (num-atoms '(1 2 3))
- not null
- not atom
- num-atoms(1)
- atom so returns 1
- num-atoms ((2 3))
- not null
- not atom
- num-atoms (2)
- return 1
- ....
- and so on
BUT, if I write the code like this:
(defun num-atoms (list)
(cond
((null list) 0)
((atom list) 1)
(t (+ (num-atoms (cdr list))
(num-atoms (car list))))))
here I just switched de car and cdr positions in the last line.
It still works ! and if I do a Trace, it gives me the number of atoms in the same order ! it counts the 1 first in the '(1 2 3) list and so on. Can someone explain to me how this 2nd version of the code still works ? I dont really understand the logic here.
(count-if #'atom …)would do this. FWIW.count-ifwould count all top-level atoms in a sequence, whereas his version counts all atoms in a tree.