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; };
    l;
};

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;
        Prim.natToNat8(n);
    });
};
3 Likes

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.

3 Likes

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?

2 Likes

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