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

Reply via email to