It is not really clear what should be the position when the element is found in some deep level of the tree.
One possibility is to return the index of the n-th leaf corresponding to the element.
In this case, for instance, given a flatten function, you could write a function like this:
(defun my-position (elm tree)
(position elm (flatten tree))
Another possibility is to generalize the concept of index to a tree structure, for instance by returning a list in which the element in position j is the position of the element or the list containing it at level j. For instance:
(my-position 'A '(A (B 1 2 (3 x y z)) C D)) => (0)
(my-position 'B '(A (B 1 2 (3 x y z)) C D)) => (1 0)
(my-position 'y '(A (B 1 2 (3 x y z)) C D)) => (1 3 2)
In this case, a recursive function could be:
(defun my-position (elm tree &optional (start 0))
"find the generalized position of elm inside tree.
Parameters: elm - element to be found
tree - a list of atoms and lists in which to search the element
start - the tentative position"
(cond ((null tree) nil) ; element not present => nil
((atom (first tree)) ; if the first element is an atom, then
(if (eql elm (first tree)) ; if equal to element, found
(list start) ; return position start
;; otherwise, recur on rest of list incrementing the tentative position
(my-position elm (rest tree) (1+ start))))
;; otherwise, the first element is a list,
;; try to find it inside, with a recursive call
(t (let ((pos (my-position elm (first tree) 0)))
(if pos ; if not nil the element has been found
(cons start pos) ; return the current position followed by the position inside the list
; otherwise recur on rest of list incrementing the tentative position
(my-position elm (rest tree) (1+ start)))))))
Final note: to write a more “professional” function one should add the keyword parameters of the predefined position
function.