On Mon, Mar 14, 2011 at 4:13 PM, Tassilo Horn <[email protected]> wrote:
> Hi all,
>
> I've implemented IEditableCollection support for ninjudd's
> PersistentOrderedSet. But when using that, my application delivered
> wrong results. See <[email protected]> and follow-ups.
>
> I was able to track it down to the strangeness in the subject:
>
> (.contains (transient (hash-set)) foo)
>
> returns true for any object foo, that is, the empty transient hash-set
> contains everything.
>
> The above clojure code is equivalent to this java code, which I used in
> the PersistentOrderedSet extension:
>
> ((ITransientSet) PersistentHashSet.EMPTY.asTransient()).contains(o)
>
> For now, I worked around this strange behavior by checking the count()
> of the TransientHashSet backing my TransientOrderedSet implementation in
> addition to contains().
>
> But anyway: Is that behavior intended and facilitated internally
> somehow? If so, is there some documentation about the rationale?
>
> Bye,
> Tassilo
At first blush, the answer appears to be "no".
Here is APersistentSet.contains:
public boolean contains(Object key){
return impl.containsKey(key);
}
Here is ATransientSet.contains:
public boolean contains(Object key) {
return this != impl.valAt(key, this);
}
This should probably use a sentinel; it's possible to put a transient
map into itself, at least in principle. But the real problem:
user=> (.valAt (.asTransient clojure.lang.PersistentHashMap/EMPTY) 1 42)
nil
Oops! This should have returned 42, not nil!
The actual error is on line 278 of PersistentHashMap.java:
Object doValAt(Object key, Object notFound) {
if (key == null)
if (hasNull)
return nullValue;
else
return notFound;
if (root == null)
return null;
return root.find(0, Util.hash(key), key, notFound);
}
This obviously should say
if (root == null)
return notFound;
!!!
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en