On Mon, Sep 3, 2012 at 1:58 PM, Stephen Compall <stephen.comp...@gmail.com> wrote: >> I would have hoped that would be guaranteed > > Nevertheless, by declaring "pred must be free of side-effects", > `take-while' is refusing to make that promise, among many others.
It seems like a leap to go from pred being free of side-effects to refusing to make *that* promise. If the reason that pred must be free of side-effects that take-while is *thereby* free to call pred on the elements of coll in arbitrary order then actually only *some* side-effects need to be banned. (Maybe you want to track how many times pred has been called---that's a side effect but it shouldn't interfere with pred's being called more than strictly necessary for take-while to get the right answer, since, after all, if pred is called more than is strictly necessary, that's exactly what you wanted to know.) And in refusing to make that promise, take-while is also doing *more* than just requiring that pred be free of (some) side-effects, it's also saying that take-while *itself* (i.e., *not* 'first') reserves the right to have the side-effecty function of forcing the computation of *arbitrary* amounts of a lazy sequence. Side note: the concept of *pred*, specifically, being free of side-effects seems underdetermined. Is (fn [f] (even? (f))) free of side-effects? It is iff f is. What if I pass in, not the pure function f, but rather the impure function (memoize f)? (memoize f) isn't *visibly* side-effecty to its caller (the way some Haskell people are willing to sell their souls and say, "well, you can use unsafePerformIO as long as *you* know it's safe..."), but it isn't side-effect-free sensu stricto. > In general, you may not assume that more elements of a lazy sequence > than you need will not be computed. I exempt `reductions', `iterate', > and any sequences derived from those in my own practice; you may be more > or less comfortable with such exemptions. > > user=> (first (map print [1 2 3 4])) > 1234nil > user=> (first (map print '(1 2 3 4))) > 1nil I'm aware of seq chunking; it seems tangential to the main concern here. The following two questions are distinct: - will calling "first" on a lazy seq cause more than just its first element to be computed? - will take-while cause more of a lazy seq to be realized than is present in its output *because it calls pred on arbitrary elements of the seq*? Of course take-while might cause more of a lazy seq to be realized than is present in its output because of seq chunking. But I'd *hope* that it wouldn't exacerbate that by reserving the right to work like, say, this, where n is the largest number of elements of a seq calling first might compute: 1. Realize the first 1000n elements of a seq, retaining them in memory. 2. Call pred on those elements in reverse order. 3. If pred was true for all of them, realize the next 1000n elements, etc., otherwise return a lazy seq of the first stretch of elements for which pred returned true. That admittedly would be insane, but if pred is free of side-effects (and computing the elements of the collection is also free of side-effects) it would be correct. -- Ben Wolfson "Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure." [Larousse, "Drink" entry] -- 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