I often thought why kotlin doesn't support 'latein...
# announcements
h
I often thought why kotlin doesn't support 'lateinit val', as you know kotlin just has supported 'lateinit var'. My colleague sometime overwrite that variable what I defined. Is there whom can answer for that?
m
As a thought experiment, where can you initialize such a lateinit val? Do you allow only a single assignment to it in the whole program? If yes, how do you plan to check that at compile time?
As for your colleague, it's hard to give advise without seeing the code; depending on why and where he overwrites this property, we could have different ways of mitigating that.
h
for example, our class has initialize method like onCreate of Android (not constructor or init of kotlin). And I want to set that value just on initialize method however it is var, it could be overwritten anytime by other method.
l
@Harry You can make a delegate that calls
error("…")
if the value is already initialized.
h
@louiscad Thanks for your advice. If kotlin supports 'lateinit val' from language level, it could be solved easily without any more source code. I just wonder why it isn't supported on kotlin.
l
I think it's because Kotlin wants to discourage such use as
lateinit val
could easily be more abused and cripple codebases. I had a few times where I would have used a
lateinit val
too, but many times where I had to think about it because I couldn't and I didn't want it to become a
var
, I ended up with better solutions, including using
lazy
and coroutines.
b
I think there's already a singleAssign delegate just for that. It throws an error on subsequent assign attempts
l
@Big Chungus Not in
Delegates
nor in the stdlib AFAIK.
b
My bad, it was in tornadofx. Nothing stops you from writing your own, though.
h
@louiscad
Copy code
I think it's because Kotlin wants to discourage such use as lateinit val could easily be more abused and cripple codebases.
Could you let me know any example for that cases?
l
@Harry I don't have specific examples to point to. I can only tell you that a
lateinit val
would still be like a
var
in the sense that it makes the code harder to reason about as things can change from outside/under and initialization can become undeterministic when looking at the code only.
b
In all fairness, I personally prefer
var: Any?
Over
lateinit var: Any
anytime
🚫 1
3
This ensures you handle unitialused scenarios in all places
h
@louiscad I partially agree with you. However, many Android developer (only me?) would want to set a variable of class just one time at onCreate method and they wish that this variable would not be changed anymore. but a variable of 'lateinit var' could be changed later.
l
@Harry I just put my code in another file/class/function amd run all my logic here instead of having it all in the entry point (
Activity
or whatever). And thanks to that, I never need
lateinit var
in my code.
1
n
Yeah, tend to agree with Louis above
IMHO lateinit itself is actually a hack. It's a useful hack in some situations where you don't want to refactor
But basically lateinit suggests you ought to have two separate types
And then you are back to really using the type system, which lateinit dodges
h
@louiscad that's nice approch and I love that. however to do that, developer have to make a new file.
@Nir If that is a official position of Jetbrain, I will not use the 'lateinit var'.
l
@Harry You can also put it in the same file outside of the
Activity
/whatever class. But I don't see how it's an issue to create a new file unless you struggle to find a better name than `WhateverActivity`/`WhateverWhatever`
@Harry You don't need an official position to make your code better.
n
I don't claim to represent jetbrains official position. If they added it I'm sure it has usage. It is more lines of code, etc, to make what we're suggesting work
But usually I'd prefer to create that separate class. It's not really that much work. Especially with delegation
And the number of times I need lateinit to start is low
h
@louiscad, @Nir I'm really happy to discuss with you. If there is 'lateinit val', we don't need to make more source code even if it is a new file or new class, isn't it? It is main point of my question.
l
Sometimes, having a little more source code is better than shaving it off until it bleeds or is close to.
Everything needs to target a healthy balance. Works in code, and many things in projects and life 🙂
h
I'm just wondering why this isn't technically supported. Almost technological advancements start with curiosity.
e
lateinit
is problematic because it's stateful and the compiler cannot track the variable initialization. It's only necessary for dependency injection where constructor injection is not supported. All other cases could be solved with constructor injection or, as Martynas said, using
var
with a nullable type. This allows the compiler to identify all uninitialized cases.
n
I don't understand what lateinit val really buys you
In fact, even lateinit buys you very little over having a nullable type
It's just saving you typing !!
@Harry you need to think about things more from the compilers perspective. The whole point of lateinit is that the compiler cannot verify that the variable is initialized on all code paths before it is accessed on all code paths
Understanding thing might require knowledge of the whole program, which would be computationally infeasible, or even things like the expected program inputs, which would be impossible
Kotlin is also very very far from trying to have the most powerful type system around, so Kotlin isn't even trying to push the envelope here
h
Today I thought of this problem, and I understand why Kotlin doesn't support
lateinit val
. Thanks for your answers, it is helpful to me.
👌 1