# Kotlin null check for multiple nullable var's

**URL:** <https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946>\
**Category:** Language Design\
**Created:** [September 1, 2016, 5:35am UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946 "2016-09-01T05:35:43Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![stupacki](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/stupacki/32/3128_2.png) [@stupacki](https://discuss.kotlinlang.org/u/stupacki)\
**Post date:** [July 14, 2017, 1:18pm UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/21 "2017-07-14T13:18:38Z")

</div>

Hey there,

i’ve run in this problem as well.  
Before I wrote Stuff in Kotlin I used Scala and Clojure to get things done, both of them have a more elegant way to deal with multiple NonNull Values for Collection Operations and Lets, then Kotlin has out of the box. So I decided to use the power of ExtensionFunctions and wrote my own Library to make it more elegant and readable.

You can find the library on Github: [GitHub - stupacki/MultiFunctions](https://github.com/stupacki/MultiFunctions)

The project is still in progress and I need to add a discription to use it but here a litte example to fix your problem.

```kotlin
import io.multifunctions.letNotNull

Quad(userApi.get(userId),
     ordersApi.get(userId),
     favoritesApi.get(userId),
     notesApi.get(userId))
    .letNotNull { user, orders, favorites, notes ->
    
         HttpResult.renderPage(user = user,
                               order = orders,
                               favorites = favorites,
                               notes = notes)

    }

```

In this example the lambda returns null in case one of the accessed apis return a null object, the let will return a null as well.

Currently the lib is able to handle 6 parallel objects/collections with the following functions:

- let
- letNotNull
- map
- mapNotNull
- forEach
- forEachNotNull
- mapIndexed
- mapIndexedNotNull
- withIndex

I hope this will help you with this problem

---

<div class="post-metadata">

**Author:** ![nic.lyth](https://avatars.discourse-cdn.com/v4/letter/n/df788c/32.png) [@nic.lyth](https://discuss.kotlinlang.org/u/nic.lyth)\
**Post date:** [July 18, 2017, 1:28am UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/22 "2017-07-18T01:28:06Z")

</div>

Despite possible performance impacts, local vals is the best solution. If the variable is mutable and accessible to outer scopes then the only way to guarantee that it hasn’t changed is making a local copy. Even null checking using `?.let {}` for single variables does this:

```
fun test() {
    name?.let { doSomething(it) }
}

```

compiles to the equivalent java code:

```
public final void test() {
    String var10000 = this.name;
    if(this.name != null) {
        String var1 = var10000;
        this.doSomething(var1);
    }
}

```

(Note: the kotlin compiler does optimise this when it can be sure that the variable won’t change. If name was a local var instead of a property, the compiler wouldn’t make an additional local variable

Swift has a similar problem with null checking multiple vars and solves this by making it easy to declare local values within if statements:

```
// Swift code 
if let name = name, let age = age {
    doSth(name, age)
}

```

A similar syntax in Kotlin could be the following:

```
if (val name = name, val age = age) {
    doSth(name, age)
}

```

Which would compile to the equivalent java code:

```
final String name = this.name;
if (name != null) {
    final Integer age = this.age;
    if (age != null) {
        doSomething(name, age);
    }
}

```

The usage of the comma instead of `&&` is to differentiate it from normal if statements in that everything should evaluate to non-null, the `||` operator is not allowed and do not make sense:

```
if (val name = name || val age == age) { /* Defeats the point of null checking */ }

```

Like with the `?.let{}` case, it would be possible for the compiler to optimise the creation of the local variables, only creating them if required. Also like the **`it`** in the `?.let{}` block, any values declared in the scope of the of the if statement and it’s following block would be immutable.

The syntax could be generalised as follows:

```
if (val var1 = <expression1> ,val var2 = <expression2>, val varN = <expressionN>) {
    // Do something with var1, var2, varN
}

```

Where `<expressionX>` is any expression that returns a nullable type

Which compiles to the equivalent java code:

```
final Type1 var1 = <expression1>;
if (var1 != null) {
    final Type2 var2 = <expression2>;
    if (var2 != null) {
        final TypeN varN = <expressionN>;
        if (varN != null) {
            // Do something with var1, var2, varN
        }
    }
}

```

It may seem a bit much, but it is almost identical to how multiple consecutive safe null calls are compiled. e.g: `foo?.bar?.baz`

The benefit however is that is that you can use earlier values in later expressions. In the example below p1 and p2 have already been null checked so we can access their age property directly.

```
fun whoIsOldest(person1: Person?, person2: Person?) {
    if (val p1 = person1, val p2 = person2, val age1 = p1.age, age2 = p2.age) {
        when {
            age1 > age2 -> print("$p1 is oldest")
            age1 < age2 -> print("$p2 is oldest")
            else -> print("$p1 and $p1 are the same age")
        }
    } else {
        print("Your need two people to compare ages")
    }
}

```

And because the expressions can be anything that returns a nullable type it can also be used with safe casts:

```
if (val child = person as? Child, val car = child.favouriteToy as? Car) {
    car.race()
    print("$child is racing their toy $car")
}

```

A additional improvement that could be made which is also available in swift is allowing boolean expressions alongside the nullable expressions. It’s a fairly common use case to check if something is non-null and then perform an additional check to see if it is appropriate to use.

```
if (val childAge = person.child?.age, childAge >= 6 && childAge < 18) {
    print("$person has to drop their child at school each weekday")
}

```

Here the use of the comma instead of `&&` reinforces the requirement that every expression needs to evaluate to non-null and true, no `||` operators are allowed.

---

<div class="post-metadata">

**Author:** ![Wavesonics](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wavesonics/32/2749_2.png) [@Wavesonics](https://discuss.kotlinlang.org/u/Wavesonics)\
**Post date:** [July 18, 2017, 6:13pm UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/23 "2017-07-18T18:13:39Z")

</div>

Minor performance issues aside, this seems like an ideal solution.

Especially the extra step of being able to have boolean expressions as this covers a huge number of use cases I’ve seen.

Yes you COULD declare these vars your self, but then they (probably?) couldn’t be optimized away. And it feels pretty boilerplatey, which is antithetical to Kotlin it seems.

So **tl;dr** +1 from me. would **_LOVE_** to see this implemented in the language 🙂

---

<div class="post-metadata">

**Author:** ![jstuyts](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/jstuyts/32/2141_2.png) [@jstuyts](https://discuss.kotlinlang.org/u/jstuyts)\
**Post date:** [July 18, 2017, 6:30pm UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/24 "2017-07-18T18:30:32Z")

</div>

> [@nic.lyth](#):
>
> Here the use of the comma instead of && reinforces the requirement that every expression needs to evaluate to non-null and true, […]

Which means that the semantics of Kotlin change in these ways:

- `val childAge = person?.child?.age` results in type `Int?` in normal declarations, but in type `Int` in `if` statements.
- Not `null` is equal to `false`, which introduces C syntax that allows multiple types in conditionals.

Not that I think these are blocking issues, but the inconsistencies are something to consider.

---

<div class="post-metadata">

**Author:** ![nic.lyth](https://avatars.discourse-cdn.com/v4/letter/n/df788c/32.png) [@nic.lyth](https://discuss.kotlinlang.org/u/nic.lyth)\
**Post date:** [July 18, 2017, 10:50pm UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/25 "2017-07-18T22:50:22Z")

</div>

> [@jstuyts](#):
>
> - Not `null` is equal to `false`, which introduces C syntax that allows multiple types in conditionals.

To clarify I’m not advocating that C style implicit boolean conversions should be added. `null` should not be treated as `false` in other circumstances: `if (person?.name) {...}` shouldn’t be possible.  
Rather I’d think of it as `not-being-able-to-assign-nullable-to-non-null` equals `false`

---

<div class="post-metadata">

**Author:** ![jstuyts](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/jstuyts/32/2141_2.png) [@jstuyts](https://discuss.kotlinlang.org/u/jstuyts)\
**Post date:** [July 19, 2017, 4:05am UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/26 "2017-07-19T04:05:11Z")

</div>

> [@nic.lyth](#):
>
> null should not be treated as false in other circumstances: if (person?.name) {…} shouldn’t be possible.

This again makes the language more inconsistent: Some constructs only work in a limited number of situations, and not in other similar situations. I can, for example, imagine people trying to use this in a `while`-statement. The (justified) expectation is that if you can use something in situation A, you can also use it in similar situation B. So if people see the expression in the `if` statement above, it is reasonable to expect them to be able to do this:

```
 val hasToBeDroppedOffAtSchoolOnWeekdays = val childAge = person?.child?.age, childAge >= 6 && childAge < 18

```

---

<div class="post-metadata">

**Author:** ![Wavesonics](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wavesonics/32/2749_2.png) [@Wavesonics](https://discuss.kotlinlang.org/u/Wavesonics)\
**Post date:** [July 19, 2017, 5:26pm UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/27 "2017-07-19T17:26:25Z")

</div>

We could have a new control structure instead of if().

guard() or something, so it’s clear this is a special case. Much like the for loop’s syntax is somewhat strange and wouldn’t work inside an if()

---

<div class="post-metadata">

**Author:** ![nic.lyth](https://avatars.discourse-cdn.com/v4/letter/n/df788c/32.png) [@nic.lyth](https://discuss.kotlinlang.org/u/nic.lyth)\
**Post date:** [July 21, 2017, 10:46am UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/28 "2017-07-21T10:46:27Z")

</div>

> [@jstuyts](#):
>
> This again makes the language more inconsistent: Some constructs only work in a limited number of situations, and not in other similar situations. I can, for example, imagine people trying to use this in a while-statement.

I don’t see any problem with also allowing while statements to use this syntax, as it’s just another type of conditional flow control. (swift also allows it’s version of this syntax in this situation)

```
val ride = RollerCoaster()
while (val person = personQueue.getNextPerson(), person.height > MIN_HEIGHT) {
	print("$person is riding the roller coaster")
	ride.add(person)
}
ride.start()

```

The equivalent java code would be a bit more complicated though compared to the if version.

* * *

> [@jstuyts](#):
>
> The (justified) expectation is that if you can use something in situation A, you can also use it in similar situation B. So if people see the expression in the if statement above, it is reasonable to expect them to be able to do this:
> 
> ```
> val hasToBeDroppedOffAtSchoolOnWeekdays = val childAge = person?.child?.age, childAge &gt;= 6 && childAge &lt; 18
> 
> ```

There are already Kotlin syntax rules which would indicate that statement wouldn’t be possible. The statement above is pretty similar to following, which won’t compile:

```
val bar = val foo = "baz" // compiler error

```

Also assigning `T?` to a `T` always requires some kind of extra context for it to work, either by explicitly null checking and relying on the smart cast or using an elvis operator to provide a fallback value. The proposed syntax is just another way to add context to let the assignment work

* * *

> [@jstuyts](#):
>
> Which means that the semantics of Kotlin change in these ways:
> 
> val childAge = person?.child?.age results in type Int? in normal declarations, but in type Int in if statements.

I don’t see it as inconsistent, it’s just the type inference working as it should. Without it, the if statements would be written as follows look like follows:

```
if (val age: Int = person.age) { ... }

```

Where it works just like smart casting or the elvis operator, extra context is provided to ensure that age will not be null and type inference can eleminate the need to explicitly specify the non null type.

I’d even argue that this syntax is even easier to understand and more consistent than smart casts.

- Its easier to understand because it forces the assignment to be next to the control structure making it easy to see why the assignment is possible. With smart casts there could be 100’s if lines of code between the null check that makes it possible and the actual cast. There’s also two cases where smart casts can occur:

- It’s more consistent because to works regardless of where it is. One of the problems showed in the example by the OP was a smart cast not working despite performing a null check. Take for example:

---

<div class="post-metadata">

**Author:** ![Wavesonics](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wavesonics/32/2749_2.png) [@Wavesonics](https://discuss.kotlinlang.org/u/Wavesonics)\
**Post date:** [July 21, 2017, 5:52pm UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/29 "2017-07-21T17:52:47Z")

</div>

_Maybe_ the inconsistency could cause a problem for a small fraction of people for a moment before they learn why.

But the multiple null check issue will effect every single Kotlin user. So even if the inconsistency is an issue (_which I don’t think it is, especially if you create a new keyword that it is only valid inside of_) this is still a much greater good,

---

<div class="post-metadata">

**Author:** ![antonin.brettsnajdr](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/antonin.brettsnajdr/32/4531_2.png) [@antonin.brettsnajdr](https://discuss.kotlinlang.org/u/antonin.brettsnajdr)\
**Post date:** [September 23, 2017, 3:10pm UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/30 "2017-09-23T15:10:51Z")

</div>

What about:

```
    fun notNull(vararg args: Any?, action: () -> Unit) {
        when {
            args.filterNotNull().size == args.size -> action()
        }
    }

    val a = 1
    val b = "something"
    var c: Float? = 2f

    notNull(a, b, c) {
        println("Almost safe!")
    }

    c = null

    notNull(a, b, c) {
        println("Doesn't print ...")
    }

```

---

<div class="post-metadata">

**Author:** ![mslenc](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mslenc/32/3861_2.png) [@mslenc](https://discuss.kotlinlang.org/u/mslenc)\
**Post date:** [September 23, 2017, 4:53pm UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/31 "2017-09-23T16:53:28Z")

</div>

Shameless plug:  
[https://youtrack.jetbrains.com/issue/KT-20294](https://youtrack.jetbrains.com/issue/KT-20294)

TL;DR: the error is not actually preventing any bugs, yet is a major nuisance; it should just become a (suppressable) warning instead. Please voice your support for this change!

---

<div class="post-metadata">

**Author:** ![youhansr](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/youhansr/32/4052_2.png) [@youhansr](https://discuss.kotlinlang.org/u/youhansr)\
**Post date:** [October 16, 2017, 5:23am UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/32 "2017-10-16T05:23:31Z")

</div>

Can’t we have an extended elvis operator like below? :

```auto
val result = operationX(a?, b?, c?) ?: getDefaultValue()

```

Which would be the short syntax for:

```auto
val result = if (a != null && b != null && c !=null && operationX(a, b, c) != null) 
                operationX(a, b, c) 
             else 
                getDefaultValue()

```

This is the syntax which Advanced Java Folding plugin (from Jetbrains itself) is using to fold ternary operators in Java codes. This plugin will fold this:

```auto
return fixedPayment!=null? service.trs(p -> p.saveOrUpdate(fixedPayment)).map(Res::result) : null;

```

to this:

```auto
return service.trs(p -> p.saveOrUpdate(fixedPayment?)).map(Res::result) ?: null;

```

---

<div class="post-metadata">

**Author:** ![vbezhenar](https://avatars.discourse-cdn.com/v4/letter/v/35a633/32.png) [@vbezhenar](https://discuss.kotlinlang.org/u/vbezhenar)\
**Post date:** [October 16, 2017, 7:23am UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/33 "2017-10-16T07:23:32Z")

</div>

There’s some heated discussion there, I don’t want to bloat bugtracker with flames, but I’m very against this kind of change. Null-safety and smart casts are awesome in Kotlin and it makes me much more productive. I understand where this problem comes from, I even wrote something about it myself, but I don’t think that there’s any sane way to make it much better than now.

1. Sacrificing null-safety or type-safety is just not an option at all. I love that Kotlin’s guarantees are hard to break and almost impossible with normal code.
2. Changing, whether one function compiles, analyzing another function bodies is just bad. I’m sure that it’s bad from compiler performance perspective, but first of all it’s bad from cognitive load. I’m changing implementation of one function and suddenly 10 other functions do not compile. That’s very fragile construction.

With that said, I think that there still could be a way to improve this situation.

1. Explicit construction to use temporary local variable as a property alias. Now one could modify this variable and use it as a local variable, but changes will propagate to property (but not other way), so external modifications won’t be visible.

2. If property is not open and it’s trivial (without explicit getter/setter), compiler could treat this property as a local variable until some function call occurs. Of course there’s still danger of multithreading modifications, but I think that if access to a variable is not guarded by proper synchronizations, it’s a bug anyway. And any synchronization results to some function call, which will disable smart casting.

---

<div class="post-metadata">

**Author:** ![Wavesonics](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wavesonics/32/2749_2.png) [@Wavesonics](https://discuss.kotlinlang.org/u/Wavesonics)\
**Post date:** [November 22, 2017, 8:31pm UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/34 "2017-11-22T20:31:05Z")

</div>

I’ve just discovered the cross-module smart cast limitation.

It’s very common to have your data contracts in another module, which means this issue is an even bigger problem.

Currently the only solution I see is creating tons of temporaries, which seems so counter to Kotlin’s philosophy of no boilerplate.

---

<div class="post-metadata">

**Author:** ![mrtact](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mrtact/32/4751_2.png) [@mrtact](https://discuss.kotlinlang.org/u/mrtact)\
**Post date:** [December 1, 2017, 10:50pm UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/36 "2017-12-01T22:50:57Z")

</div>

Call me crazy, but I don’t find a dumb cast especially onerous here:

```auto
class Person(var name:String? = null, var age:Int? = null){
    fun test(){
        if (listOf(name, age).all { it != null }) {
            doSth(name!!, age!!)
        }
    }

    fun doSth (someValue:String, someValue2:Int){

    }
}
```

---

<div class="post-metadata">

**Author:** ![ice1000](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ice1000/32/1981_2.png) [@ice1000](https://discuss.kotlinlang.org/u/ice1000)\
**Post date:** [December 7, 2017, 8:46am UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/37 "2017-12-07T08:46:01Z")

</div>

What about this?

```kotlin
class A(var a: A? = null, var b: A? = null) {
  fun test() {
    val (a, b) = a to b
    if (a != null && b != null) { ~ }
  }
}

```

---

<div class="post-metadata">

**Author:** ![pootow](https://avatars.discourse-cdn.com/v4/letter/p/8e7dd6/32.png) [@pootow](https://discuss.kotlinlang.org/u/pootow)\
**Post date:** [December 20, 2017, 10:33am UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/38 "2017-12-20T10:33:30Z")

</div>

the more I use kotlin, the more I miss groovy truth.

what about this:

```
class Person(var name:String? = null, var age:Int? = null){
    fun test(){
        if(name != null && age != null)
            doSth?(name, age) //no need to cast
    }

    fun doSth (someValue:String, someValue2:Int){

    }
}

```

doSth?(…) is consistent and concise.

---

<div class="post-metadata">

**Author:** ![ashvinsolanki](https://avatars.discourse-cdn.com/v4/letter/a/96bed5/32.png) [@ashvinsolanki](https://discuss.kotlinlang.org/u/ashvinsolanki)\
**Post date:** [January 5, 2019, 5:28pm UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/40 "2019-01-05T17:28:29Z")

</div>

For Checking One More var

````
```
fun <T> notNull(vararg elements: T): Boolean {
    elements.forEach {
        if (it == null) {
            return false
        }
    }
    return true
}
```

````

> Example

```
if(notNull(name,age))
{
//do work......
}

```

For More [java - Kotlin: Convert variables to non nullable if condition is true - Stack Overflow](https://stackoverflow.com/questions/54054290/kotlin-convert-variables-to-non-nullable-if-condition-is-true)

---

<div class="post-metadata">

**Author:** ![NogbadTheBad](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/nogbadthebad/32/5945_2.png) [@NogbadTheBad](https://discuss.kotlinlang.org/u/NogbadTheBad)\
**Post date:** [January 6, 2019, 5:13pm UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/41 "2019-01-06T17:13:51Z")

</div>

What’s wrong with `val anyNull = listOf(foo, bar).any { it != null }`  
`

---

<div class="post-metadata">

**Author:** ![Wasabi375](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wasabi375/32/4741_2.png) [@Wasabi375](https://discuss.kotlinlang.org/u/Wasabi375)\
**Post date:** [January 6, 2019, 5:26pm UTC](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946/42 "2019-01-06T17:26:46Z")

</div>

The problem is that neither `foo` nor `bar` will be smart cast.

```kotlin
if(listOf(foo, bar).all { it != null }) { 
    foo.foo() // error, foo might be null
    bar.bar() // error, bar might be null
}

```

[Previous page](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946.md?page=1)

[Next page](https://discuss.kotlinlang.org/t/kotlin-null-check-for-multiple-nullable-vars/1946.md?page=3)
