2
votes

Hi I'm kind of new to clojure and I'm trying to write a function called up that removes a pair of parentheses from each top level element of a list. If the top level element is not a list, then it is added as well. For example,

>(up '((1 2) (3 4)))
(1 2 3 4)

>(up '(x (y) z))
(x y z)

Right now, I'm having a problem with the function ending too soon if I'm trying to remove one pair of parentheses. I want to do this recursively and without the help of other functions if possible. What I have at the moment:

(defn up [lst]
   (if (empty? lst)
     ()
     (if (list? (first lst))
       (up (first lst))
       (cons (first lst) (up (rest lst))))))

I know that the problem is that I am cons-ing an empty list with the last element of a nested list which ends my function, but I can't figure out how else to do it.

1
Are you trying to reimplement flatten or remove just one level of parentheses? Óscar's answer below flattens the sequence completely. - Diego Basch
I want to flatten it. - Chris Phillips

1 Answers

0
votes

Diego's comment seems to indicate there were other answers here, but I don't see them now, so here goes...

Your function ends too soon because, when it hits an item that is itself a list, it recursively calls up on that item and ignores the rest of the items in the original list. (up (first lst))

The minimal change to your code would be to, instead, recursively call up on the concatenation of that first list item and the rest of the list. (up (concat (first lst) (rest lst)))

Even better would be to use the existing core function flatten instead of up.

On a side note, you would generally want to achieve recursion using recur instead of calling up directly, in order to avoid a stack overflow for large input lists.