lambdaisland / deep-diff2

Deep diff Clojure data structures and pretty print the result
Eclipse Public License 1.0
296 stars 18 forks source link

Show diff at deeper level (Sets) #33

Closed FiV0 closed 1 year ago

FiV0 commented 1 year ago

In certain cases the diff shows higher up in the hierarchy then expected. As an example:

  (require '[lambdaisland.deep-diff2 :as diff])

  (def d1 #{{:foo 1M} {:bar 2}})
  (def d2 #{{:foo 1} {:bar 2}})
  (diff/pretty-print (diff/diff d1 d2))
  ;; #{+{:foo 1} -{:foo 1M} {:bar 2}}

  (def d1 #{{:foo 1M}})
  (def d2 #{{:foo 1}})
  (diff/pretty-print (diff/diff d1 d2))
  ;; #{{:foo -1M +1}} 

I would have expected the diff to appear in the first case the same as in the second case.

plexus commented 1 year ago

There might be a way to make this better, I'm not sure, but given that sets have no deterministic ordering I don't think there's a good way to handle this in a general way. How do we know which set element to diff with which other set element?

alysbrooks commented 1 year ago

If we generated multiple equivalent diffs, we could implement various heuristics for picking the "best" one, but that would add significant complexity and consume more resources, so not a quick project.

FiV0 commented 1 year ago

I agree that handling all the cases and ordering is probably hard (and expensive computewise). I just found it weird that in both cases above we are subdiffing {:foo 1} and {:foo 1M}, but end up with different diffs for that part.

Do you have a notion of distance for the diffs?

plexus commented 1 year ago

The reason you get a different result is that the seqs over these sets have different ordering

(seq #{{:foo 1M} {:bar 2}}) ;; => ({:foo 1M} {:bar 2})
(seq #{{:foo 1} {:bar 2}})  ;; => ({:bar 2} {:foo 1})