# Hashes change whenever package is pre-compiled

**URL:** <https://discourse.julialang.org/t/hashes-change-whenever-package-is-pre-compiled/37555>\
**Category:** General Usage\
**Tags:** question, package\
**Created:** [April 14, 2020, 10:19am UTC](https://discourse.julialang.org/t/hashes-change-whenever-package-is-pre-compiled/37555 "2020-04-14T10:19:03Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [April 14, 2020, 10:19am UTC](https://discourse.julialang.org/t/hashes-change-whenever-package-is-pre-compiled/37555/1 "2020-04-14T10:19:03Z")

</div>

I have a very simple package I am developing, say defined like this:

```julia
module MyPkg
struct A
   a::Int
end
end # module

```

Now in a Julia session, I import this package, and compute a hash of an object:

```julia
julia> using MyPkg # first-usage, precompiles
julia> hash(A(5)) # returns a hash

```

Next, I do some modification of the package source code,

```julia
module MyPkg
struct A
   a::Int
end
f() = 2 # modification of package source code
end # module

```

So next time I use this package, a precompilation is triggered again:

```julia
julia> using MyPkg # precompiles again
julia> hash(A(5)) # returns a different hash than before!

```

Even though the type `A` has not changed, for some reason I now get a different hash for `A(5)`. Two questions:

1. Why is this happening? Why the hash is not the same in the second usage?
2. How can I get a “deterministic” hash that doesn’t change whenever the package is pre-compiled?

Note that here I am doing “minor” modifications, in that things like the package identity (name, uuid) nor the type `A` definition have changed. So what is the hash depending on that is changing here?

---

<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:** [April 14, 2020, 11:07am UTC](https://discourse.julialang.org/t/hashes-change-whenever-package-is-pre-compiled/37555/2 "2020-04-14T11:07:06Z")

</div>

The fallback implementation of `hash` uses `objectid`, which is very fast but can change from sessions to session.

The solution is writing your own `hash` function.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [April 14, 2020, 11:18am UTC](https://discourse.julialang.org/t/hashes-change-whenever-package-is-pre-compiled/37555/3 "2020-04-14T11:18:43Z")

</div>

Is it possible to have a generic hash function, that doesn’t have this instability?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [April 14, 2020, 11:43am UTC](https://discourse.julialang.org/t/hashes-change-whenever-package-is-pre-compiled/37555/4 "2020-04-14T11:43:03Z")

</div>

[https://github.com/andrewcooke/AutoHashEquals.jl](https://github.com/andrewcooke/AutoHashEquals.jl)

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [April 14, 2020, 11:47am UTC](https://discourse.julialang.org/t/hashes-change-whenever-package-is-pre-compiled/37555/5 "2020-04-14T11:47:06Z")

</div>

> [@Tamas\_Papp](#):
>
> The fallback implementation of `hash` uses `objectid` , which is very fast but can change from sessions to session.

Thanks, I think I understand what the problem is. However it seems that the `hash` should not change if the identity of the object doesn’t change?

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [April 14, 2020, 11:48am UTC](https://discourse.julialang.org/t/hashes-change-whenever-package-is-pre-compiled/37555/6 "2020-04-14T11:48:47Z")

</div>

AutoHashEquals needs to be used at the definition of the type. I meant I would like to have a generic hash that can be used for an outside type (probably defined without AutoHashEquals), and not have this instability.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [April 14, 2020, 11:56am UTC](https://discourse.julialang.org/t/hashes-change-whenever-package-is-pre-compiled/37555/7 "2020-04-14T11:56:15Z")

</div>

> [@e3c6](#):
>
> I meant I would like to have a generic hash that can be used for an outside type (probably defined without AutoHashEquals), and not have this instability.

Not sure what you mean here. `myhash(x) = UInt64(1)` would satisfy your criteria.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [April 14, 2020, 12:11pm UTC](https://discourse.julialang.org/t/hashes-change-whenever-package-is-pre-compiled/37555/8 "2020-04-14T12:11:32Z")

</div>

> [@kristoffer.carlsson](#):
>
> Not sure what you mean here. `myhash(x) = UInt64(1)` would satisfy your criteria.

Yes but that would have too many collisions. I mean satisfying the normal typical requirements of a hash function (as few collisions as possible), but still being consistent even if the package defining a type has to be precompiled (if the type definition itself does not change).

---

<div class="post-metadata">

**Author:** ![krrutkow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krrutkow/32/9138_2.png) [@krrutkow](https://discourse.julialang.org/u/krrutkow)\
**Post date:** [April 14, 2020, 12:16pm UTC](https://discourse.julialang.org/t/hashes-change-whenever-package-is-pre-compiled/37555/9 "2020-04-14T12:16:35Z")

</div>

What you are expecting is a persistent hash function, which is not really what `hash` is meant for. Look to something like [https://github.com/staticfloat/SHA.jl](https://github.com/staticfloat/SHA.jl) for supporting persistent hashing. As a core/builtin function, `hash` should have the goal of being very performant without excess functionality. I use the fact that it can produce different hashes in different Julia sessions to actually uncover bugs in code. Not my code, of course… 😏

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [April 14, 2020, 12:23pm UTC](https://discourse.julialang.org/t/hashes-change-whenever-package-is-pre-compiled/37555/10 "2020-04-14T12:23:01Z")

</div>

Thanks. Is [https://github.com/staticfloat/SHA.jl](https://github.com/staticfloat/SHA.jl) the same as the stdlib SHA? Unfortunately it seems these functions only take certain kind of arguments (strings, `Array{UInt8}`, or `IO` objects).

---

<div class="post-metadata">

**Author:** ![krrutkow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krrutkow/32/9138_2.png) [@krrutkow](https://discourse.julialang.org/u/krrutkow)\
**Post date:** [April 14, 2020, 12:30pm UTC](https://discourse.julialang.org/t/hashes-change-whenever-package-is-pre-compiled/37555/11 "2020-04-14T12:30:27Z")

</div>

Yeah, it might be in stdlibs now actually, been a while since I used it directly… You might need to create a method to dispatch for your types, or a generic method to iterate over the `propertynames` of types to build the SHA.

---

<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:** [April 14, 2020, 12:46pm UTC](https://discourse.julialang.org/t/hashes-change-whenever-package-is-pre-compiled/37555/12 "2020-04-14T12:46:37Z")

</div>

> [@e3c6](#):
>
> I meant I would like to have a generic hash that can be used for an outside type (probably defined without AutoHashEquals), and not have this instability.

That would be an option, but note the performance trade-off — for many cases `objectid` is a good choice.

Generally I think it would make sense to have various predefined implementations of hashing (and of course equality, to be consistent), to which one can opt-in with traits.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [April 14, 2020, 12:49pm UTC](https://discourse.julialang.org/t/hashes-change-whenever-package-is-pre-compiled/37555/13 "2020-04-14T12:49:13Z")

</div>

> [@Tamas\_Papp](#):
>
> Generally I think it would make sense to have various predefined implementations of hashing (and of course equality, to be consistent), to which one can opt-in with traits.

Could also be implemented in separate packages. Something like `SHA` mentioned above, if it handled generic types.
