Reputation: 13
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?
Upvotes: 1
Views: 487
Reputation: 5372
You might consider looking at an introductory text like "The Little Schemer". One of the first things it does is shows you how to take a consistent approach to problems just like this. The resulting function might look like:
(define (pl lst)
(cond ((null? lst) '())
((not (pair? lst)) (list lst))
(else (append (pl (car lst))
(pl (cdr lst))))))
Sure, this is Scheme, but the approach is the same for Lisp:
The same function in Lisp would look like:
(defun pl (lst)
(cond ((null lst) '())
((atom lst) (list lst))
(t (append (pl (car lst))
(pl (cdr lst))))))
Arguments can be made that this is not the most efficient code, but that isn't the point. This type of pattern occurs over and over again. It's a good idiom to learn.
Upvotes: 1
Reputation: 891
A function will normally only return one value, which is value of its body. If you look closely at pl
you see that it is an if
form, so pl
either returns the value of lst
or the value of progn
.
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 the atom
test. The second thing to point out here is that (atom nil)
is also true. Remember that the last element of a list is nil
, so when you give pl
a 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 append
instead of progn
, 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.
Upvotes: 4