On Mon, Dec 6, 2010 at 7:10 PM, Michael Gardner <gardne...@gmail.com> wrote: > On Dec 6, 2010, at 5:35 PM, Ken Wesson wrote: > >> Who was relying on the order? If you merely relied on seeing 5 or 6, >> or on not seeing 3 or 4 twice, you were screwed. > > Ah, I misunderstood what you wrote. Obviously (seq) should hand you each item > in the collection exactly once, but that's at a weaker guarantee than that > different calls to (seq) on the same collection should always hand them to > you in the same order. > >> The point was that you can't even rely on seeing all of the elements, >> once each, in *some* order, unless the seq is a copy instead of a view >> backed by the other data structure. > > I don't see how this follows. It seems like you're making some unstated > assumptions about how (seq) gets items from the underlying collection.
I'll try this one more time. You suggested the innards, and with them the seq order of the elements, might get rearranged. If (seq c) produces a lazy seq that is backed by some kind of iterator traversing some data structure underlying c and such a rearrangement happens during said traversal, then there are two branching possibilities. 1. The iterator just keeps traversing even though it's now on quicksand. (Or worse, it stops with a ConcurrentModificationException or something.) In that event, the seq contract is broken. At best you'll get traversals like (1 3 4 2 4 3) sometimes from traversing things like #{1 2 3 4 5 6}; more likely you'll get things like (1 3 4 2) that simply stop short and omit items; at worst, exception throws. 2. There is some way in which the seq "holds onto" a particular ordering of the elements, even through rearrangements. The seq may be non-lazy, created as a PersistentList of the elements when seq was called; or the structure may include a (stable!) linking system for traversing the elements (ala java.util.LinkedHashMap), or something. In case #2, seq meets its contract, but nth can also be made to work easily enough; in the linking-system case nth "naturally" works stably, whereas in the non-lazy case the seq version once created can be cached, both making repeated calls to seq cheaper and making nth work in a consistent way on that instance. In case #1, on the other hand, though nth can't be made to work *seq can't be made to work either* even though it is supported -- it's supported, and yet *it'll break and needs to be fixed* if the structure is rewritten to rearrange its innards. And fixing it will necessarily also fix nth. >> And if it's a copy, it is >> expensive to produce. And if it is expensive to produce, it can be >> cached once produced. And if it can be cached once produced, nth can >> give consistent results by consulting the cached seq. > > It's not just about (nth) giving consistent results. It's also about forcing > the programmer to make his intentions explicit, per Rich's quote. We may just have to agree to disagree about that. It seems to me that calling nth, or first, or seq, or anything like that makes the programmer's intentions explicit, as those are all clearly treating the structure as a sequence. It's calling (foo coll) where foo calls (nth (seq coll)) or somesuch under the hood that doesn't make the programmer's intentions (as) explicit; they're calling some function on, say, a map and it may not be especially obvious that that function treats the map (and anything else passed to it) as a sequence. Anyway, you can't legislate code clarity at the language level. They tried that with Java and look where it got them. Annotations, generics, and checked exceptions, oh my! -- 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