Why does the second evaluation with butlast loop endlessly in Clojure?
user=> (->> (range) butlast lazy-seq (take 0))
()
user=> (->> (range) butlast lazy-seq first) ; ...
The equivalent in Haskell can be reasonably lazy-eval'ed.
ghci> take 0 . init $ [0..]
[]
ghci> head . init $ [0..]
0
Edit
take 0 is no-op as being pointed out below.
If you look at the implementation of butlast
, you can see that it's eager (using loop
instead of lazy-seq
). An alternate lazy implementation would do what you want:
(defn butlast'
"Like clojure.core/butlast but lazy."
[xs]
(when (seq xs)
((fn f [[x & xs]]
(if (seq xs)
(lazy-seq (cons x (f xs)))
()))
xs)))