www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Getting the hash of any value easily?

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
A coworker asked about the idiomatic way to get the hash of a string in 
D, and somewhat surprisingly the best answer I could find is: "to get 
the hash of an lvalue x, call typeof(x).getHash(&x)."

That's admittedly quite clunky and indirect. Is it worth it to simplify 
that by means of a template in object.di?


Andrei
Jul 30 2014
next sibling parent Daniel Gibson <metalcaedes gmail.com> writes:
Am 31.07.2014 03:07, schrieb Andrei Alexandrescu:
 A coworker asked about the idiomatic way to get the hash of a string in
 D, and somewhat surprisingly the best answer I could find is: "to get
 the hash of an lvalue x, call typeof(x).getHash(&x)."

 That's admittedly quite clunky and indirect. Is it worth it to simplify
 that by means of a template in object.di?


 Andrei
I proposed something like the following in another thread and think it would be really useful (to implement toHash() amongst other things): hash_t createHash(T...)(T args) { // return a hash over all arguments } In that thread (I think it was "WAT: opCmp and opEquals woes") it was implied that currently the compiler generates a toHash() automagically by hashing all members (of a struct or class) - analogous to opEquals that just compares all members. I can't find any documentation on that behavior.. but if it indeed exists there must already be a sensible hash algorithm for multiple values of different types which could just be reused here. Of course hashing a single value is just a special case of this. Cheers, Daniel
Jul 30 2014
prev sibling parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Wed, Jul 30, 2014 at 06:07:57PM -0700, Andrei Alexandrescu via Digitalmars-d
wrote:
 A coworker asked about the idiomatic way to get the hash of a string
 in D, and somewhat surprisingly the best answer I could find is: "to
 get the hash of an lvalue x, call typeof(x).getHash(&x)."
 
 That's admittedly quite clunky and indirect. Is it worth it to
 simplify that by means of a template in object.di?
[...] It's about time somebody noticed this!! Why don't we just expose druntime's core.internal.hash.hashOf() function somewhere? It's not as though it isn't already in druntime, so the function is already present in the executable, we just need a public declaration of it somewhere that users can make use of. Not to mention, it's already a template function that correctly calculates the hash of various built-in types. T -- The problem with the world is that everybody else is stupid.
Jul 31 2014
parent reply "Brian Schott" <briancschott gmail.com> writes:
On Thursday, 31 July 2014 at 17:39:43 UTC, H. S. Teoh via 
Digitalmars-d wrote:
 It's about time somebody noticed this!!

 Why don't we just expose druntime's core.internal.hash.hashOf() 
 function
 somewhere? It's not as though it isn't already in druntime, so 
 the
 function is already present in the executable, we just need a 
 public
 declaration of it somewhere that users can make use of.

 Not to mention, it's already a template function that correctly
 calculates the hash of various built-in types.


 T
I've often just put "import core.internal.hash;" in my code. Once we get this solved we need to work on the fact that many hash generation functions are not pure. (Object.toHash not being pure prevents a lot of containers from being used in pure templated code)
Jul 31 2014
parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Thu, Jul 31, 2014 at 07:08:16PM +0000, Brian Schott via Digitalmars-d wrote:
 On Thursday, 31 July 2014 at 17:39:43 UTC, H. S. Teoh via Digitalmars-d
 wrote:
It's about time somebody noticed this!!

Why don't we just expose druntime's core.internal.hash.hashOf()
function somewhere? It's not as though it isn't already in druntime,
so the function is already present in the executable, we just need a
public declaration of it somewhere that users can make use of.

Not to mention, it's already a template function that correctly
calculates the hash of various built-in types.


T
I've often just put "import core.internal.hash;" in my code. Once we get this solved we need to work on the fact that many hash generation functions are not pure.
I'm not sure I understand why. Un- safe (probably should be trusted) I can understand, since you basically have to treat arbitrary typed data as ubyte[] in order to compute the hash, but impure? I don't see it. The definition of hash function requires that its output depend only on its input(s), so why can't it be pure?
 (Object.toHash not being pure prevents a lot of containers from being
 used in pure templated code)
Yeah, this is one of the things that prompted us to move towards removing toHash from Object. T -- Spaghetti code may be tangly, but lasagna code is just cheesy.
Jul 31 2014
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 07/31/2014 09:40 PM, H. S. Teoh via Digitalmars-d wrote:
 The definition of hash function requires that its output depend only on its
 input(s), so why can't it be pure?
For example, because it might actually be random on the first invocation and cached later. :-) http://hg.openjdk.java.net/jdk7/jdk7/jdk/file/tip/src/share/classes/java/lang/Object.java#l101 http://blogs.tedneward.com/CommentView,guid,eca26c5e-307c-4b7c-93 b-2eaf5b176e98.aspx (caution, broken script, didn't find a better source to quote quickly.)
Jul 31 2014
parent "safety0ff" <safety0ff.dev gmail.com> writes:
On Thursday, 31 July 2014 at 22:45:44 UTC, Timon Gehr wrote:
 For example, because it might actually be random on the first 
 invocation and cached later. :-)
This is interesting. Some hash functions in druntime might break in an environment with a precise moving GC.
Jul 31 2014