I ran the following code in both kotlinc and ki (github)
data class Person(val name: String, val roles: List<String>)
val m = Person("bob", mutableListOf("developer"))
m.roles.addFirst("a")
In kotlinc, I got an error message:
> kotlinc -script Immutable.kts
Immutable.kts:4:9: error: unresolved reference 'addFirst'.
m.roles.addFirst("a")
^
However, ki allowed me to modify the mutable list roles:
> ki
ki-shell 0.5.2/1.7.0
type :h for help
[0] data class Person(val name: String, val roles: List<String>)
[1] val m = Person("bob", mutableListOf("developer"))
[2] m.roles.addFirst("a")
[3] m.roles
res3: List<String> = [a, developer]
So, why the code returns two different outcomes depending on how it was executed?
I got confused by the use of listOf() and mutableListOf(). I understand that listOf() creates an immutable list (addFirst() is not available, so we cannot change the list), whereas mutableListOf() returns a mutable list (addFirst() is available, so we can change the list). However, that behavior does not apply when using data classes in kotlinc, is that correct? Such a difference is expected when using ki?
I am using these versions:
$ kotlinc -version
info: kotlinc-jvm 2.0.0 (JRE 22+36-2370)
$ javac -version
javac 22
$ ki --version
ki-shell 0.5.2/1.7.0
I got this answer from StackOverflow:
This isn’t about data classes as such — just about declared types. In both versions of your code, you’re creating a
MutableList, but storing it in aListproperty.MutableListis a subtype ofList, so it’s OK to store it there — that’s an upcast. From then on, the compiled code knows only that it’s aList. (After all, you could easily write some other code which stored an immutable list in that property.) However, Ki can do something that a compiler can’t: it can check the actual type at runtime.And here, it seems to see that although the reference is of a
Listtype, at this point in the run the object it’s actually referring to is aMutableList, and so it’s OK to treat it as mutable. — Now, whether a REPL should be doing this is another question… (I don’t know Ki; it’s possible that this is unintended behaviour!)
Is that answer correct? If so, is it OK for kotlinc and ki to treat mutable lists differently?