https://kotlinlang.org logo
Title
l

lifter

08/25/2018, 7:04 PM
Can someone please explain why the second
println(f())
prints “Yes” instead of “No”?
fun main(args: Array<String>) {
    var (f, x) = g()
    println(f()) // Prints "yes"
    x = 1
    println(f()) // Prints "yes"
}

fun g(): Pair<() -> Char, Int> {
    var x = 0
    var f = fun(): Char { return if (x == 0) { println("yes"); 'Y' } else { println("no"); 'N' } }
    return f to x
}
d

Dominaezzz

08/25/2018, 7:11 PM
x is returned by value. So when you set x to 1. The x referenced by f doesn't change.
l

lifter

08/25/2018, 7:14 PM
Is it? I’m confused because this prints “true”:
fun main(args: Array<String>) {
    val x = 0
    val y = f(x)
    println(x === y)
}

fun f(x: Int): Int {
    return x
}
d

Dominaezzz

08/25/2018, 7:33 PM
===
is the same as
==
for "primitives".
l

lifter

08/25/2018, 7:34 PM
That’s interesting, I thought everything in Kotlin was an object and there were no primitives.
d

Dominaezzz

08/25/2018, 7:35 PM
Although it may return false for
Int?
instead of
Int
.
l

lifter

08/25/2018, 7:36 PM
So it sounds like it’s impossible to compare `Int`s for equality of reference? Even though they are objects?
d

Dominaezzz

08/25/2018, 7:36 PM
===
is the same as
==
for values that are represented as primitive types at runtime.
That's more accurate.
l

lifter

08/25/2018, 7:36 PM
Wow that’s a little unfortunate.
This prints “true”, leading me to think that for non-“primitive” types, a function will in fact return a reference.
import java.io.File

fun main(args: Array<String>) {
    val fileA = File("/etc")
    val fileB = f(fileA)
    println(fileA === fileB)
}

fun f(file: File): File {
    return file
}
Anyhow, I appreciate your help with this head-scratcher.
d

Dominaezzz

08/25/2018, 7:41 PM
No problem.
k

karelpeeters

08/25/2018, 7:47 PM
Everything is by-value-of reference, and there is nothing else in Java/Kotlin.
You can look at primitives as if they share "instances" for value-equal values.
🤔 1
l

lifter

08/25/2018, 7:58 PM
I think I get what you are saying @karelpeeters. Tho I have to admit this, to me, seems like an exception to the statement “Everything is by-value-of reference”:
fun main(args: Array<String>) {
    val x = 0
    val y = 0
    println(x === y) // Prints "true"
}
k

karelpeeters

08/25/2018, 8:00 PM
Right, pretend like primitives do interning like strings do. Replace
0
by
"hello"
and it probably still prints
true
.
l

lifter

08/25/2018, 8:17 PM
Yeah, it does
k

karelpeeters

08/25/2018, 8:25 PM
But that stuff only happens for primitives and strings, both immutable types, where the distinction between reference and value is less relevant.
s

SiebelsTim

08/26/2018, 8:28 AM
Either way, setting x in your very first example won't work, if its a primitive or object. You change the reference, so in the end x points to a different object.
☝️ 1
a

Andreas Sinz

08/26/2018, 9:35 AM
exactly, your
x = 1
assigns a new value to the local
x
, you aren't changing the old value