Skip to content

Conversation

@ShapelessCat
Copy link
Contributor

No description provided.

@ShapelessCat
Copy link
Contributor Author

ShapelessCat commented Jun 27, 2021

Also, should we use Scala's hash code function .## here instead of Java's .hashCode?
.## handles Java boxed values differently.

val i1Boxed = java.lang.Integer.valueOf(1)
val d1Boxed = java.lang.Double.valueOf(1.0)

i1Boxed == d1Boxed        // true
i1Boxed equals d1Boxed    // false

i1Boxed.hashCode   // 1
i1Boxed.##         // 1

d1Boxed.hashCode  // 1072693248
d1Boxed.##        // 1

In Scala's hash-based data structures, the method .## is used:

val mp = HashMap(d1Boxed -> 3, 1 -> 4)
// val mp: HashMap[Matchable, Int] = HashMap(1.0 -> 4)

If .hashCode was used, this hash-map should include two key-value pairs.

@ShapelessCat
Copy link
Contributor Author

ShapelessCat commented Jun 27, 2021

I also created two errata reports through https://www.oreilly.com/catalog/errataunconfirmed.csp?isbn=0636920365686.

Copy link
Owner

@deanwampler deanwampler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching these typos!

@deanwampler
Copy link
Owner

Apparently ## behaves differently from hashCode for boxed value types and null: https://dotty.epfl.ch/api/scala/Any.html###-0

@deanwampler deanwampler merged commit cbce659 into deanwampler:master Jun 28, 2021
@ShapelessCat
Copy link
Contributor Author

ShapelessCat commented Jun 28, 2021

Apparently ## behaves differently from hashCode for boxed value types and null: https://dotty.epfl.ch/api/scala/Any.html###-0

I mean, in the first paragraph of the section "Case Objects and hashCode", you write
"The notion of equality goes hand in hand with the results of hashing an object, as done by hashCode, which is used in hash-based data structures, like the default Map and Set implementations."

This sentence is correct, but do you think there can be a new footnote to mention ##? Because of the usages of ##, we have this:

val mp = HashMap(d1Boxed -> 3, 1 -> 4)
// val mp: HashMap[Matchable, Int] = HashMap(1.0 -> 4)

If people don't know ##, they may think Scala hash-based data structures use hashCode directly, then if they didn't try some code, they may think val mp = HashMap(d1Boxed -> 3, 1 -> 4) will be a two key-value pairs Map after evaluation.

@ShapelessCat ShapelessCat deleted the fix-CaseObjectHashCode branch June 28, 2021 17:51
@ddl-deanwampler
Copy link

I'll consider a footnote that recommends reading the scaladoc for ##, but the different behavior is an edge case. Most people will let Map and other tools call whatever hash code method on keys it wants to use internally. As long as the same method is used consistently, the results will be consistent. Also, it will be very rare for people use Java wrappers around doubles in Scala code. The behavior for null is also different, but using null in any context where a hash code will be computed is an application bug anyway.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants