On Mon, 6 Dec 2010 17:07:15 -0500 Ken Wesson <kwess...@gmail.com> wrote:
> On Mon, Dec 6, 2010 at 4:44 PM, Mike Meyer > <mwm-keyword-googlegroups.620...@mired.org> wrote: > > On Mon, 6 Dec 2010 16:30:10 -0500 > > Ken Wesson <kwess...@gmail.com> wrote: > > > >> On Mon, Dec 6, 2010 at 1:05 PM, Stuart Sierra > >> <the.stuart.sie...@gmail.com> wrote: > >> > On Dec 6, 8:36 am, Ken Wesson <kwess...@gmail.com> wrote: > >> >> Furthermore, the comment (not made by Hickey) that map order "may be > >> >> unstable" is more than a little puzzling in light of the fact that the > >> >> maps in question are immutable. :) > >> > > >> > In general, Rich has been careful not to promise things that might > >> > limit changes he can make in the future. Sets and maps are unordered. > >> > `seq` happens to be deterministic on ArrayMap and HashMap, but there > >> > might some day be some other kind of map or set for which `seq` cannot > >> > be deterministic. Therefore, Clojure does not promise anything about > >> > `seq` on maps, other than that it will return the key-value pairs. > >> > >> I confess I can't see any obvious reason ever to make seq > >> nondeterministic on an immutable data structure. > > > > I suspect you're applying "immutable" to everything about the data > > structure, whereas it can also be applied the value without including > > the implementation. I can see wanting to change the implementation in > > ways that don't change the value - triggered by something like wanting > > to share parts of the value with another structure, or a garbage > > collection, or ... - which could easily change the results of calling > > seq on the structure. > > Perhaps. But under those circumstances seq itself has the same problem > you're using to excuse not supporting nth, yet seq is supported. I had some trouble figuring out what you're saying here, so let me know if I got this wrong: I'm providing reasons for seq to not have a guarantee of determinism when called on some structures, and that non-determinism is the justification for nth not being supported, so why is seq supported? A non-deterministic nth has no value - you might as well just use first (and in fact, you can). A non-deterministic seq, on the other hand, *does* have a value: it provides representation of the value for which nth (and friends) have a deterministic value. Having nth call seq on structures for which seq is non-deterministic would slow down nth, and possibly hide buggy code. Forcing the call to seq be explicit means there's a chance they'll notice the non-deterministic result, and fix the bug. > And so is (nth (seq x)) on these things; if the implementation > changed its innards while you were walking the seq (even with map! > Nevermind using nth) this could trip up. You might have a set #{1 2 > 3 4 5 6} and seq would produce (1 3 4 5 2 6) and then someone makes > another set from it with disj and the structure rearranges, so seq > would now produce (1 5 6 2 4 3). Meanwhile, another thread has > produced a seq and is traversing it at the time and gets (1 3 4 2 4 > 3). Oops. There are a number of ways to avoid this bug. You found at least one of them here: > If that kind of internal rearrangement is to be done, seq will have to > copy the structure's contents (by realizing the seq promptly; so there > goes laziness) in order to avoid that kind of error. And once you have > that, you will want to create AND CACHE the (immutable!) structure's > seq-representation when it's first needed. And you can do so when nth > is called, as well as seq. And then due to the caching both nth and > seq will obey (if (identical? s1 s2) (identical? (f s1) (f s2))) when > substituted for f. > > Even then, I'd expect internal rearrangement to be a thread-safety > nightmare; in all likelihood a) rearranging operations, and b) > operations like realizing the seq that will be b0rked by concurrent > rearrangements, will require locking the structure. Locking is > supposed to be kept to a minimum as one of Clojure's design goals, > IIRC. > > This gets worse when you note that seq realization can cause the > execution of user-supplied code (e.g. the body of a lazy-seq macro) > during realization. If user-supplied code can end up executing with > user-invisible monitors locked, and can in turn cause more monitors to > be locked (say, by disjing a set thus causing one of your hypothetical > internal rearrangements), then it can cause deadlocks that would be > fiendishly difficult to track down and fix. And deadlock avoidance is > *emphatically* one of Clojure's design goals. All true. As far as I'm concerned, it's also all irrelevant. Just because doing a thing is hard in all known examples doesn't mean you want to give up the right to do it should you decide you need to. <mike -- Mike Meyer <m...@mired.org> http://www.mired.org/consulting.html Independent Network/Unix/Perforce consultant, email for more information. O< ascii ribbon campaign - stop html mail - www.asciiribbon.org -- 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