On Mon, May 12, 2014 at 12:15 PM, John Hume <duelin.mark...@gmail.com>wrote:

> On Sunday, May 11, 2014 6:33:25 PM UTC-5, Alex Miller wrote:
>
>> On Sun, May 11, 2014 at 2:06 PM, Mikera <mike.r.an...@gmail.com> wrote:
>>
>>> OK..... this thread is a bit worrying. If I understand correctly, it
>>> means that we've now got inconsistent hash and equals functions. I suspect
>>> this hasn't bitten many people yet simply because it is unusual to mix Java
>>> and Clojure collections as keys in the same structure, but it seems like a
>>> really nasty issue.
>>>
>>
>> Reports of real problems in real codebases would change my own opinion of
>> the severity of this issue.
>>
>
> Here's the real problem I feared when thinking about what was new in
> Clojure 1.6, which led to the testing that led to this thread:
> One of our Clojure applications has two kinds of clients. (1) Legacy Java
> clients use a legacy remoting lib w/ generated,
> shared-across-client-and-server Java value types as messages. Where those
> have a collection, that's exposed as a java.util.List<AnotherValueType>.
> (2) Newer (Clojure) clients use a lighter-weight message format that's
> easily read into Clojure data structures. Clients interested in the same
> data need to be aggregated, and the commonality is contained in one
> java.util.List<AnotherValueType> from a message the legacy clients send.
> The old code used those as map keys.
>

I think the general recommendation would be to not do that. :)  My
recommendation in Java would be the same - using mutable objects as keys in
a map (where mutability changes the hashcode) is a bug waiting to happen.


> The new code for Clojure clients currently builds a vector of
> AnotherValueType and throws that into the same map, where, under Clojure
> 1.5.1, vectors and non-Clojure Lists can play nicely together. Under
> Clojure 1.6, they won't play nicely any more.
>
> This is an easy problem to work around by making the keys from the two
> client types more similar, either vectors on both sides or non-Clojure
> java.util.Lists on both sides.
>

IMO vectors are the only choice that makes sense here.


> Luckily the change on our side is recent, and Clojure 1.6 is brand new, so
> this jumped out at me as something to test well before embarking on an
> upgrade, and this is a (probably) subtle bug we've avoided.
>

Depending on your point of view, you could also say that the use of a
mutable Java collection as a key is the bug you had already incurred and
it's just now biting you. :)

I really am sympathetic to what you're describing, but just trying to
highlight how the mutability of Java collections really is a problem when
used for hashing (and this is true regardless of language). Immutability is
what allows us to cache the hash code of a collection (something that
cannot be done in Java or Scala due to the mutability of objects, even in
immutable collections).


> What primarily worries me about the new behavior is that Clojure has
> always embraced the host platform, but the notion of "value" that seems to
> be reified in 1.6 excludes the closest things the Java platform has to
> collection values.
>

I really don't think anything has changed philosophically in 1.6. There is
a tension between interop support for mutable objects and the immutability
at the core of Clojure. We've come to a point where performance concerns
are driving us a bit further in one direction.


> While I agree a java.util.ArrayList is a bad value, mutability is not part
> of the java.util.List contract – it's optional – and even the best
> (immutable) Java collection value type one can write wouldn't be treated as
> a value by Clojure 1.6 unless it also implemented some clojure.lang
> interface(s) (which no sane Java lib would do). In the spirit of embracing
> the host platform, I'd like to see support for Java collections as values
> (and let those who mutate their value-treated Java collections deal with
> the nasty consequences).
>

In general, Clojure treats Java collections (and arrays) as values now ...
but if you do mutation, then any Clojure guarantees are off (in hashing, in
STM, etc). I think that's been generally a happy compromise so far. The
question is to what extent that should continue.


> From the comments on the ticket (
> http://dev.clojure.org/jira/browse/CLJ-1372), particularly Alex Miller's
> two longer comments from March 10th, I have the impression that there's no
> principled objection to this, just the performance concern with supporting
> so many types in hasheq. Does that seem right, Alex?
>

That's my feeling (not speaking for Rich) - I'd prefer to say without
exception that equiv=true => hash=same. As I said above, I think treating
Java collections as "look the other way" values has been mostly a happy
compromise.

It may even be that this could be supported without much of a hit. Strings,
numbers, keywords, symbols, and all Clojure collections should be handled
above the suggested change and that covers most common key types. Some
research would need to be done on what common non-Clojure classes (hence
not IHashEq implementors) fall into the final else case - java.lang.Class
is one that comes to mind which is used a lot inside Clojure itself.


> I'd feel much better about an open issue and agreement that Clojure is in
> search of a high-performance implementation treating Java collections as
> values than about clear documentation of when and why hasheq is and will
> remain inconsistent w/ = and all the quirks that follow from that. (Though
> since we're living w/ the inconsistency, that documentation is important.)
>
> Thanks.
> -hume.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Clojure Dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure-dev+unsubscr...@googlegroups.com.
> To post to this group, send email to clojure-...@googlegroups.com.
> Visit this group at http://groups.google.com/group/clojure-dev.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to