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)
)
Firstly, the Common Lisp standard library has that already; it's called position
.
(position 'a '(a b c d e)) ==> 0
(position 'b '(a b c d e)) ==> 1
(position 'z '(a b c d e)) ==> NIL
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:
(defun hello-world ()
(format t "Hello World!"))
or
(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))
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, but position-in-list
is probably not doing it the way you expect. Try this:
(defun position-in-list (letter list)
(cond
((null list) nil)
((eq (car list) letter) 0)
(t (1+ (position-in-list letter (cdr list))))))
Ultimately, returns NIL if letter
is not found in list
, 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:
(defun position-in-list (letter liste)
(cond
((atom liste) nil)
((equal letter (car liste)) 0)
((position-in-list letter (cdr liste)) (+ 1 (position-in-list letter (cdr liste)))) ) )
((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
Here is a tail-recursive version in CL:
(defun position-in-list (elt list &key (test #'eql))
(labels ((pill (tail p)
(cond ((null tail) nil)
((funcall test elt (first tail)) p)
(t (pill (rest tail) (1+ p))))))
(pill list 0)))
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):
(define (position-in-list elt lst #:test (test eqv?))
(let pill ([tail lst] [p 0])
(cond [(null? tail) #f]
[(test elt (first tail)) p]
[else (pill (rest tail) (+ p 1))])))