Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
StefanKarpinski opened this issue Feb 12, 2018 · 3 comments
Open

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

StefanKarpinski opened this issue Feb 12, 2018 · 3 comments
Labels
design Design of APIs or of the language itself hashing keyword arguments f(x; keyword=arguments)

Comments

@StefanKarpinski
Copy link
Member

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.

@StefanKarpinski StefanKarpinski added the triage This should be discussed on a triage call label Feb 12, 2018
@ararslan ararslan added the keyword arguments f(x; keyword=arguments) label Feb 12, 2018
@JeffBezanson
Copy link
Member

would get a clear error message that hash(x::MyType) does not accept an h keyword argument

Unfortunately, due to #9498 I don't think this will work. Instead a less-specific method that does accept the keyword argument will be called.

The definition in point 3 can be written now as

Base.hash(x::MyType, h::UInt=zero(Uint)) = hash((x.f1, x.f2, x.f4), h + hash(MyType))

so I would say that's a separate issue.

@StefanKarpinski
Copy link
Member Author

Fair enough. I guess that means we don't really have to change anything then?

@StefanKarpinski StefanKarpinski added this to the 1.x milestone Feb 15, 2018
@StefanKarpinski
Copy link
Member Author

We can consider non-breaking aspects of this in the 1.x timeframe. Breaking changes to the hashing protocol will have to wait until 2.0.

@StefanKarpinski StefanKarpinski removed the triage This should be discussed on a triage call label Feb 15, 2018
@DilumAluthge DilumAluthge removed this from the 1.x milestone Mar 13, 2022
@nsajko nsajko added hashing design Design of APIs or of the language itself labels Dec 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design Design of APIs or of the language itself hashing keyword arguments f(x; keyword=arguments)
Projects
None yet
Development

No branches or pull requests

5 participants