equality bug on records created with nested calls to map->record

Description

Depending on the type of the map passed to a record map constructor, records will not correctly compare for equality:

Cause: The type of the map passed into the map constructor leaks into the __extmap, affecting equality comparison of the record. This bug was described in this post: https://groups.google.com/forum/#!topic/clojure/iN-SPBaTFUw

Approach: Clean the extmap before putting it into the record constructor.

Patch: CLJ-1388-record-equality-and-map-record-factory.patch

Screened by: Alex Miller

Environment

None

Attachments

4

Activity

import 
March 30, 2015 at 3:32 PM

Comment made by: mikerod

Thanks for the clarification Andy. As I mentioned my post may be irrelevant.

I just saw this while scanning the 1.7 changes and figured I'd mention in case there was any more circling back to this (if the patch that was applied proved unsuccessful, etc).

Andy Fingerhut 
March 29, 2015 at 4:08 PM

Mike, this bug was closed on Aug 29 2014 by applying the patch mentioned after "Patch:" in the description, which is CLJ-1388-record-equality-and-map-record-factory.patch

You can see the commit in the Clojure commit history on github here: https://github.com/clojure/clojure/commit/62acc2aae934ba4c4d0830fe5664d4aa0107d855

import 
March 28, 2015 at 7:41 PM

Comment made by: mikerod

If the decision is to go forward with CLJ-1388-record-equality-and-map-record-factory.patch on this what I have to say isn't necessarily relevant.
I didn't see anyone mention this before though, so I want to just make a point about the proposal of changing the use of clojure.core/= to clojure.lang.Util/equals in CLJ-1388v2.patch and any other related.

Changing to Util/equals would actually Clojure record types that are nested in the __extmap no longer have type-sensitive equality checking. I think that would be undesirable.

e.g.

This is false prior to any changes from this Jira.
Swapping = to Util/equals in the Clojure record `equiv` implementation would change the result to true.
In general, a switch from clojure.core/= to clojure.lang.Util/equals for the __extmap would "be contagious" to all nested equality comparisons within the __extmap. That doesn't sound desirable.

Again, it sounds like the direction Alex has mentioned this is taking is CLJ-1388-record-equality-and-map-record-factory.patch. I see no issues with this. Perhaps someone already thought of the above case too and just didn't mention it on here. I wanted to make this point here in case there was any further discussion around the = to Util/equals proposal.

On a side note, I do not believe I can find any tests in clojure.test-clojure.protocols with Clojure records having nested Clojure records within their basis fields or __extmap. So I don't think this example would have been something caught there with the = to Util/equals patch (assuming this is the only test namespace with these sorts of tests).

Alex Miller 
May 23, 2014 at 5:19 PM

Screened specifically CLJ-1388-record-equality-and-map-record-factory.patch - use map as is if it supports MapEquivalence (and can thus be compared under a map) and otherwise dump into a clojure map.

Alex Miller 
May 6, 2014 at 4:22 PM

From brief conversation with Rich, we should not allow arbitrary map types in __extmap so would prefer to force a clean map and rely on standard equality checking. I think CLJ-1388-record-equality-and-map-record-factory.patch is the preferred path based on that, which still seems like it should avoid copying in nearly all common cases.

Completed

Details

Assignee

Reporter

Labels

Approval

Patch

Priority

Affects versions

Fix versions

Created March 19, 2014 at 2:24 AM
Updated March 30, 2015 at 3:32 PM
Resolved March 30, 2015 at 3:32 PM