Thread
#stdlib
    m

    Marc Knaup

    3 years ago
    Can we kotlinify Java’s
    Objects.hash(foo, bar, baz, …)
    to something like this?
    hash { foo x bar x baz x … }
    Just the boxing is a little tricky as well as getting it to work with just a single non-
    Int
    value without introducing boxing. Implementation:
    inline fun hash(block: HashScope.() -> Int) =
    	HashScope.block()
    
    object HashScope {
    
    	inline infix fun Any?.x(hashable: Any?) =
    		(31 * hashCode()) + hashable.hashCode()
    
    	inline infix fun Any?.x(hashable: Int) =
    		(31 * hashCode()) + hashable
    
    	inline infix fun Int.x(hashable: Any?) =
    		(31 * this) + hashable.hashCode()
    
    	inline infix fun Int.x(hashable: Int) =
    		(31 * this) + hashable
    }
    
    class Example(val foo: String, val bar: List<Any>?, val baz: Int) {
    
    	override fun hashCode() =
    		hash { foo x bar x baz }
    }
    j

    jw

    3 years ago
    What's the advantage over just
    hashOf(vararg args: Any?)
    which seems more idiomatic than a somewhat-cryptic DSL? Then you can add an intrinsic in the compiler, similar to what's being explored in javac.
    m

    Marc Knaup

    3 years ago
    Java’s isn’t multiplatform. Also, doesn’t
    Objects.hash()
    cause a lot of wrapping (primitives/inline classes)? + additional array and ArrayList allocation. Or are calls replaced by something intrinsic at runtime?
    Also intrinsic would need compiler support. My suggestion would be pure Kotlin within stdlib.
    j

    jw

    3 years ago
    Have you observed the boxing to be a problem in practice?
    Mine also is a pure Kotlin suggestion that could be aliases to the JDK version for the JVM. The intrinsic is only for increasing performance, probably through invoke dynamic.
    m

    Marc Knaup

    3 years ago
    I can only judge from the Kotlin decompiler in IntelliJ that a lot of wrapping and one array allocation would occur. I don’t know whether that will actually disappear at runtime.
    marcinmoskala

    marcinmoskala

    2 years ago
    @Marc Knaup here is a simple and multiplatform implementation. Still thinking about the name though 🤔 @jw What do you think?
    override fun hashCode(): Int =
        hashCodeFrom(timeZone, millis)
    
    inline fun hashCodeFrom(vararg values: Any?) =
        values.fold(0) { acc, value ->
            (acc * 31) + value.hashCode()
        }