# Deep-equal

**URL:** <https://discourse.julialang.org/t/deep-equal/45315>\
**Category:** General Usage\
**Created:** [August 21, 2020, 10:09am UTC](https://discourse.julialang.org/t/deep-equal/45315 "2020-08-21T10:09:04Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [August 21, 2020, 10:09am UTC](https://discourse.julialang.org/t/deep-equal/45315/1 "2020-08-21T10:09:04Z")

</div>

We have `deepcopy`, which recursively copies the object down to its “atoms”. Has anyone written the corresponding `deepequal`, such that `deepequal(deepcopy(x), deepcopy(x)) == true`?

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [August 21, 2020, 11:13am UTC](https://discourse.julialang.org/t/deep-equal/45315/2 "2020-08-21T11:13:29Z")

</div>

Under what circumstance would `deepequal` yield different results to `equal`? For `deepcopy`, presumably you would want to change some component and not affect the object you copied from.

But I can’t think of a reason why you would need a `deepequal`.

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [August 21, 2020, 11:25am UTC](https://discourse.julialang.org/t/deep-equal/45315/3 "2020-08-21T11:25:18Z")

</div>

🤷‍♂️ Whenever you want to know that two structures are equivalent?

```julia
julia> isequal(Ref(1), Ref(1))
false

```

That would be `deepequal`.

I think it’s a bit like `deepcopy`. Not super clean semantically, but can be very useful for testing/debugging/rapid development.

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [August 21, 2020, 11:31am UTC](https://discourse.julialang.org/t/deep-equal/45315/4 "2020-08-21T11:31:32Z")

</div>

FWIW, there’s a classic Lisp article on why multiple `copy` / equality implementations are needed: [P.S.: The Best of Intentions](https://www.nhplace.com/kent/PS/EQUAL.html)

---

<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:** [August 21, 2020, 12:13pm UTC](https://discourse.julialang.org/t/deep-equal/45315/5 "2020-08-21T12:13:23Z")

</div>

Not that I know of. FWIW, I think that generally `==` or `isequal` should be used by most user code, and types should just define the relevant methods.

That said, I often define custom equality operators (eg for unit testing), it is pretty easy to do recursively. Cf `fieldnames` for `struct`, use in a generated function.

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [August 21, 2020, 12:20pm UTC](https://discourse.julialang.org/t/deep-equal/45315/6 "2020-08-21T12:20:18Z")

</div>

There doesn’t exist one, but you can easily define your own if you really need it. The following function is one I’ve found useful in the past to extend `==` for my own types:

```julia
function deepequal(a, b)
    typeof(a) == typeof(b) || return false
    N = fieldcount(typeof(a))
    for i in 1:N
        getfield(a, i) == getfield(b, i) || return false
    end
    return true
end

```

I also just cooked up the following which is more generic, but haven’t tested it very thoroughly, and really don’t know if it’s really worth it to write as a `@generated` function…

```julia
@generated function deepequal(a, b)
    # check the types
    a == b || return :(false)
    N = fieldcount(a)

    # fallback to regular comparison for primitive types
    N == 0 && return :(a == b)

    # unroll the loop, because it's cool!
    quote
        Base.@nexprs $N i -> (getfield(a, i) == getfield(b, i) || return false)
        return true
    end
end

```

edit: actually, for what you want both functions should be recursive. The comparisons should be `deepequal(getfield(a, i), getfield(b, i))` rather than `==`

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [August 21, 2020, 1:49pm UTC](https://discourse.julialang.org/t/deep-equal/45315/7 "2020-08-21T13:49:43Z")

</div>

Thanks! I thought of writing my own, but the [deepcopy internals](https://github.com/JuliaLang/julia/blob/master/base/deepcopy.jl) are surprisingly complex. Eg. Your `deepequal` would fail with circular structures, and it might fail with arrays/dicts. I was hoping someone had provided it in a package or something.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [August 21, 2020, 3:37pm UTC](https://discourse.julialang.org/t/deep-equal/45315/8 "2020-08-21T15:37:25Z")

</div>

Note that `Ref(1) == Ref(1)` falls back to `===` by default. You can check this with `julia> @edit Ref(1) == Ref(1)`. Most regular containers check their content already (e.g. `[1] == [1]`), so if you define `==` on your type to check its own fields as well, it should work out fine. Just make sure to special case circular dependencies or disallow your type to contain itself.
