# 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:** 1

<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:** [June 14, 2018, 12:58pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/1 "2018-06-14T12:58:30Z")

</div>

Hi  
I don’t really like constructions like this:

```
(record["speed"] as Int?)?.let { speed = it }

```

Maybe it would be better to make something like this work:

```
speed ?= record["speed"] as Int?

```

I think ruby have something similar already in the form of:

```
a ||= b

```

---

<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:** [June 14, 2018, 1:03pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/2 "2018-06-14T13:03:23Z")

</div>

Upd: I was wrong about ruby. It checks left side and if it is not null then assigns

---

<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:** [June 14, 2018, 1:08pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/3 "2018-06-14T13:08:13Z")

</div>

I don’t even understand what your Kotlin example should be doing and I don’t think this will actually run. Unless you mean something like this

```kotlin
var speed = someValue
(record["speed"] as Int?)?.let { speed = it }

```

Why not just

```kotlin
speed = (record["speed"] as Int?) ?: speed

```

---

<div class="post-metadata">

**Author:** ![pdvrieze](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/pdvrieze/32/1882_2.png) [@pdvrieze](https://discuss.kotlinlang.org/u/pdvrieze)\
**Post date:** [June 14, 2018, 1:08pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/4 "2018-06-14T13:08:39Z")

</div>

Maybe the cast in your example isn’t really great, but I agree with your issue. It is ugly although it works. Your syntax is an interesting approach.

---

<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:** [June 14, 2018, 1:12pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/5 "2018-06-14T13:12:21Z")

</div>

Yeah, I should define what speed is. It is some property in the current scope. I’m filling an object with incoming data in the form of a map

---

<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:** [June 14, 2018, 1:15pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/6 "2018-06-14T13:15:03Z")

</div>

I like the idea of `speed ?= someValue` assigning only if not null. I just was confused by the cast 😉

---

<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:** [June 14, 2018, 4:40pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/7 "2018-06-14T16:40:21Z")

</div>

EDIT:

I think I misunderstood.

The correct alternative is something like

```
if (someValue != null) speed = someValue

```

or

```
speed = someValue ?: speed

```

Just like my original reply, I think most people would assume `speed ?= someVlue` to perform just like the Ruby `a ||= b` (if left side is null, assign some value).

* * *

ORIGINAL:

I think this would have limited gain.

Something like

```
speed ?= someValue

```

is only short for

```
if (speed == null) speed = someValue

```

or

```
speed = speed ?: someValue

```

IMO, although `speed ?= someValue` is slightly shorter than the current options, the current options work fine as they are now.

All of these options assume we’re working with non-final fields. Maybe I’m missing some use case where you have a ton of `null` properties that need to be set to default values.

---

<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:** [June 14, 2018, 5:00pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/8 "2018-06-14T17:00:49Z")

</div>

Its like

```
val maybeSpeed: Int? = record["speed"] as Int?
if(maybeSpeed != null) speed = maybeSpeed

```

I was wrong comparing it to ruby. Ruby’s `a ||= b` is more like `speed = speed ?: defaultValue`  
But what I want is compare right side expression to null, and only if its not null then assign.  
And yes I have a lot of code like that. Its mostly untyped data transfer maps in which most keys can absent

---

<div class="post-metadata">

**Author:** ![pdvrieze](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/pdvrieze/32/1882_2.png) [@pdvrieze](https://discuss.kotlinlang.org/u/pdvrieze)\
**Post date:** [June 14, 2018, 8:58pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/9 "2018-06-14T20:58:24Z")

</div>

The meaning is to assign only if not null (maybe it would work on either side - aka a field reference on a null object). I can see how `?=` may be confusing though. I like the concept, I’m not sure on the syntax.

---

<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:** [June 15, 2018, 5:35am UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/10 "2018-06-15T05:35:46Z")

</div>

What does the declaration of `speed` look like. Is a default value assigned to is if `maybeSpeed` is `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:** [June 15, 2018, 9:26am UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/11 "2018-06-15T09:26:10Z")

</div>

I think no, the value should stay the same, and not reassigned or reset to default when right-hand side is null.  
`speed` is just a `var` property, in this particular case it is delegated to some ORM-like storage like `var speed: Int? by Storage.attribute<Int?>("columnName")` but it doesn’t actually matter

---

<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:** [June 15, 2018, 9:51am UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/12 "2018-06-15T09:51:40Z")

</div>

So `speed` is a nullable `var`.

Normally you would use one of the proposed solutions above (using `?:`) to provide a default value, but in your case you want to keep the current value unless the new value is not `null`.

The version with `let` is the shortest way to write what you need at this moment. If you find it hard to read, you could write a function yourself. But this will make the code a bit longer:

```auto
fun <T: Any> assignIfNotNull(value: T?, block: (T) -> Unit) {
    if (value != null) {
        block(value)
    }
}

fun main(args: Array<String>) {
    val record = mapOf("speed2" to 2)
    var speed: Int? = 1
    assignIfNotNull(record["speed"] as Int?, { speed = it })
    println(speed)
    assignIfNotNull(record["speed2"] as Int?, { speed = it })
    println(speed)
}

```

A shorter syntax would be nice, but I agree that `?=` is not appropriate, because the question mark currently always evaluates the expression before it. Maybe reverse it: `=?`

---

<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:** [June 15, 2018, 10:17am UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/13 "2018-06-15T10:17:16Z")

</div>

> [@jstuyts](#):
>
> Maybe reverse it: `=?`

I think you are right, `=?` is better

---

<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:** [June 15, 2018, 2:18pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/14 "2018-06-15T14:18:05Z")

</div>

What about something like this:

```run-kotlin
import kotlin.reflect.KMutableProperty0

fun <T> KMutableProperty0<T>.setIfNotNull(value: T?) {
    if (value != null) this.set(value)
}

var speed = 1
fun main(args: Array<String>) {
    //sampleStart
    println(speed) // speed is 1

    var maybeSpeed: Int? = null
    ::speed.setIfNotNull(maybeSpeed)

    println(speed) // speed is 1

    maybeSpeed = 2
    ::speed.setIfNotNull(maybeSpeed)

    println(speed) // speed is 2
    //sampleEnd
}

```

---

<div class="post-metadata">

**Author:** ![Beholder](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/beholder/32/2078_2.png) [@Beholder](https://discuss.kotlinlang.org/u/Beholder)\
**Post date:** [June 15, 2018, 2:27pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/15 "2018-06-15T14:27:22Z")

</div>

@arocnies, reflection is too costly.  
I think, `let` function is enough for most cases.

---

<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:** [June 15, 2018, 2:42pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/16 "2018-06-15T14:42:28Z")

</div>

I know reflection can be costly at times, but in this case I wonder how much of an impact it would be on the application. It runs fine in JavaScript as well.

I’d love to see some performance metrics to show if this use case really is costly.

---

<div class="post-metadata">

**Author:** ![dalewking](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dalewking/32/1496_2.png) [@dalewking](https://discuss.kotlinlang.org/u/dalewking)\
**Post date:** [June 16, 2018, 1:50am UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/17 "2018-06-16T01:50:27Z")

</div>

> [@Wasabi375](#):
>
> Why not just
> 
> ```auto
> speed = (record["speed"] as Int?) ?: speed
> 
> ```

Not expressing an opinion on the proposal, but that is subtly different in that it always sets speed. For standard setters, it doesn’t matter but with custom setters it could be a big difference.

---

<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:** [June 16, 2018, 1:55am UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/18 "2018-06-16T01:55:10Z")

</div>

point taken. Did not think of that.

---

<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, 11:29am UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/19 "2018-09-18T11:29:30Z")

</div>

Groovy now has this feature since 3.0: [Elvis assignment operator](http://groovy-lang.org/releasenotes/groovy-3.0.html)  
in the form of:

```auto
    name = name ?: 'Hydrogen' // existing Elvis operator
    atomicNumber ?= 2 // new Elvis assignment shorthand

```

---

<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, 12:31pm UTC](https://discuss.kotlinlang.org/t/conditional-assignment-operator-proposal/8150/20 "2018-09-18T12:31:48Z")

</div>

I got confused again  
groovy’s new operator checks if left side is null but in the first message of the post I wanted simpler syntax to check right side, and assign it only when it contains something but null  
if there would be both `?=` and `=?` for that two cases that would make sense, but isn’t it too much, WDYT?

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