Run, with, let, also and apply

Some of the Kotlin’s standard functions are so similar that we are not sure which to use. Here I will introduce a simple way to clearly distinguish their differences and how to pick which to use.

Scoping functions

The functions that I’ll focus on is run, with, T.run, T.let, T.also and T.apply. I call them scoping functions as I view their main functionality as provide an inner scope for the caller function.

Run

The simplest way to illustrate scoping is the run function.


With this, inside the test function, you could have a separate scope where mood is redefined to ‘I am happy’ before printing, and it is fully enclosed within the run scope.

This scoping function itself seems not very useful. But there’s another nice bit it has than just the scope; it returns something i.e. the last object within the scope. Hence the below would be neat, where by we can apply the show() to both views as below, without calling it twice.


3 attributes of scoping functions

To make scoping functions more interesting, let me categorize their behavior with 3 attributes. I will use these attributes to distinguish them from each others.

1. Normal vs. extension function

If we look at with and T.run, both functions are actually pretty similar. The below does the same thing.

However, their different is one is a normal function i.e. with, while the other is an extension function i.e. T.run.

So the question is, what is the advantage of each?

Imagine if webview.settings could be null, they will look as the code at the right.


If we

In this case, clearly T.run extension function is better, as we could apply check for nullability before using it.
2. This vs. it argument

If we look at T.run and T.let, both functions are similar except for one thing, the way they accept the argument. The code shows the same logic for both functions.

If you check the T.run function signature, you’ll notice the T.run is just made as extension function calling block: T.().

Hence all within the scope, the T could be referred as this. In programming, this could be omitted most of the time. Therefore in our example above, we could use $length in the println statement, instead of ${this.length}. I call this as sending in this as argument.

However for T.let function signature, you’ll notice that T.let is sending itself into the function i.e. block: (T). Hence this is like a lambda argument sent it. It could be referred within the scope function as it. So I call this as sending in it as argument.

From the above, it does seems like T.run is more superior over T.let as it is more implicit, but there are some subtle advantages of T.let function.


The T.let does provide a clearer distinguish use the given variable function/member vs. the external class function/member.

In the event that this can’t be omitted e.g. when it is sent as a parameter of a function, it is shorter to write than this and clearer.

The T.let allow better naming of the converted used variable i.e. you could convert it to some other name.

3. Return this vs. other type

However their subtle different is what they return. The T.let returns a different type of value, while T.also returns the T itself i.e. this.

Both are useful for chaining function, where by T.let let you evolve the operation, and T.also let you perform on the same variable i.e. this.


The T.also may seems meaningless, as we could easily combine them into a single block of function. Thinking carefully, it has some good advantages.

  • It can provide a very clear separation process on the same objects i.e. making smaller functional section.
  • It can be very powerful for self manipulation before being used, making a chaining builder operation.

When both combine the chain, i.e. one evolve itself, one retain itself, it becomes something powerful e.g. below.


Function selections

Hence clearly, with the 3 attributes, we could now categorize the functions accordingly. And based on that, we could form a decision tree below that could help decide what function we want to use pending on what we need.

 

Hopefully the decision tree above clarifies the functions clearer, and also simplifies your decision making, enable you to master these functions usage appropriately.

 

 

Questions

I hope the description was understandable and clear. But if you have still questions, then leave me comments below! 😉

Have a nice a day! 🙂

 


 

Follow and like us:
Click to rate this post!
[Total: 0 Average: 0]

Leave a Reply

Your email address will not be published. Required fields are marked *