Value type hash code (original) (raw)

Jonas Konrad me at yawk.at
Thu Apr 19 16:04:50 UTC 2018


That would make it useless in almost all cases where reference types are present in the value. Even something simple like a String field (which is definitely immutable) would use identity hash and make this hashcode useless.

It might be nice conceptually but if we do that we might as well throw an exception when a reference type is present. It'd be useful in the same cases (meaning none) and it would at least be fail-fast and users wouldn't be bitten by behaviour like identityHashCode of strings.

On 04/19/2018 12:38 PM, Daniel Latrémolière wrote:

A value type is explicitly immutable by design and not by documentation, then equals/hashcode methods needs to have the same immutable behaviour not just by documentation but also by design. These methods can not be delegated to user (because it would allow value type design bugs in immutability if hashCode change when user implement hash code with a random function or by following a reference to a mutable object.

The only really immutable available information for a reference field is System.identityHashCode(), then it need to be used. NB: A value type is (for me) pure data designed for performance: it can be a pair of integers, but it can not be a fraction. If you want comparison behaviour of a fraction, you can do a fast equalsAsFraction method by cross multiplication, but you can not implements fast and correct hash code (you would need to simplify the fraction to have no common divider between numerator and denominator).

Daniel. Le 19/04/2018 à 10:04, David Simms a écrit :

Summary of points raised:  * Implementation specification: besides the general contract [1], implementation doesn't need to be specified o this has advantages to JDK and JVM developers to enable change, protects users from said future changes  * Default implementation o Javac could provide the default implementation + bloats class file forever o BSM mechanism described by John enables more flexibility, efficiency and better optimization opportunities + e.g. BSM may read annotations at lookup time, allowing users to decoratively specify which fields and which method for handling references + may have bootstrapping issues, if so, said JDK classes need to implement hashCode themselves o Even if the JVM doesn't implement it directly, it shouldn't crash or behave erratically + JVM: Return 0, -1, 4711, or throw exception (doesn't matter given the point above, 0 for argument's sake) ?  * On the topic of calling reference fields, calling "hashCode()" or using "System.identityHashCode()" o "System.identityHashCode()" is consistent with "Arrays.hashCode(Object[])" [2] + Almost meaningless to the user, many think it is a mistake o Calling "hashCode()" is consistent with "List.hashCode(Object[])" [3] + may result in recursion or costly traversal # This is fine, user needs to decide what to do by supplying their own... o BSM method can help user to declare what they prefer Obviously a similar discussion can be had for "equals()", except this issue doesn't really involve the JVM (as hashCode does). Clearly being able to declaratively control hash/equals deep vs identity is very powerful...we'll be prototyping looking for further technical issues.

Feel free to call shenanigans if I have something wrong. Agreeing to disagree is also an option, and nothing is set in stone, still prototyping. Thanks for all the feedback ! /David Simms [1] https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#hashCode() [2] https://docs.oracle.com/javase/10/docs/api/java/util/Arrays.html#hashCode(java.lang.Object%5B%5D) [3] https://docs.oracle.com/javase/10/docs/api/java/util/List.html#hashCode() --- Just for history, my response to Rémi's mail last week on this subject in amber (forbidden because discussion is not allowed on the corresponding mailing list, and his following copy [1] of his mail was on a reserved mailing list, then I had administrative phobia): [1]: http://mail.openjdk.java.net/pipermail/amber-spec-experts/2018-April/000557.html -------- Message transféré -------- Sujet :     Re: Record design (and ancillary fields) Date :     Sun, 15 Apr 2018 06:19:44 +0200 De :     Daniel Latrémolière <daniel.latremoliere at gmail.com> Pour :     Remi Forax <forax at univ-mlv.fr> Copie à :     amber-spec-comments <amber-spec-comments at openjdk.java.net> Le 14/04/2018 à 23:18, Remi Forax a écrit : I do not think we have to do something specific for supporting relational database mapping,[...] I'm not asking for object-relational mapping, only for not forgetting experience from database design. MapReduce in Google index database is not the same than map/reduce in java.util.stream, but they are the same design pattern. PS: Given primitive/value type disallow cyclical references, this will prohibit StackOverflowException in equals/hashCode methods. only if an equals on a value type that contains an object doesn't call equals on that object. Another design would probably be a bug in these compiler generated methods for value type: value types are using pass-by-value convention for methods. They are like primitives (boolean, int, float, ... and address!). For a value type, a field targeting an object is opaque, value type know only address, not pointed object. From point of view of compiler, equals/hashCode methods of value types would be using all fields but these fields can only be primitive or value types. Then, recursion is only possible between value types, and always descending, then finite (like Fermat). After flattening all levels of value types inside a value type, it will become non recursive and using only primitives. Given pass-by-value design, these generated methods would be required to be defined like a field containing an address value (not a field targeting an object): - equals use identity test on the field (not equality test). - hashCode use result of System.identityHashCode on targeted object (not hashCode virtual method, which would also create potentially NullPointerException in case of null address if not tested before). Daniel.



More information about the valhalla-dev mailing list