The Programmers Guide To Kotlin - Anonymous and Lambda Functions
Written by Mike James   
Monday, 29 October 2018
Article Index
The Programmers Guide To Kotlin - Anonymous and Lambda Functions
Lambda Functions
Closure

Closure

Closure is one of the most mystifying aspects of lambdas. The Kotlin documentation makes a lot of the fact that a lambda has access to the local variables of any function that encloses it, but this is really just the way that local variable work rather than closure.

Closure, in the way that most languages implement it, means having access to variables that were local but are no longer in scope. The simplest example of this is when a function returns a lambda. While the function is executing, the lambda has access to variables that are local to the function – but not only this, it has access to them when the function has completed and the local variables have been, in principle, destroyed. You can think of this as the lambda "capturing" the variables in a closure.

Kotlin supports this sort of closure. For example, if we define a function that returns a simple lambda:

fun myFunction():()->Unit{
    var a=1
    var lambda= {println(a);a=a+1}
    return lambda
}

There are several interesting things about this function. The first is that its return type is ()->Unit, i.e. it returns a function that accepts no parameters and returns nothing, i.e. Unit. This is indeed the type of the lambda it returns. The lambda in question simply prints the value of a and adds one to it. Note that a is a local variable in myFunction and it is only accessible from within myFunction and it is destroyed when myFunction returns, i.e. it normally only exists while myFunction is active.

If you now call myFunction to get an instance of the lambda:

var mylambda=myFunction()

and then call the lambda twice:

    mylambda()
    mylambda()

what do you think will happen?

The answer is that it prints 1 followed by 2. The instance has access to the local variable that should have been destroyed when myFunction terminated, and it not only has access to its initial value but it can modify it. 

It is important to realize that each time you return a new instance of the lambda the local variable a is a new local variable.

For example:

var mylambda1=myFunction()
var mylambda2=myFunction()
mylambda1()
mylambda1()
mylambda2()
mylambda2()

You will see 1,2 and then 1,2 printed because the variable a captured by mylambda1 is not the same as the a captured by mylambda2.

Closure works with named and anonymous functions as well as pure lambda functions. In the case of named functions it has to be a local function and you have to use the :: operator.

For example:

fun myFunction():()->Unit{
    var a=1
    fun namedFunction(){
        println(a)
        a=a+1
    }     var lambda= ::namedFunction
    return lambda
}

If you are unfamiliar with lambda functions or functions as first class objects you might be wondering what use closure is?

There are a number of standard uses of closure, but perhaps the most useful is when you are defining an event handler of a callback function. Lambdas and anonymous functions make supplying a callback very easy. However, the callback is usually designed to process the end result of some long running task and this usually involves the function that created the callback. If the task wasn't long running you would have simply waited for it to complete and then processed its return value. The callback breaks up the original function into before the task and after the task. By allowing the callback access to the function’s local variables, closure allows a degree of communication between the original function and the callback.

Inline Functions

final version in book

Non-Local Returns

final version in book

Reified Type

final version in book

Summary

 

  • You can store a reference to an anonymous function in a variable or pass the function as an argument to another function.

  • You can store a reference to a named function in a variable or parameter using the reflection reference operator ::

  • A reference to a lambda function can also be stored in a variable or passed as a parameter.

  • A lambda is defined as { parameter list -> code }

  • A lambda, anonymous or named function can be used as extension functions.

  • The shortened forms that you can use to define and call functions make them very suitable to implement DSLs and metaprogramming.

  • You cannot have a return in a lambda but you can use a qualified return.

  • Lambdas can be simplified to the point where they are difficult to understand. You can use it as a default parameter of a single parameter lambda, leave out parameters using underscore, and execute a lambda immediately.

  • All Kotlin functions support closure where variables that were in scope at the time the function was created remain accessible to the function even after they have gone out of scope.

  • Inline functions can be used to improve performance and add features such as non-local returns and reification

 

This article is an extract from: 

Programmer's Guide To Kotlin Third Edition

kotlin3e360

You can buy it from: Amazon

Contents

  1. What makes Kotlin Special
  2. The Basics:Variables,Primitive Types and Functions 
  3. Control
         Extract: If and When 
  4. Strings and Arrays
  5. The Class & The Object ***NEW!
  6. Inheritance
  7. The Type Hierarchy
  8. Generics
  9. Collections, Iterators, Sequences & Ranges
        Extract: Iterators & Sequences 
  10. Advanced functions 
  11. Anonymous, Lamdas & Inline Functions
  12. Data classes, enums and destructuring
        Extract: Destructuring 
  13. Exceptions, Annotations & Reflection
  14. Coroutines
        Extract: Coroutines 
  15. Working with Java
        Extract: Using Swing
  16. Compose Multiplatform
        Extract: Compose Layout 

<ASIN:B0D8H4N8SK>

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

 

Banner


Gifts For Geeks 2024
22/11/2024

Are you ready for Thanksgiving, when overeating remorse and a surfeit of being thankful causes the unsettling thought that there are only four weeks till the Xmas break? So here is a mix of weird [ ... ]



Lightbend Announces Akka 3
15/11/2024

Lightbend, the company that developed Akka, has announced Akka 3, and has changed its name to Akka. The company produces cloud-native microservices frameworks, and Akka is used for building distribute [ ... ]


More News

espbook

 

Comments




or email your comment to: comments@i-programmer.info

<ASIN:1871962536>

 

 

 



Last Updated ( Saturday, 03 November 2018 )