I am trying to find the position of an atom in the list.
(position-in-list 'a (a b c d e))
gives 0
(position-in-list 'b (a b c d e) )
gives 1
(position-in-list 'Z(a b c d e) )
gives nil.
I have pasted my code which only returns 1.
(defun position-in-list (letter list) )
( cond
( (null list) nil
)
( (eq (car list) letter) count
)
( t (position-in-list letter (cdr list)) count)
)
)
( defun count ()
( + 0 1)
)
Here is a tail-recursive version in CL:
And the equivalent in Scheme (Racket here), which has a nice construct designed for just this (and also eliminates tail calls as part of the language spec of course):
Firstly, the Common Lisp standard library has that already; it's called
position
.In general, things in the standard library are there to be used. (Yes,
position
gives those outputs. I just ran those through a REPL.)Secondly, not to sound holier-than-thou or anything, but your parenthesis style just hurts my eyes. Put an opening parenthesis right in front of the first thing in the list, and all closing parens on the same line as the last thing in the list. For example:
or
This might be hard on your eyes [it was for me at first], but it helps you find mistakes more easily.
Thirdly, I don't know what your
count
function is supposed to be doing, butposition-in-list
is probably not doing it the way you expect. Try this:Ultimately, returns NIL if
letter
is not found inlist
, or the index if it is. Yes, I know those parens look opaque, but this is how Lisp is written. You'll get used to it.tl;dr Use
position
in the standard library; it does what you want.Here is another solution using only recursion:
((atom liste) nil)
= after all the recusion, if the list is empty, it returns nil((equal letter (car liste)) 0)
= if it finds the letter we are looking for, it returns 0 and starts unstacking((position-in-list letter (cdr liste)) (+ 1 (position-in-list letter (cdr liste))))
= it adds +1 only if have not gone through the whole list already, so only if we have found our letter before then