OrangeCalx01
OrangeCalx01

Reputation: 826

Not of the expected type in Lisp?

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

Answers (2)

Sylwester
Sylwester

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

Rainer Joswig
Rainer Joswig

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

Related Questions