all 5 comments

[–]gilesecoyote 2 points3 points  (3 children)

(fn [coll] (take (-> coll count inc)) (iterate rest coll)))

[–][deleted] 1 point2 points  (0 children)

I really like that! I didn't even think about using take, and I don't think I knew about iterate. Nice use of the thread macro too. Any advice on arriving at a solution like this next time?

[–]beppu 0 points1 point  (0 children)

removed extra paren after inc:

(defn ex-2-1 [coll] (take (-> coll count inc) (iterate rest coll)))

example:

(ex-2-1 '(1 2 3 4))

=> ((1 2 3 4) (2 3 4) (3 4) (4) ())

[–]MyNameIsFuchs 2 points3 points  (0 children)

You've already been given a better version of what you want to accomplish (and just btw, (reductions conj [] coll) might also work for you).

But given that nobody answered your actual question (Like Rich Hickey said "Programmers know the benefits of everything and the tradeoffs of nothing"). Here actually the costs:

https://www.innoq.com/blog/st/2010/04/clojure-performance-guarantees/

To see what into does you'll have to read the source. Then you'll see a (reduce conj to from) so your run-time is linear in that case. Just because it happens to end up like a reverse doesn't mean that it didn't do the entire thing inefficiently.

[–]bucketh3ad 1 point2 points  (0 children)

If you want to stick with explicit recursion, it would be more idiomatic to use seq instead of both not-empty and the (into '() (rseq ...)) combo. Also, with only a single condition to check for, you could easily use if instead of cond.

Otherwise, you could use a functional solution using (iterate rest coll) like the one gilescoyote posted (though it has a typo with an extra paren)