Skip to content

hash(x, h::UInt=zero(UInt)) => hash(x; h::UInt=zero(UInt)) ? #26015

Open
@StefanKarpinski

Description

If we make the incoming hash argument a keyword instead of positional it would have a few benefits:

  1. A common mistake when defining custom hashing is to define hash(x::MyType) instead of hash(x::MyType, h::UInt). This leads to broken behavior with no error. If the initial hash value was supplied by generic code using the hash function as a keyword argument, this mistake would get a clear error message that hash(x::MyType) does not accept an h keyword argument, which seems like it would make it much easier to figure out what's wrong.

  2. It would open up the hash API to allow a varargs version that chain hashes its arguments: hash(arg1, args...; h::UInt=zero(UInt)) would be defined like this:

function hash(args...; h::UInt=zero(UInt))
    for arg in args
        h = hash(arg, h=h)
    end
    return h
end
  1. Ideally, the common pattern of generating a random value for each type and explicitly using it in custom hashing functions could be avoided and replaced with a compile-time call to hashing a type name or something like that. I would like to define a custom hashing function like this:
Base.hash(x::MyType; h::UInt=zero(Uint)) = hash(h = h + hash(MyType), x.f1, x.f2, x.f4)

Note: a single call to hash does chaining for you; the call to hash(MyType) is constant could be evaluated at compile time – if we base hash(MyType) on a canonical name of MyType then it would be stable across Julia processes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    designDesign of APIs or of the language itselfhashingkeyword argumentsf(x; keyword=arguments)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions