# Conditional assignment operator proposal

**URL:** <https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150>\
**Category:** Language Design\
**Created:** [June 14, 2018, 12:58pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150 "2018-06-14T12:58:30Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [September 18, 2018, 3:54pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/21 "2018-09-18T15:54:14Z")

</div>

Checking whether the left side is not null is quite a use case. It would allow program flows like the following:

```
var x: Foo
x ?= foo?.let{
  // complex expression 1
}
x ?= bar?.let{
  // complex expression 2
}
x ?= baz?.let{
  // complex expression 3
}

```

Doing that with Elvis would be a very complex expression.

In this case I would like if the variable can be declared as a val. It is effectively final, assigned only once and never re-assigned.

---

<div class="post-metadata">

**Author:** ![guai](https://avatars.discourse-cdn.com/v4/letter/g/7ba0ec/32.png) [@guai](https://discuss.kotlinlang.org/u/guai)\
**Post date:** [September 18, 2018, 4:25pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/22 "2018-09-18T16:25:21Z")

</div>

@fatjoe79, what if all of the assignments give `null`  
You’ ll need ensure not null via `x!!` at the end. Then yo kinda already have non-nullable type after this line via narrowing

This case looks kinda cool to me, but I’m not sure if having twin elvis assignments

```auto
a ?= b // for
if(a == null) a = b
//and
a =? b // for
if(b != null) a = b

```

would not make it too perl’ish

---

<div class="post-metadata">

**Author:** ![guai](https://avatars.discourse-cdn.com/v4/letter/g/7ba0ec/32.png) [@guai](https://discuss.kotlinlang.org/u/guai)\
**Post date:** [September 18, 2018, 4:28pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/23 "2018-09-18T16:28:27Z")

</div>

Or even third option to have both

```auto
a ?=? b // for
if(a == null && b != null) a = b

```

🙂

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [September 18, 2018, 4:33pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/24 "2018-09-18T16:33:01Z")

</div>

> [@guai](#):
>
> @fatjoe79, what if all of the assignments give `null`

It will need to look like this then:

```
var x: Foo
x ?= foo?.let{
  // complex expression 1
}
x ?= bar?.let{
  // complex expression 2
}
x ?= baz?.let{
  // complex expression 3
}
x ?= defaultValue

```

---

<div class="post-metadata">

**Author:** ![guai](https://avatars.discourse-cdn.com/v4/letter/g/7ba0ec/32.png) [@guai](https://discuss.kotlinlang.org/u/guai)\
**Post date:** [September 18, 2018, 4:45pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/25 "2018-09-18T16:45:21Z")

</div>

ok, I think this way compiler could ensure non-nullability. but in this case it’ll have to look forward, not sure if this possible.  
I think having `var x: Foo?` here is good enough since `x` will be narrowed after last conditional assignment anyway

---

<div class="post-metadata">

**Author:** ![tieskedh](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/tieskedh/32/2816_2.png) [@tieskedh](https://discuss.kotlinlang.org/u/tieskedh)\
**Post date:** [September 18, 2018, 5:35pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/26 "2018-09-18T17:35:46Z")

</div>

is this a duplicate of: [Nullable assigner?](https://discuss.kotlinlang.org/t/nullable-assigner/3931)

if so, some reasons to include:

> [@Nullable assigner?](https://discuss.kotlinlang.org/t/nullable-assigner/3931/5):
>
> The main reason why I posted this is that I found a lot of the following code samples: if(a != null) a = func() a!!.exec() I wanted to refactor this, but right now I need to check four things before I can refactor: Is setA or func expensive? Does setA handle assigning the same variable to it well? Does func have side effects? Does a need to be set, before calling exec on it. When one of these reasons is true, only the nullable assigner or where it is mapped to is possible. I will search fo…

---

<div class="post-metadata">

**Author:** ![guai](https://avatars.discourse-cdn.com/v4/letter/g/7ba0ec/32.png) [@guai](https://discuss.kotlinlang.org/u/guai)\
**Post date:** [September 18, 2018, 5:50pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/27 "2018-09-18T17:50:20Z")

</div>

Seems similar  
Looks like in groovy they made what you proposed  
I also wanted to have a simpler syntax for something like this

```auto
val b = getValueOrNull() // map["key"] for example
if(b != null) a = b

```

@tieskedh, didn’t you create a KEEP or task for this feature?

---

<div class="post-metadata">

**Author:** ![tieskedh](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/tieskedh/32/2816_2.png) [@tieskedh](https://discuss.kotlinlang.org/u/tieskedh)\
**Post date:** [September 18, 2018, 5:51pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/28 "2018-09-18T17:51:52Z")

</div>

Nope, at the moment of creation, I didn’t get a lot of likes, so I didn’t continue the topic.  
The biggest part of the conversation was about if you needed to write everything as a one-liner 😉

---

<div class="post-metadata">

**Author:** ![tomschrot](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/tomschrot/32/4346_2.png) [@tomschrot](https://discuss.kotlinlang.org/u/tomschrot)\
**Post date:** [September 18, 2018, 5:57pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/29 "2018-09-18T17:57:42Z")

</div>

Maybe I didnt catch the idea, but any conditional assignment could be done using the when-syntax, e.g.:

```
val str: String? = "c"
   val n: Int =
	when(str){
		null -> 0
		"a" -> 1
		"b" -> 2
		else -> -1
	} 

```

-T

---

<div class="post-metadata">

**Author:** ![guai](https://avatars.discourse-cdn.com/v4/letter/g/7ba0ec/32.png) [@guai](https://discuss.kotlinlang.org/u/guai)\
**Post date:** [September 18, 2018, 6:01pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/30 "2018-09-18T18:01:05Z")

</div>

WDYT about this three elvises `?=`, `=?` and `?=?` ?  
One of them would be familiar to groovy coders (the one that checks receiver), another one checking the message, and last one well for symmetry

---

<div class="post-metadata">

**Author:** ![tieskedh](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/tieskedh/32/2816_2.png) [@tieskedh](https://discuss.kotlinlang.org/u/tieskedh)\
**Post date:** [September 18, 2018, 6:15pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/31 "2018-09-18T18:15:39Z")

</div>

Now I see we had different use-cases: I wanted to have “set if not null and get always”.

I’m interested in a use-case where you would like to use `?=` , but not `?=?`

---

<div class="post-metadata">

**Author:** ![guai](https://avatars.discourse-cdn.com/v4/letter/g/7ba0ec/32.png) [@guai](https://discuss.kotlinlang.org/u/guai)\
**Post date:** [September 18, 2018, 6:23pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/32 "2018-09-18T18:23:37Z")

</div>

They are for one-liners, to save one null check. Kinda like what elvis does  
In my project I have a lot of untyped input data which needs to be assigned to typed DTOs before any further usage.

My final proposal for now is to make 3 new operators (one of which will be borrowed from groovy 3):

```auto
a ?= b // instead of
if(a == null) a = b

a =? b // instead of
if(b != null) a = b

a ?=? b // instead of
if(a == null && b != null) a = b

```

question mark here is on the side which is to be checked for null

---

<div class="post-metadata">

**Author:** ![guai](https://avatars.discourse-cdn.com/v4/letter/g/7ba0ec/32.png) [@guai](https://discuss.kotlinlang.org/u/guai)\
**Post date:** [September 18, 2018, 7:23pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/33 "2018-09-18T19:23:46Z")

</div>

Yeah, on second thought it kinda looks useless by itself. The only difference here is whether a setter should be called when null passed to a null receiver  
so then let it be

```auto
a ?= b // instead of
if(a == null && b != null) a = b

a =? b // instead of
if(b != null) a = b

```

---

<div class="post-metadata">

**Author:** ![tieskedh](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/tieskedh/32/2816_2.png) [@tieskedh](https://discuss.kotlinlang.org/u/tieskedh)\
**Post date:** [September 18, 2018, 7:49pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/34 "2018-09-18T19:49:17Z")

</div>

The problem at this point is that the syntax doesn’t do what it seems to do

---

<div class="post-metadata">

**Author:** ![guai](https://avatars.discourse-cdn.com/v4/letter/g/7ba0ec/32.png) [@guai](https://discuss.kotlinlang.org/u/guai)\
**Post date:** [September 18, 2018, 8:25pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/35 "2018-09-18T20:25:51Z")

</div>

in case of `?=` it will do the same as in groovy, assign default value, except assigning null as a default which is pointless  
in case of `=?` its just ‘assign if there is something to assign’  
and “there will be a null check on the side where ‘?’ is”  
dunno, seems ok to me

---

<div class="post-metadata">

**Author:** ![cabman](https://avatars.discourse-cdn.com/v4/letter/c/50afbb/32.png) [@cabman](https://discuss.kotlinlang.org/u/cabman)\
**Post date:** [September 19, 2018, 3:22am UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/36 "2018-09-19T03:22:52Z")

</div>

Isn’t this equivalent of:

> [@](#):
>
> ```
> val x = foo?.let {
> // complex expression 1
> } ?: bar?.let {
> // complex expression 2
> } ?: baz?.let {
> // complex expression 3
> }
> 
> ```

It seams even more clean and readable this way. Also type can be calculated automatically (nullable or not).

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [September 19, 2018, 4:19am UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/37 "2018-09-19T04:19:44Z")

</div>

Yes, that’s what I would code today.

Cool? Yes. It is amazing what can be done in a single expression in kotlin.

But I disagree that it is more clean. It can get out of control quickly.

---

<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:** [September 19, 2018, 4:37am UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/38 "2018-09-19T04:37:50Z")

</div>

> [@cabman](#):
>
> Isn’t this equivalent of:

> [@fatjoe79](#):
>
> Yes, that’s what I would code today.

Is it? Are we talking about the same code samples here?  
If I understand you correctly you said that

```auto
// from fatjoe79
var x: Foo // I guess that would need to be Foo? = someInitlialValue
x ?= foo?.let{
  // complex expression 1
}
x ?= bar?.let{
  // complex expression 2
}
x ?= baz?.let{
  // complex expression 3
}

```

is the same as

```kotlin
// from cabman
val x = foo?.let {
    // complex expression 1
} ?: bar?.let {
    // complex expression 2
} ?: baz?.let {
    // complex expression 3
}

```

But based on my understanding the code @fatjoe79 posted translates to

```kotlin
var x: Foo? = someValue
if(x == null) x = foo?.let{ ... }
if(x == null) x = bar?.let{ ... }
if(x == null) x = baz?.let{ ... }

```

So @cabman’s code would need to be

```kotlin
val x = x ?: foo?.let {...} 
//etc

```

Which is still not the same exactly as the setter is called even if x is not null, which might in some cases have side effects.

---

<div class="post-metadata">

**Author:** ![cabman](https://avatars.discourse-cdn.com/v4/letter/c/50afbb/32.png) [@cabman](https://discuss.kotlinlang.org/u/cabman)\
**Post date:** [September 19, 2018, 4:39am UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/39 "2018-09-19T04:39:42Z")

</div>

… as your solution.

I think this syntax sugar is unnecessary and will make language come complicated then needed.

---

<div class="post-metadata">

**Author:** ![cabman](https://avatars.discourse-cdn.com/v4/letter/c/50afbb/32.png) [@cabman](https://discuss.kotlinlang.org/u/cabman)\
**Post date:** [September 19, 2018, 4:50am UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/40 "2018-09-19T04:50:00Z")

</div>

I recall the idea was to make `val x`, so there is no setter AT ALL.

I didn’t suggest `val x = x ?: foo?.let {...} ` in which case the getter is called unlike original code.

If you want `var x` then setter will be called anyway as the initial value must be assigned. @Wasabi375, your code would be converted into:

```
var x = someValue ?: foo?.let{...} ?: bar?.let{...} ?: baz?.let{...}

```

In both case there is only 1 assignment will be executed (except in your code and not one from @fatjoe79) the original value.

Still don’t see advantage of these extra sugar.

[Previous page](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150.md?page=1)

[Next page](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150.md?page=3)
