Kotlin Tutorial: Scoping functions, lambda functions and more

In this document you can find a series of basic examples showcasing the syntax and other aspects of functions, delegates, extension functions in Kotlin. This writeup deviates from what you might have learned with Java – you can treat this as brand-new knowledge.

Lazy property

Upon studying source code of Android apps written in Kotlin you will encounter examples like this:

kotlin private val users: MutableLiveData<List<User>> by lazy { // See the by lazy property? MutableLiveData().also{ //saves inside LiveData loadUsers() } } Read more about the also operator

As you can see from the example above, this kind of syntax is quite different from Java and most likely looks a bit confusing at first. Let’s tackle this one piece at a time – so what does the … by lazy { } do?

“Lazy” here refers to a lazy property: the value inside the brackets gets computed only when it is needed, upon first access. For example the following block of code corresponding to lazyValue is executed only when an attempt is made to access the value:

```kotlin val lazyValue: String by lazy { //Declare the var lazyValue using the by lazy{} keyword println(“computed once and then saved!”) //Initial the value is not set until lazyValue is called “Hello” //Subsequent calls use saved value }

fun main(){
   println(lazyValue)   // lazy keyword forces the initialization
   println(lazyValue)   // subsequent calls use the value stored from the lazy execution
}

`` Thelazyblock in the code above executes only once, the second time we accesslazyValueit will be read from the memory (upon the first execution it will besaved`).

So with lazy we can have more efficient code capable of delaying the execution of potentially heavy initialization blocks of code. It is especially suitable for properties that may or may not be accessed.

Read more about the lazy operator

lateinit keyword

Normally, if a property is declared, but not initialized, your code won’t compile, and you will get a nastygram from the compiler. You can think of lateinit as a way of telling the compiler that the given property will not be null and will initialize at some point, but not now:

```kotlin class Human { lateinit var name: String

fun name() {
    print(name.length) //raises an error since name isn't initialized yet.
    name = "John Doe"
    print(name.length)
}

} `` lateinitis useful for variables that hold handled to things like local databases, which take some time into start when the app runs. You can declare the handle aslateinit, and then test if the handle is created or not before use. It's important to remember that trying to use a variable that is declaredlateinitwill raise an error, so make sure your variables are initialized before use. Also, remember that you can't uselateiniton primitives likeInt,Long,Float,Char`, etc.

Read more about the lateinit keyword

Lambda functions

```kotlin class DetailFragment : Fragment () { private lateinit var model: SharedViewModel

override fun onCreate(savedInstanceState: Bundle? ){
    super.onCreate(savedInstanceState)
    model = activity?.run {
        ViewModelProviders.of(this).get(SharedViewModel::class.java)
    } ?: throw Exception("Invalid Activity")

    model.selected.observe(this, Observer<Item> { item ->
        //This is a lambda function
        //Do some stuff to update the UI
    })
}

} `` What about the functions that use->` syntax? The example shown in the screenshot above is using a lambda function. You can think of lambda functions as functions that are anonymous, so they can’t be called directly (since they are unnamed), and for one-time use. Here are some example of how lambda functions can used in Kotlin:

```kotlin //Lets create some lamdba functions that can be passed as parameters //The first will take two Ints and add them together, returning the sum val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }

//The second takes 2 Ints, multiplies them, and returns the product val mult = { x: Int, y: Int -> x * y }

/* This function takes three params: two Ints, and a Function. The function parameter passed determines the type of math applied / fun arithmetic ( i:Int,j:Int, foo: (i:Int,j:Int)->Int): Int{ return foo(i,j) }

fun main(){ println(arithmetic(2,3,sum)) // Add 2 and 3 println(arithmetic(2,3,mult)) // Mulitply 2 by 3

//In this case, we are creating a lambda function, to divide the Ints, within the call the arithmetic println(arithmetic(4,2,{x,y -> x / y})) // Divide 4 by 2 }

/ Output would be: 5 6 2 / ```

The example above shows how Kotlin can treat functions as parameters and pass them to other functions. In this particular case we have a function called arithmetic that takes three parameters: two ints and a function. The function that is received as a parameter determines the actual arithmetic operation to be performed. In our example there are three possibilities: summation, multiplication and division. All three of the operations have dedicated functions that are passed to arithmetic and then executed. Note the differences in the syntax used to define the functions. The differences in syntax show the flexibility of Kotlin in defining functions. The last example (division) is using a lambda function — it is not using a variable to refer to its body, the function is simply defined on the spot inside the place where the parameter referring to the function would go.

Read more about lambda functions

What about the also block (and other similar blocks)? What is it and why use it? See the docs..

And use the following guideline when it comes to choosing various scoping functions: