Would it make sense for hash
to be variadic? In Python it is easy and cheap to create and pass a tuple to hash
to hash multiple objects, but this is not possible in Mojo as Hashable
objects are not necessarily Copyable
and Movable
. It also results in unnecessary copying. I propose making the following change to the builtin hash
function.
from hashlib import Hasher
from hashlib._fnv1a import Fnv1a
fn hash[*Ts: Hashable, HasherType: Hasher = Fnv1a](*hashable: *Ts) -> UInt64:
var hasher = HasherType()
@parameter
for i in range(len(VariadicList(Ts))):
hasher.update(hashable[i])
var value = hasher^.finish()
return value
fn main():
print(hash(1, 2.2, String("hello")))
I could see it being useful in some cases, but I think that you’re just as likely to want to add more stuff after the pack. I could see an argument for a “hash all of these things and give me the hasher” function.
However, right now hash
is designed to match the signature of Python’s hash
. For anything else, you should probably be using a hasher so you have better control over memory.
Thanks for a good answer!
The main use case I have is caching the hash value for large immutable structs. I made some changes based on your feedback, but I agree that this functionality does not need to be added to stdlib.
from hashlib import Hasher
from hashlib._fnv1a import Fnv1a
fn hash[*Ts: Hashable, HasherType: Hasher = Fnv1a](*hashable: *Ts, out hasher: HasherType):
hasher = HasherType()
@parameter
for i in range(len(VariadicList(Ts))):
hasher.update(hashable[i])
fn main():
print(hash(1, 2.2, String("hello")).finish())