# ANN: WhyNotEqual.jl

**URL:** <https://discourse.julialang.org/t/ann-whynotequal-jl/98539>\
**Category:** Package Announcements\
**Tags:** package, announcement\
**Created:** [May 9, 2023, 9:28am UTC](https://discourse.julialang.org/t/ann-whynotequal-jl/98539 "2023-05-09T09:28:31Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [May 9, 2023, 9:28am UTC](https://discourse.julialang.org/t/ann-whynotequal-jl/98539/1 "2023-05-09T09:28:31Z")

</div>

Ever encountered a situation like this:

```julia
@test expected == result
Test Failed at /home/jan/.julia/dev/WhyNotEqual/doit.jl:21
  Expression: expected == result
   Evaluated: (v = (hello = :world, language = :julia), w = 42, x = [1, 2, 3, 4, 5], y = AB(1, 2), 
z = Dict{AB, Any}(AB(2, 3) => AB(3, ()), AB(1, 2) => 3), zz = (foo = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10
  … 91, 92, 93, 94, 95, 96, 97, 98, 99, 100], bar = :bar)) == (v = (hello = :world, language = :ju
lia), w = 42, x = [1, 2, 3, 4, 5], y = AB(1, 2), z = Dict{AB, Any}(AB(2, 3) => AB(4, ()), AB(1, 2) 
=> 3), zz = (foo = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10 … 91, 92, 93, 94, 95, 96, 97, 98, 99, 100], bar
 = :bar))
ERROR: LoadError: There was an error during testing

```

Can you spot the difference? This [WhyNotEqual.jl](https://github.com/jw3126/WhyNotEqual.jl) can do it for you:

```julia
using WhyNotEqual
whynot(==, expected, result)

```

```julia
DifferentAndNoChildren: When applying `lens` to both objects, we get `obj1` and `obj2`.
obj1 and obj2 are different, but they don't have any children.
lens: (@optic _.z[AB(2, 3)].a)
obj1: 3
obj2: 4

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [May 9, 2023, 9:42am UTC](https://discourse.julialang.org/t/ann-whynotequal-jl/98539/2 "2023-05-09T09:42:12Z")

</div>

A beautiful application of the amazing Accessors.jl API!

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [May 9, 2023, 10:03am UTC](https://discourse.julialang.org/t/ann-whynotequal-jl/98539/3 "2023-05-09T10:03:45Z")

</div>

I really like the idea, thanks for creating this! But I wonder if the output could be more useful: does it really provide that much more information than the fact that the two aren’t equal? Sure, I can see that 3 is different from 4, but in many cases I may not be able to guess where that 3 or 4 came from. Scanning those two objects, there are a lot of 3s and 4s, which “slot” holds the difference?

What about using something like [AbstractTrees](https://github.com/JuliaCollections/AbstractTrees.jl) to provide context? Or maybe even [FoldingTrees](https://github.com/JuliaCollections/FoldingTrees.jl) to make it interactive?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [May 9, 2023, 10:04am UTC](https://discourse.julialang.org/t/ann-whynotequal-jl/98539/4 "2023-05-09T10:04:12Z")

</div>

Very cool. Could it also do other comparisons, like `<`?

I wonder if a macro could do something like this:

```julia
>> @whynot expected == result

expected.z[AB(2, 3)].a: 3
result.z[AB(2, 3)].a: 4

```

?

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [May 9, 2023, 10:04am UTC](https://discourse.julialang.org/t/ann-whynotequal-jl/98539/5 "2023-05-09T10:04:34Z")

</div>

So interesting line is this:

```julia
lens: (@optic _.z[AB(2, 3)].a)

```

Sure I am open to make it interactive or make the message more friendly.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [May 9, 2023, 10:06am UTC](https://discourse.julialang.org/t/ann-whynotequal-jl/98539/6 "2023-05-09T10:06:08Z")

</div>

Ah, good. Might be worth explaining, it’s very mysterious to someone who has never looked at Accessors.jl before. Not exactly sure how to do that, though, without digging in to that package.

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [May 9, 2023, 10:08am UTC](https://discourse.julialang.org/t/ann-whynotequal-jl/98539/7 "2023-05-09T10:08:35Z")

</div>

Yeah, that is probably are more friendly error message.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [May 9, 2023, 11:14am UTC](https://discourse.julialang.org/t/ann-whynotequal-jl/98539/8 "2023-05-09T11:14:52Z")

</div>

Perhaps some inspiration for the display of the diff can be had from [GitHub - ssfrr/DeepDiffs.jl: Compute and pretty-print diffs for data structures like arrays and dictionaries](https://github.com/ssfrr/DeepDiffs.jl) ?

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [May 9, 2023, 11:24am UTC](https://discourse.julialang.org/t/ann-whynotequal-jl/98539/9 "2023-05-09T11:24:11Z")

</div>

`Very cool. Could it also do other comparisons, like <?`

Instead of `whynot(==, obj1, obj2)` you can do `whynot(cmp, obj1, obj2)` for any comparison that takes two objects and returns a bool. This will generally work well for `==`, `===`, `isequal` or anything else, that satisfies the same structural recursion rules. For instance `cmp` of two arrays should imply `cmp` for each element. Or `cmp` for two objects should imply `cmp` for all of their properties etc.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [May 9, 2023, 8:48pm UTC](https://discourse.julialang.org/t/ann-whynotequal-jl/98539/10 "2023-05-09T20:48:57Z")

</div>

Looks really neat!  
Any way to list all mismatches, not only the first one?

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [May 11, 2023, 9:00am UTC](https://discourse.julialang.org/t/ann-whynotequal-jl/98539/11 "2023-05-11T09:00:31Z")

</div>

Currently not, but I don’t see significant technical obstacles to doing this.
