What is wrong with my flatten function

111 Views Asked by At

This function is supposed to remove all parentheses from the inside of a list. I am not asking how to do that (I already know that would be a duplicate) I am asking why when I run my solution, it breaks and tells me

"Error: The variable APPEND is unbound."

here is my code

(defun flatten (lst)
   (cond ((null lst) lst)
   ((listp (first lst))(append((flatten(first lst)) flatten(rest lst))))
   (append(list(first lst) flatten(rest lst)))))

heres how its SUPPOSED to work: 1:First it checks to see if list is empty. Base case 2: then it checks to see if its first element is a list. if it is, then it appends that list onto the result of a recursive call on the tail of the list 3: lastly, if the first element is not a sublist, then it appends a list containing that one element onto the result of a recursive call on the tail.

what isn't working?

edit


I would just like to add to this that, this is literally my first time programming in lisp ever. If my mistakes are due to parentheses placement or other rookie mistakes, I don't know, because I am still adjusting to programming in a functional language.

1

There are 1 best solutions below

0
On BEST ANSWER

Lots of stuff here won't work. Something like

(append ((flatten(first lst)) flatten(rest lst))))

is a function call to the function append, but with one argument:

((flatten(first lst)) flatten(rest lst))

That's like a function call, except that (flatten (first lst)) isn't a function that you can call. And even if it was, you'd be calling with with two arguments:

flatten

and

(rest list)

The second of those sort of makes sense, except that you don't have a variable list, you only have lst. The first would be a variable reference, but you haven't declared a variable flatten.

The specific error you're getting, though, isn't either of those. You're probably calling your function with something that's not the empty list (so you're not in the first clause), and that doesn't have a list as the first argument (so you're not in the second clause). That means that you go to the third clause:

(defun flatten (lst)
  (cond ((null lst)          lst)
        ((listp (first lst)) (append ((flatten(first lst)) flatten(rest lst))))
        (append              (list(first lst) flatten(rest lst)))) ; *here*

In that, you're going to evaluate append, and if it's true, you'll evaluate

(list(first lst) flatten(rest lst)))

append isn't a variable though, so you're getting the unbound variable error. Even if it were, and it were true, you'd get an error when you try to evaluate

(list(first lst) flatten(rest lst)))

since that's a function call to list, with (first lst) as its first argument (which is fine), and flatten as its second argument (another unbound variable), and (rest lst) as its third argument (which is fine). Remember that a function call in Lisp looks like

(<function-name> <arg1>...)

so you write (list (flatten (first lst)) (flatten (rest lst))), although, you'd probably actually want (append (flatten ...) (flatten ...)). That said, there are already lots of questions about how to flatten a list on Stack Overflow. Some of them may be more enlightening.