After writing several projects using Kotlin I still cannot understand why this design decision has been made. I mean disallowing smartcast for nullable variable properties.
I will try to explain why it is so bad.
- You need variable properties in your classes. This is true unless you are writing in pure functional language which is not our case.
- You need some of them to be nullable occasionally. One may say that you can use some kind of Optional for that. But this, firstly, is unnecessary overhead over just a nullable value which exists for the same reason. And the most important, secondly, does not have any principal difference with nullable type, and, if the compiler would be aware of it, it could say “Smart cast from
Tis not possible because it might be changed since isPresent() was called”.
- Every time you access your variable in your class, you are sure that you can do it safely here, either by ensuring it is done in one thread or under some kind of synchronisation. All the code in the world which uses variables and does not have race bugs there, is such. I understand that under this design decision probably was some idea about helping to prevent race bugs for variable access, but it does not work. The compiler actually cannot detect if there is a race, and that’s the reason why it always prohibits smart casting of variable properties. And while it does not help to prevent them, it really hurts making all such code full of !! (wedge-writing, brainfuck-style, name it as you like), making it ugly and less readable. Most probably another reason (and the only “useful” effect) is that !! ensures that in case the value is null, Kotlin nice NPE is thrown instead of not-invented-here vanilla Java NPE. That’s, honestly, is absolutely no point for me personally, but the same check still can be done under the hood on each access to smart-casted nullable variable, just remove !! from the code in this case.
What do you think, people? Am I alone with this pain?