Field hash is deprecated

private let myMap: HashMap.HashMap<Nat, MyObject> = 
   HashMap.HashMap<Nat, MyObject>(10, Nat.equal, Hash.hash,);

throws following warning with dfx v0.10.0

warning [M0154], field hash is deprecated:
For large `Nat` values consider using a bespoke hash function that considers all of the argument's bits.

Somebody already migrated and has an example to share?

1 Like

I am waiting for a new release of moc so that we have support for shift primitives for Nat.
The feature is already merged (e4125ef), but not yet included in a release (as of v0.6.29).

Once this feature is added, it will be much easier to create hash functions.
You could already use SHA hashes, but that seems a little inefficient (depending on the use case).

EDIT: as long as you can convert your data structure to a blob, you can always use Blob.hash (ref).

// NOTE: this is NOT efficient!
private let bl = 256;

private func bytelen(n : Nat) : Nat {
    var m = n; var l = 0;
    while (m > 0) { l += 1; m /= bl; };

public func natToArray(n : Nat) : [Nat8] {
    var m = n; let l = bytelen(n);
    Prim.Array_tabulate(l, func (i : Nat) : Nat8 {
        let n = m % bl; m /= bl;

same issue with dfx 0.12.1, does anyone has any better solution to migrate?

Don’t use hashmap. It has various problems. There are better alternatives.


Or more precisely, at least consider not using Hash.hash as your hash function, as the message indicates.

Instead, I think answer is that developers should use a library that hashes the full value for them, unlike the current (very poor) hash function provided by base.

I wasn’t aware of that message, but it makes sense.

If you look at the implementation, it’s not using the full Nat , and thus may introduce a lot of collisions for certain kinds of Nat sets that have common bits once they go through Prim.intToNat32Wrap.

My guess (not sure) is that @quint has a better hash function for Nat by now?


Does Blob.hash suffer from the same issue?

Interesting question!

Blob.hash uses a different, well-known hash function (crc32), at a different level (Rust run-time system code).

Indeed, @quint has a library for doing crc32 in user code:

1 Like