# "DataType" for only initial null value

**URL:** <https://discuss.kotlinlang.org/t/datatype-for-only-initial-null-value/26492>\
**Category:** Language Design\
**Created:** [March 7, 2023, 9:09pm UTC](https://discuss.kotlinlang.org/t/datatype-for-only-initial-null-value/26492 "2023-03-07T21:09:58Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![gunnarb](https://avatars.discourse-cdn.com/v4/letter/g/a3d4f5/32.png) [@gunnarb](https://discuss.kotlinlang.org/u/gunnarb)\
**Post date:** [March 7, 2023, 9:09pm UTC](https://discuss.kotlinlang.org/t/datatype-for-only-initial-null-value/26492/1 "2023-03-07T21:09:58Z")

</div>

For various reasons I work with classes which contain variables for objects which only can be null if not initialized.  
I would like this as an option to declare.

```auto
class Hull {

        var nodeHullOptions: List<HullOption>? = null
        private set

}

```

I would suggest a third option: Do not allow to assign null again, maybe mark it with an additional exclamation mark:

```auto
class Hull {

        var nodeHullOptions: List<HullOption>?! = null
        private set

}

```

The compiler can then do all the same checks it would do if there was no ‘?’, for all assignments, whereas read operations would allow null value.

There is one area of interest for me:

```auto
val isBig = nodeHullOptions != null && nodeHullOptions.size > 100

```

Error: Smart cast to ‘List’ is impossible, because ‘nodeHullOptions’ is a mutable property that could have been changed by this time

I could use !! or a construct with ?.let {}, but not allowing null in further assignments could also reduce one more error constellation.

‘lateinit’ also does not work, because in some cases it never gets a value.

So, what do you think?

---

<div class="post-metadata">

**Author:** ![broot](https://avatars.discourse-cdn.com/v4/letter/b/a88e57/32.png) [@broot](https://discuss.kotlinlang.org/u/broot)\
**Post date:** [March 7, 2023, 9:32pm UTC](https://discuss.kotlinlang.org/t/datatype-for-only-initial-null-value/26492/2 "2023-03-07T21:32:47Z")

</div>

> [@gunnarb](#):
>
> ‘lateinit’ also does not work, because in some cases it never gets a value.

What do you mean here? I think `lateinit` is exactly for the case you described.

---

<div class="post-metadata">

**Author:** ![gunnarb](https://avatars.discourse-cdn.com/v4/letter/g/a3d4f5/32.png) [@gunnarb](https://discuss.kotlinlang.org/u/gunnarb)\
**Post date:** [March 8, 2023, 8:45am UTC](https://discuss.kotlinlang.org/t/datatype-for-only-initial-null-value/26492/3 "2023-03-08T08:45:47Z")

</div>

@broot No, it is not. It is by design that in some cases these variables will never be initialized.

Think of a tree where you store the var parent and the var list of childs. The top-node will never have a parent and thus never be initialized. This is checked by parent == null. The bottom nodes do not have childs, as such also always null.

The usecase for lateinit is just a split second after object initialization, e.g. for JavaFx variables or in Android where during runtime you expect the variables to be initialized, but not as a design feature.

---

<div class="post-metadata">

**Author:** ![christofferberg79](https://avatars.discourse-cdn.com/v4/letter/c/c0e974/32.png) [@christofferberg79](https://discuss.kotlinlang.org/u/christofferberg79)\
**Post date:** [March 8, 2023, 6:21pm UTC](https://discuss.kotlinlang.org/t/datatype-for-only-initial-null-value/26492/4 "2023-03-08T18:21:28Z")

</div>

> [@gunnarb](#):
>
> The usecase for lateinit is just a split second after object initialization

lateinit only cares about that you don’t access the property before it has been initialized. It doesn’t matter if it’s a split second or five a minute.

Maybe you can use lateinit together with [.isInitialized](https://kotlinlang.org/docs/properties.html#checking-whether-a-lateinit-var-is-initialized) for your use case?

---

<div class="post-metadata">

**Author:** ![broot](https://avatars.discourse-cdn.com/v4/letter/b/a88e57/32.png) [@broot](https://discuss.kotlinlang.org/u/broot)\
**Post date:** [March 8, 2023, 6:57pm UTC](https://discuss.kotlinlang.org/t/datatype-for-only-initial-null-value/26492/5 "2023-03-08T18:57:40Z")

</div>

Ok, now I understand your case. I think there are really two separate features involved here.

First is a possibility to have a getter and a setter with different types. I think this could be pretty useful, I remember some discussions here about such feature, but I don’t know if there are any plan for it.

Second feature is that the compiler understands the property could only change from A type to B type and can make guarantees needed for smart-casting. This is more complicated than it sounds, because we need to remember properties are not fields, they can have custom behavior, they can be overridden in subtypes, etc. However, Kotlin compiler already does this e.g. for `val` properties - we can smart cast only if there is no custom getters and property is not open. So your case should be doable.

One note: I don’t think it should be limited to nulls. We can generalize this case to setter using a subtype of the getter.

---

<div class="post-metadata">

**Author:** ![arocnies](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/arocnies/32/5143_2.png) [@arocnies](https://discuss.kotlinlang.org/u/arocnies)\
**Post date:** [March 8, 2023, 7:34pm UTC](https://discuss.kotlinlang.org/t/datatype-for-only-initial-null-value/26492/6 "2023-03-08T19:34:31Z")

</div>

Have you look at delegated properties? For example, Lazy, NotNull, etc.

---

<div class="post-metadata">

**Author:** ![broot](https://avatars.discourse-cdn.com/v4/letter/b/a88e57/32.png) [@broot](https://discuss.kotlinlang.org/u/broot)\
**Post date:** [March 8, 2023, 9:51pm UTC](https://discuss.kotlinlang.org/t/datatype-for-only-initial-null-value/26492/7 "2023-03-08T21:51:59Z")

</div>

Delegated properties can help with runtime checks, but OP basically needs a setter for `List` and getter for `List?`. Ideally, with smart cast improvements. I believe for now the best we can get are two functions instead of a property.
