Clojure butlast vs drop-last

What is the difference between butlast and drop-last in Clojure?

Is it just laziness? Should I prefer one over the other?

+6
source share
2 answers

also, if you need to implement the entire collection, butlast much faster, which is logical if you look at their source:

 (def butlast (fn ^:static butlast [s] (loop [ret [] ss] (if (next s) (recur (conj ret (first s)) (next s)) (seq ret))))) (defn drop-last ([s] (drop-last 1 s)) ([ns] (map (fn [x _] x) s (drop ns)))) 

therefore drop-last uses map , but butlast uses a simple iteration with recur . Here is a small example:

 user> (time (let [_ (butlast (range 10000000))])) "Elapsed time: 2052.853726 msecs" nil user> (time (let [_ (doall (drop-last (range 10000000)))])) "Elapsed time: 14072.259077 msecs" nil 

therefore, I would not blindly choose one by one. I use drop-last only when I really need laziness, otherwise butlast .

+8
source

Yes, laziness, as well as the fact that drop-last can also take n , indicating how many elements fall from the end lazily.

It is discussed here , where someone makes the case that butlast more readable and perhaps a familiar idiom for Lisp programmers, but I generally just prefer to use drop-last .

+4
source

All Articles