Reputation: 826
I'm writing a program that takes a list, and replaces all elements (whether it's an atom, a cons, or a list), with "X." So, if I were to evaluate my function with:
((A B) (C . D) E))
it would return
((X X) (X . X) X))
However, I keep getting "X is not of the expected type LIST" error when trying to evaluate my function. I don't understand why, though. I'm using Allegro Common Lisp Express edition under Windows. What am I doing wrong?
(defun exify (lst)
(exify-aux lst nil))
(defun exify-aux (lst acc)
(if (null lst)
acc
(if (atom (car lst))
(append 'x acc)
(if (consp (car lst))
(append (cons 'x 'x) acc)
(if (listp (car lst))
(append (exify-aux (car lst) nil) acc)
(if (eq (car lst) nil)
(append nil acc))))))
(exify-aux (cdr lst) acc))
Upvotes: 1
Views: 1655
Reputation: 48745
There is a lot of dead code in your code and ulimately it's an infinite loop.
(defun exify-aux (lst acc)
;; This whole block if, correct, doesn't amount to any result
(if (null lst)
acc
(if (atom (car lst))
(append 'x acc)
(if (consp (car lst))
(append (cons 'x 'x) acc)
(if (listp (car lst))
(append (exify-aux (car lst) nil) acc)
(if (eq (car lst) nil)
(append nil acc))))))
;; This is the tail call and it's called unconditionally
(exify-aux (cdr lst) acc))
You need to be more intimate with cons
.
(defun exify (tree)
(cond ((null tree) nil)
((atom tree) 'x)
(t (cons (exify (car tree))
(exify (cdr tree))))))
When you are you might want to do higher order functions:
(defun exify (tree)
(accumulate-tree tree
(lambda (_) 'x) ; replaces all non nil leafs with x
#'cons ; copies branches
nil)) ; copies empty leafs
accumualte-tree can be defined like this:
(defun accumulate-tree (tree term combiner null-value)
(labels ((rec (tree)
(cond ((null tree) null-value)
((atom tree) (funcall term tree))
(t (funcall combiner (rec (car tree))
(rec (cdr tree)))))))
(rec tree)))
Upvotes: 3
Reputation: 139251
(append 'x acc)
How should that work? Append takes lists. x
is a symbol.
Also, what is the purpose of (append nil acc)
? Appending empty lists does nothing useful. (append '() '() '() '())
is just ()
.
Upvotes: 2