Making Safe Functions

When we write Kotlin functions, it’s important that we make sure that our code is stable and behave correctly. It’s also important to be clear as to what the function expects in order to behave correctly.

To do this, we have to declare our expectations clearly. Luckily, Kotlin provides built-in functions to help us do this.

Require

We can use require to set expectations for our function arguments. require function will throw an exception if the predicate was not satisfied. For example:

fun greet(age: Int) : {
    require(age in 10..99) { "Age must be within 10 and 99" }
    makeGreetings()
}

If we call greet(0), the program will terminate because of IllegalArgumentException with a message “Age must be within 10 and 99”. This is great because we can clearly set the expectations without writing a lot of boilerplate code.

Check

Another useful built-in function is check. If your function relies on specific state of the object, you can use check to verify the value of the state. For example:

class Person {
    var awake = true

    fun sing() {
        check(awake) { "A person cannot sing while sleeping." }
        performSinging()
    }
}

Here, we check first if the person object is awake before actually singing. It throws an IllegalStateException if awake is false.

Assert

Another useful function is assert. Similar to check, it’s another way to verify if an expression is true. The main different with check is that assert will only be evaluated during testing mode.

class Person {
    var awake = true

    fun sing() {
        check(awake) { "A person cannot sing while sleeping." }
        val state = performSinging()
        assertTrue(state)        
    }
}

Elvis operator

Elvis operator is a very concise way of verifying arguments. But personally, I find this sometimes too complex to understand compared to a simple if-else block or require.

fun isInRange(endInclusive: Int): Boolean {
    return endInclusive > 0 && endInclusive < 100 ?: throw IllegalArgumentException("endInclusive should be between 1 and 99")
}

In summary, Kotlin provides a lot of useful functions that can help us write safe and readable functions.