Certainly the problem is the realizing the tail sequence of the split-with
before the head sequence, and take shouldn't be trying to solve that. But I
guess I would have thought that (doall (take (count t) t)) would have
realized all of t so the head could be released.

Indeed, the take* formulation is effectively a look-ahead, realizing one
element more than necessary, and I can see how this might be undesirable. I
suppose the two have to be weighed against each other and (doall (take
(count t) t)) is enough of a special case that it's not worth the
lookahead. But take* is the same formulation as drop, no? Is the lookahead
problem not a problem there?

Thanks for the response!


On Mon, Oct 24, 2016 at 7:22 AM, Meikel Brandmeyer (kotarak) <m...@kotka.de>
wrote:

> I think this is not a bug in take, but an unfortunate constellation of
> laziness.
>
> The solution you propose is basically making take looking one step ahead,
> which is not take's business. It could be actually quite dangerous to do
> so in case take's n was carefully calculated based on some external
> stopping condition.
>
> It just fixes your one-step look ahead special case. However the real
> problem is realising the tail sequence of the split-with before the head
> sequence. This is not a problem of take either.
>
> That notwithstanding one could optimise take a little bit by actually
> preventing holding onto the tail in the last step, since n is known
> upfront.
>
> (defn take
>   [n coll]
>   (when (pos? n)
>     (lazy-seq
>       (when-let [s (seq coll)]
>         (cons (first s) (take+ (dec n) coll))))))
>
> This would “fix” (split-at 50 (range 1e8)) in your example. However, it
> wouldn't help with split-with. Here the stopping condition is unknown,
> because it is based on a predicate of the input data. There we have to hold
> onto the head of the input.
>
> Takeaway: Always realise t before d. And full t, not some derivative, if
> you hold onto its head.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/
> topic/clojure/AvL4nurdB1E/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to