lambdaisland/deep-diff2

Show diff at deeper level (Sets)

FiV0 opened this issue · 4 comments

FiV0 commented

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.

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?

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

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?

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})