kotlin?.apply{null} Anti-pattern!

Image for post
Image for post

Some light on “Also this is Null” anti-pattern.

Kotlin weekly is a great newsletter, once a week they send amazing blogs about Kotlin and Android development,

this week, i.e. 31stMarch19 Edition # 355, I saw an article named “Kotlin Anti-Patterns — Also this is Nullwhich made me panic because I use this pattern everywhere in my codebase. I will suggest you guys go and read this article but for all lazy people …

  • The safe calls operator ?. allows for a method to be called on a variable if the variable is not null, otherwise, the statement returns null.
  • The also block .also{}, creates a function block with this value as its argument and returns this value. Allowing you to operate on a variable repeatedly with less boilerplate.
  • The anti-pattern is when, when we combine these who methods together. which Paul Blundell author of the article calls as “Also this is Null”.

When we are chaining safe call operator with also functional block we are creating a null check in disguise.

example:

foo?.also { //it: Foo
it.someFunc()
}

OR

foo?.also { //it: Foo
someFunc(it)
}
  • Null check in disguise and cannot be figured out at first glance.
  • Using also block internally creates a micro-context switch named it, adding unnecessary cognitive load to reading the code.
  • Code block not having a resemblance to past learned code patterns, it is hiding the potential to spot it as a typical code smell.

He recommends,

  • Writing a method referenced or parameter null object as Recommended methods foo?.someFunc()
  • Prefer immutability or refactor to an explicit null check. i.e

if(foo != null) { someFunc(foo) }

  • Don't be scared of using !!.It is slightly significant as will cause an exception and stop the code executing. someFunc(foo)!!
  • The aim of Kotlin is to avoid mutability and null objects, sometimes though they are a necessary evil.

My opinion on this anti-pattern is quite different, I duly respect Paul’s view here, because he as much more experience here. Going through his article made me jump through so many posts that I have read on using functional blocks of run,let,apply,also , and my understanding dropped many thoughts that is discusse below below:

  • This Anti-pattern is surely a null check in disguise, and it was supposed to be looked like that,

Kotlin as a language is designed for focusing on readability, making it closer to a higher level language like English. One of the things that are very common in Java is null pointer exception and ugly null pointer check, to make Kotlin null safe it, Jetbrain added safe operator ? . Just by wrapping that null check in the immersion of English like experience just increase.

We even do this kind of approach in writing a unit test, Mockk a unit test library for Kotlin add some extension function like verify, every, returns which has wrapped functions adds to readability for the test case.

  • Adding also functional block creates a micro-context named it . Adding functional block also adds to the readability as well as micro-module in your codebase.

for instance, observe the following code :

var init:Intent? = getIntent()
init.putExtra("foo","pokemon")
init.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP )
startActivity(init)

generally, most of the code is not so linear like this, I have encountered much real-life implementation where the code is Spaghetti and Salsa together much like :

isloading = false
var init:Intent? = getIntent()
init.putExtra("foo","pokemon")
hideDialog()
init.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP )
showToast()
sharedPref.update(pokemon)
SendfirebaseEvent("Exiting activity 1")
startActivity(init)
SendfirebaseEvent("Starting activity 2")

Each line of the code is doing something else as well as referring back to the Intent object. Here using this pattern can really affect readability and also create micro-module for better workflow design.


startActivity( getIntent()?.also {
it.putExtra("foo","pokemon")
it.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP )
})

Here everything is wrapped in nice small space. You can even use apply to skip it from the window if it adds noise to cognitive load.

  • Code block not having a resemblance to past learned code patterns, and creates a smell in code, I believe this is somewhat wrong. Patterns are sometimes language-specific. This could be treated Kotlin block pattern.

these are the only places I find disagreement with his views, and I absolutely agree that we should not be scared of using !! operator, but would like to minimize its use cause it looks hacky and makes a distraction while reading. The aim of Kotlin not only to avoid mutability and null objects but to provide readability.

This post shouldn't be taken as hate for Paul’s article, he is great! that why in Kotlin weekly . I’m just sharing my humble opinion.

The End…or is It?

Well, again all my jibberish was fake… this Anit-pattern exists. Yes but in a different form. if you observe above code properly,

startActivity( getIntent()?.also {
it.putExtra("foo","pokemon")
it.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP )
})

we have passed getIntent()? as the parameter of the startActivity() tough we have specified what happens it's not null, but what about when it isn’t?.

Elvis operator ?: When we have a nullable reference lets say foo, we can say “if foo is not null, use it, otherwise, use some non-null value something else”. example:

val length = fooArray?.length ?: -1

so a proper implementation of such as function would be

startActivity( getIntent()?.also {
it.putExtra("foo","pokemon")
it.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP )
}?:Intent(this,SOME_ERROR::class))

🙈 sorry for this example no one practically uses this but just needed a sample for explaining this.

Conclusion.

I'm not that well convinced that it is an anti-pattern. It keeps my code cleaner and readable. For now, I'm keeping it as my applys don't return null and even if they do my Elvises are waiting for them.

Please do let me know your opinion. Thanks

P.s. checkout my blogger, maybe you discover something new!

Happy Coding!

Written by

Coding enthusiast! love Android #kotlinAlltheWay, want to explore all opportunity around it! CodingMantra: #cleanCoder #TDD #SOLID #designpatterns

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store