Nir
09/18/2020, 3:34 PMmap
with your own that returns an ImmutableList instead of a List. How would you do it?allan.conda
09/18/2020, 3:48 PMJakub Pi
09/18/2020, 3:49 PMJakub Pi
09/18/2020, 3:50 PMCasey Brooks
09/18/2020, 3:52 PMList
is not immutable, it’s read-only. By casting it to MutableList
you might be able to modify it (definitely a sign of bad code, but still possible). Or the danger is in passing a Kotlin List
to Java, where it is not read-only.
But like others have said, the best route is definitely to make an extension function with this functionality (such as mapImmutable
). This makes it more clear the intent behind your code, and also doesn’t require any nasty hacks to make it workJakub Pi
09/18/2020, 3:59 PMNir
09/18/2020, 4:08 PMNir
09/18/2020, 4:08 PMNir
09/18/2020, 4:08 PMNir
09/18/2020, 4:09 PMNir
09/18/2020, 4:11 PMNir
09/18/2020, 4:11 PMNir
09/18/2020, 4:12 PMmap
, because the standard map
is a mistakeNir
09/18/2020, 4:16 PMimport prelude.*
in every fileNir
09/18/2020, 4:17 PMNir
09/18/2020, 4:18 PMmap
do the right thingNir
09/18/2020, 4:18 PMmap
should probably have returned an ImmutableList to begin withBig Chungus
09/18/2020, 4:27 PMmyStuff
) present in all the files (same as println
is) so that this "file" would compile
// note no imports
fun main() {
myStuff()
}
instead of having to do
import my.package.myStuff
fun main() {
myStuff()
}
Jakub Pi
09/18/2020, 4:28 PMBig Chungus
09/18/2020, 4:28 PMCasey Brooks
09/18/2020, 4:36 PM.map
in your project means something different than every other Kotlin project out there, and so is difficult to enforce the proper usage and is not good having to train team members on this fact. By using extension functions with a different name, it becomes clear what the expectation is (use .mapImmutable
instead of .map
), easy to detect in code reviews and lint, and follows Kotlin conventions and practices.Casey Brooks
09/18/2020, 4:40 PMList
should suffice to keep a list from being modified, and if you’re having issues with that list being modified, then you need to train your team members to not cast lists to MutableList
but use .toMutableList()
instead, or to always send a copy of the list into Java codeNir
09/18/2020, 4:46 PMNir
09/18/2020, 4:46 PMNir
09/18/2020, 4:47 PMList
Nir
09/18/2020, 4:47 PMList
that you specifically get from map
, yes, that's true, but you don't get the guarantee in the type system, so it's not good enough. Hence why I said, map
is mis-designedNir
09/18/2020, 4:48 PM.mapImmutable
approach, is that people coming onto the team will almost certain use .map
a lot, and if that' snot what you want, then now you have to catch map
usages everywhere which is much more workCasey Brooks
09/18/2020, 4:48 PMList
interface has no methods that allow it to be modified, so you must be doing something dangerous to that object which allows it to be modified (reflection, casting to MutableList
, sending it to unsafe Java code, etc). List
by itself doesn’t need to be fully immutable to be safe, assuming you are using it safelyNir
09/18/2020, 4:49 PMNir
09/18/2020, 4:49 PMBig Chungus
09/18/2020, 4:49 PMdata class ImmutablePretender(val list:List<Any>);
fun main() {
val trickster = mutableListOf<Any>();
val pretender = ImmutablePretender(trickster);
println(pretender.list.size) // 0
trickster.add(1);
println(pretender.list.size) // 1
}
Nir
09/18/2020, 4:49 PMNir
09/18/2020, 4:50 PMCasey Brooks
09/18/2020, 4:50 PMList
implied a list that cannot be changed or mutated. But it is just an interface, any real guarantees of a truly immutable List must be an implementation detail. What more could you add to a the List interface to make sure the implementation is safe?Nir
09/18/2020, 4:51 PMBig Chungus
09/18/2020, 4:51 PMset
methodsBig Chungus
09/18/2020, 4:52 PMNir
09/18/2020, 4:52 PMList
interface incorrectly, as well, so that things like get
actually perform mutationsNir
09/18/2020, 4:52 PMCasey Brooks
09/18/2020, 4:52 PMImmutableList
interface can do that would prevent the ImmutablePretender
problem above. The only thing that could is if ImmutableList
is a final class (that is, an implementation)Big Chungus
09/18/2020, 4:53 PMNir
09/18/2020, 4:53 PMNir
09/18/2020, 4:53 PMNir
09/18/2020, 4:53 PMCasey Brooks
09/18/2020, 4:54 PMlistOf()
with a single element on JVM returns Collections.singletonList
, which is immutableNir
09/18/2020, 4:54 PMBig Chungus
09/18/2020, 4:54 PMNir
09/18/2020, 4:54 PMNir
09/18/2020, 4:54 PMNir
09/18/2020, 4:54 PMBig Chungus
09/18/2020, 4:55 PMNir
09/18/2020, 4:55 PMBig Chungus
09/18/2020, 4:55 PMCasey Brooks
09/18/2020, 4:55 PMImmutableList
implementation that misuses that interface, how does it help any more than the normal List
interface?Nir
09/18/2020, 4:55 PMNir
09/18/2020, 4:56 PMNir
09/18/2020, 4:56 PMNir
09/18/2020, 4:56 PMNir
09/18/2020, 4:56 PMBig Chungus
09/18/2020, 4:56 PMNir
09/18/2020, 4:56 PMNir
09/18/2020, 4:56 PMMutableList
does not implement ImmutableList
Nir
09/18/2020, 4:57 PMMutableList
does implement List
Big Chungus
09/18/2020, 4:57 PMNir
09/18/2020, 4:57 PMNir
09/18/2020, 4:57 PMBig Chungus
09/18/2020, 4:57 PMNir
09/18/2020, 4:58 PMBig Chungus
09/18/2020, 4:58 PMNir
09/18/2020, 4:59 PMBig Chungus
09/18/2020, 4:59 PMNir
09/18/2020, 4:59 PMNir
09/18/2020, 4:59 PMNir
09/18/2020, 4:59 PMNir
09/18/2020, 5:00 PMNir
09/18/2020, 5:00 PMmap
, is because map
is a waste in that sense. map
creates a new list, with only one reference, which is read-only.Big Chungus
09/18/2020, 5:00 PMNir
09/18/2020, 5:00 PMmap
really is immutable shy of casting.Jakub Pi
09/18/2020, 5:00 PMNir
09/18/2020, 5:00 PMJakub Pi
09/18/2020, 5:01 PMNir
09/18/2020, 5:02 PMNir
09/18/2020, 5:02 PMJakub Pi
09/18/2020, 5:03 PMNir
09/18/2020, 5:04 PMNir
09/18/2020, 5:04 PMJakub Pi
09/18/2020, 5:04 PMNir
09/18/2020, 5:04 PMNir
09/18/2020, 5:04 PMNir
09/18/2020, 5:05 PMNir
09/18/2020, 5:05 PMJakub Pi
09/18/2020, 5:08 PMNir
09/18/2020, 5:11 PMNir
09/18/2020, 5:12 PMNir
09/18/2020, 5:14 PMmap
is peanuts compared to dealing with immutable data classes; need to use arrow lenses for that 🙂 Still very easy to learn, but more foreignJakub Pi
09/18/2020, 5:16 PMNir
09/18/2020, 5:17 PMNir
09/18/2020, 5:17 PMNir
09/18/2020, 5:18 PMJakub Pi
09/18/2020, 5:18 PMNir
09/18/2020, 5:18 PMNir
09/18/2020, 5:19 PMNir
09/18/2020, 5:20 PMJakub Pi
09/18/2020, 5:23 PMNir
09/18/2020, 5:24 PMNir
09/18/2020, 5:24 PMJakub Pi
09/18/2020, 5:24 PMNir
09/18/2020, 5:24 PMNir
09/18/2020, 5:25 PMNir
09/18/2020, 5:25 PMJakub Pi
09/18/2020, 5:26 PMJakub Pi
09/18/2020, 5:29 PMNir
09/18/2020, 5:38 PMNir
09/18/2020, 5:39 PMJakub Pi
09/18/2020, 5:54 PMJakub Pi
09/18/2020, 5:55 PMNir
09/18/2020, 6:05 PM