Null-save arithmetic operations (a /? b)

From time to time I have to work with nullable numbers in Kotlin. Kotlin has a lot of instuments for working with nullable types, but I believe it lacks support of arithmetic operations on them.

For instance, consider the following snippet:

var a: Double? = 10.0
var b: Double? = 20.0
var c = if (a != null && b != null) a / b else null

Here we need to check both variables for null before applying division - too much code

The situation gets worse when operands are mutable fields

class Test {
    var a: Double? = null
    var b: Double? = null;
    var c: Double? = null;
}

class TestService() {
    fun calculateValues(test: Test) {
        val a = test.a
        val b = test.b
        if (a != null && b != null)
            test.c = a / b
    }
}

My suggestion is to add arithmetic operators, that can accept nullable arguments and return null if one of the arguments is null: something like that

var a: Double? = 10.0
var b: Double? = 20.0
var c = a /? b

and

class TestService() {
    fun calculateValues(test: Test) {
         test.c = test.a /? test.b
    }
}

Defining whole new set of operators just to solve this narrow use case is a bit strange (I am totally opposed to that idea). If you really need it, I think you can create new class like that:

class SmartDouble(val a: Double?){
    operator fun div(b:Double?): Double?{
        return if (a != null && b != null){
             a / b
        } else{
            null
        }
    }
}

There is no need to define additional classes.
Just define extension methods like this:

operator fun Double?.div(other: Double?) = if (this != null && other != null) this / other else null
1 Like

Also, if you need “invalid propagating” arithmetic, you can always use Double.NaN instead of nulls.

I thought about that. But I am not sure it will work, since method signature looks the same as div already defined for Double. In that case extension method won’t work since implemented method always shadows extension.

It works because objects of type Double? are not instances of Double, so it’s not even possible to call Double.div with Double?s.