Hi Steve,
thank you for taking a look and for your suggestions!
> This part concerns me:
>
> > Note: Since clojure maps are no java maps, they can't be equal to java
> > maps. This holds for wrapped clojure maps as well - surprisingly (in a
> > bad sense), but i don't see a way around this:
>
> > (= (doto (HashMap.) (put 1 2)) {1 2})
> > -> false
>
> > (= (jmap {1 2}) {1 2})
> > -> false
That bugs me too, and i did try to resolve it. As far as i can see,
there are only two ways out, neither of which i like very much (worst
first):
1. Break the transitivity of = (for cases where you wouldn't expect it
to break)
2. Change = to (= a b) not necessarily being equivalent to a.equals(b)
re 1: Basically, (= a b) maps to a.equals(b) in Java (except for nil
and numbers). Suppose we'd like it to stay that way. Implementing =
for jmaps and Clojure maps would of course be easy and just a matter
of extending their equals-methods accordingly (we'd like = to be
symmetric, which means "mutual agreement" on equality in Java).
Suppose we had three representations of the same mapping: a Clojure
map a, a jmap-wrapped Clojure map b and a plain Java map c. Of course,
we want (= b c), that's the point of the whole undertaking. We also
have (= a b) after augmenting the equals-methods in question, but we
can't possibly have (= c a), because a Java map won't agree on being
equal to anything else but a Java map.
(I realise that, for arbitrary Java objects and funny implementations
of equals, = is anything but an equivalence relation, but here it
always breaks, even if equals is defined sensibly)
re 2: The idea would be to check whether we're comparing a mix of
Clojure maps and Java maps, if so, compare them entry-wise (along the
lines of the definition you gave), disregarding the Java maps
"equals". I think this would lead to weird equality semantics (e.g. a
Clojure map would appear = to a Java map within Clojure, but not from
the Java point of view, thus you couldn't pass it to Java methods that
expect Java maps).
Either way we turn it, it looks like the distinction between Clojure
maps and Java maps can only be blurred, but not removed in a
consistent way. The examples above are somewhat factitious, but
they'll likely lead to quite real issues that will be hard to
understand/explain/debug.
So i'd like to argue for a clean cut instead of blurring. In that
sense, jmap is just a function that returns a Java object, not a
Clojure map type. :-) I considered not supporting conj, assoc and
invoking on them to avoid creating that outward expression, but i went
for practicality here.
Kind regards,
achim