Skip to main content
Donovan LaDuke - Developer

Improving Legibility with the .not() Function


Featured in Android Weekly Issue 621

The exclamation point operator (i.e. !) is the most common way to invert a boolean value as it is the only and default way to do so in many languages. However, there is a more readable solution offered by the nature of Kotlin's operator overloading. By using the .not() function directly, the intention of the code becomes clearer and easier to read.

The .not() Operator Function #

The overload for the ! operator is operator fun T.not(): T which by convention negates the value. As a quick example, here is a custom class overloading the ! operator. This example is just to show how to use the overload, and is not intended to show when best to use it.

data class User(
  val name: String,
  val isActive: Boolean = true,
) {
  operator fun not(): User {
    return copy(isActive = false)
  }
}

object Test {
  var user = User("John Doe")
    
  fun deactivateUser() {
    user = !user
  }
}

Improving Legibility with .not() #

For the standard Boolean type the ! means converting false to true and vice-versa which is a common need in programming. The issue arises that while reading code the ! can slip by unnoticed risking bugs and slowing down other programmers trying to understand the code. We can fix this by calling the .not() function directly. To understand this more clearly, here is an example.

First, here is some code using !.

val limitRequests = true
if(!limitRequests) {
  println("No Limits!")
}

Now here is the same code using the .not() function directly.

val limitRequests = true
if(limitRequests.not()) {
  println("No Limits!")
}

In the second example, there is no risk of the ! hiding next to the l and the intent of the conditional is abundantly clear.

Consideration #

A critique that will immediately arise is that in cases like the above the same improvement in legibility can be accomplished by inverting the variable itself. So in the above example limitRequests could become allowRequests and then the conditional becomes if(allowRequests). This is both a valid and valuable solution for the above problem and could even be preferable. It is not however universal as the variable may be owned by an external library or the variable may need to be used both negated and not, meaning ! or not() will need to be used at some point.

Conclusion #

The old adage that applies here is that "Programs should be written for people to read, and only incidentally for machines to execute." (Hal Abelson and Jerry Sussman). Consider using the .not() function in your code to improve clarity and comprehension. Until next time, thanks!

Did you find this content helpful?

Please share this post and be sure to subscribe to the RSS feed to be notified of all future articles!

Want to go above and beyond? Help me out by sending me $1 on Ko-fi. It goes a long way in helping run this site and keeping it advertisement free. Thank you in advance!

Buy me a Coffee on Ko-fi