# Different null check behavior in assignment vs expression

**URL:** <https://discuss.kotlinlang.org/t/different-null-check-behavior-in-assignment-vs-expression/22008>\
**Category:** Language Design\
**Created:** [June 3, 2021, 5:06pm UTC](https://discuss.kotlinlang.org/t/different-null-check-behavior-in-assignment-vs-expression/22008 "2021-06-03T17:06:41Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![poralexc](https://avatars.discourse-cdn.com/v4/letter/p/edb3f5/32.png) [@poralexc](https://discuss.kotlinlang.org/u/poralexc)\
**Post date:** [June 3, 2021, 5:06pm UTC](https://discuss.kotlinlang.org/t/different-null-check-behavior-in-assignment-vs-expression/22008/1 "2021-06-03T17:06:42Z")

</div>

Hello! Recently I was having a discussion [here](https://www.reddit.com/r/Kotlin/comments/nqjjsb/do_you_check_for_null/h0ezw8d/?context=3) about null coalescing operators used on a nullable property, and it brought up some strange behavior with regards to assignments/declarations.

(Note: I’ve never had an issue with this in my own code, just an interesting case.)

if I set up everything like this, with the goal of using primary.id or else alt.id or else null:

```kotlin
class Test(val id: String? = null)
var primary: Test? = null 
primary = Test() 
var alt: Test? = null 
alt = Test("alternate")

```

This works as expected:

```kotlin
var id: String? = null
id = primary?.id ?: alt?.id 
println(id) // prints "alternate"

```

But if the id is set in the declaration no dice:

```kotlin
var id: String? = primary?.id ?: alt?.id
println(id) // always prints "null" (id property of primary)

```

Same deal with an if statement:

```auto
// Always null
var id: String? = if (primary?.id != null) primary!!.id else alt?.id 

// Works as intended
var id: String? = null
id = if (primary?.id != null) primary!!.id else alt?.id

```

The difference seems to be caused by whether something is an assignment or an expression, I’m curious about what is going on under the hood here.

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [June 3, 2021, 6:19pm UTC](https://discuss.kotlinlang.org/t/different-null-check-behavior-in-assignment-vs-expression/22008/2 "2021-06-03T18:19:35Z")

</div>

These all print “alternate” from what I can observe:

```run-kotlin
class Test(val id: String? = null)

fun main(){
    var primary: Test? = null 
	primary = Test() 
	var alt: Test? = null 
	alt = Test("alternate")
    var id1: String? = null
	id1 = primary?.id ?: alt?.id 
	println(id1)
    var id2: String? = primary?.id ?: alt?.id
	println(id2)
	var id3: String? = if (primary?.id != null) primary!!.id else alt?.id 
	println(id3)
	var id4: String? = null
	id4 = if (primary?.id != null) primary!!.id else alt?.id
    println(id4)
}

```

Do you maybe have an example that reproduces this bug?

---

<div class="post-metadata">

**Author:** ![poralexc](https://avatars.discourse-cdn.com/v4/letter/p/edb3f5/32.png) [@poralexc](https://discuss.kotlinlang.org/u/poralexc)\
**Post date:** [June 3, 2021, 7:08pm UTC](https://discuss.kotlinlang.org/t/different-null-check-behavior-in-assignment-vs-expression/22008/3 "2021-06-03T19:08:41Z")

</div>

Now that I run it in it’s own file with a proper main() function it works fine, and with nice smart casting as well so the safe calls aren’t needed. 🙂

When I was encountering the issue, I was running the examples above almost verbatim in a scratch file in intellij, so it might be a difference in context having to do with scripting vs running a project.

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [June 3, 2021, 10:08pm UTC](https://discuss.kotlinlang.org/t/different-null-check-behavior-in-assignment-vs-expression/22008/4 "2021-06-03T22:08:33Z")

</div>

scratch files usually have really really weird issues. I think maybe what happened here is that it defined all the variables with their initialisers first _and then_ ran the rest of the code, and so the initialiser was evaluating to the null values that you had in all the other variables
