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 PMListNir
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 ImmutableListNir
09/18/2020, 4:57 PMMutableList does implement ListBig 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