I would like to go through a list (which may have nested lists) and have it evaluate to one flattened list with all of the elements. I can’t even get a recursive function to evaluate to anything other than nil
(defun pl(lst)
(if (atom lst)
lst
(progn
(pl (car lst))
(pl (cdr lst)))))
I’ll then call with something like (pl '(1 (2 3) (4 5))), but it always evaluates to nil.
I changed
(if (atom lst) lst
to
(if (atom lst) (print lst)
and this doesn’t even print any of the items of the list.
what concept I am missing here?
A function will normally only return one value, which is value of its body. If you look closely at
plyou see that it is anifform, sopleither returns the value oflstor the value ofprogn.The first thing I have to point out here is that the return value of a
(progn ...)form is the value of its last expression, which in this case is the recursive call(pl (cdr lst)). As you do not do anything with the return value of(pl (car lst))this call has no effect whatsoever. The value of the recursive call will at some point fall through theatomtest. The second thing to point out here is that(atom nil)is also true. Remember that the last element of a list isnil, so when you givepla list it will always return nil as you have observed.If your print version shows nothing, it is probably because the print output is shown somewhere else, in another buffer for example.
As for the solution: you either want a pure recursive solution by using
appendinstead ofprogn, because that’s what in your homework assignment. In regular lisp you just use one of the iteration constructs.My advice is to check any textbook on lisp or scheme to grasp the fundamentals of recursion and tail-recursion.