How To Use Kotlin Function Literals

dimitrilc 2 Tallied Votes 232 Views Share

Introduction

While Functional Interfaces and Function Types are used to declare the types of a function, Function Literals create the actual implementations of these types.

In this tutorial, we will learn what Kotlin Function Literals are and how to create them.

Goals

At the end of the tutorial, you would have learned:

  1. How to create lambdas.
  2. How to create anonymous functions.

Tools Required

  1. A Kotlin IDE such as IntelliJ IDEA version 2022.2 (Community Edition).
  2. The Kotlin version used in this tutorial is 1.7.10.

Prerequisite Knowledge

  1. Basic Kotlin
  2. Function Types

Project Setup

To follow along with the tutorial, perform the steps below:

  1. Create a new Kotlin project using Gradle as the build system.
  2. For the Project JDK, use JDK 18.

Lambda Expressions

The syntax for a lambda expression includes the following rules:

  1. Must always be surrounded by curly braces.
  2. Parameters go inside the curly braces, to the left of the arrow (->). Type annotation is optional if no explicit function type is declared on the variable, parameter, and return type.
  3. The body goes inside the curly braces, after the arrow (->).
  4. Unless the return type of the lambda is Unit, the lambda implicitly returns the last expression or the single value.

Here is an example of a lambda expression:

val timesTwo: (Int) -> Int = { x: Int -> x * 2 }

Screen_Shot_2022-08-14_at_10.42.21_AM.png

Because the type declaration already specified the parameter type, we can skip that in the lambda’s parameter as well.

val timesThree: (Int) -> Int = { x -> x * 2 }

The type declaration can be skipped entirely when the lambda contains enough information for the compiler to infer the parameter and return type.

val timesFour = { x: Int -> x * 2}

Here is an example of lambda expression being used as function arguments.

fun onClick(listener: (Any)->Unit){}
…
onClick (
   { any -> }
)
…

And here is an example of lambda expression being used as return values

fun getLambda(): (Int)->String {
   return { x -> "$x" }
}

This is an even shorter version of getLambda().

fun getLambda() = { x: Int -> "$x" }

Passing Trailing Lambda Syntax

When the last parameter of a function is a function, then you can use a special syntax called passing trailing lambda, which allows you to place the lambda expression outside the parentheses.

The onClick() function used in the previous section

onClick (
   { any -> }
)

can be we rewritten using the passing trailing lambda syntax

onClick { any ->  }

Since the listener was the only parameter on onClick(), we can skip the parentheses entirely.

Anonymous Functions

Anonymous functions are similar to lambdas, but with only a few differences:

  1. You do not need to wrap it inside curly braces.
  2. It looks exactly the same as a regular function, but without a name.
  3. You can use the return keyword directly in the function body.

Below is an example of an anonymous function being used with a variable.

val timesTwo = fun(x: Int): Int {
   return x * 2
}

timesTwo(1)

Here is an example of an anonymous function being used as a return value.

fun getLambda3(): (Int)->String {
   return fun(x: Int): String{
       return "$x"
   }
}

and its shorter version

fun getLambda4() = fun(x: Int): String { return "$x" }

Finally, this is how you can pass an anonymous function as an argument to another function.

onClick(fun(any){})

Summary

We have learned Kotlin’s lambda expressions and anonymous functions in this tutorial.

When working on real code, I rarely see anonymous function being used over lambda expressions because anonymous functions are much more verbose.

Dani AI

Generated

Builds on ’s clear primer by collecting practical patterns and gotchas that show up in real code: when a return exits the outer function vs only the literal, how to stop a lambda early, small performance choices (inline/noinline), using function literals with receiver for DSL-like code, and using function references or fun interface (SAM) for concise interoperability. (kotlinlang.org)

A common source of confusion is return semantics. Plain return inside a lambda can be non-local (it can exit the enclosing function) in contexts where the higher-order function is inlined; to return only from the lambda, use a labeled return (return@forEach) or an anonymous function (which returns locally). The examples below show both approaches.

val nums = listOf(1, 2, 3)
nums.forEach {
  if (it == 2) return@forEach   // local to the lambda
  println(it)
}

val mapped = nums.map(fun(x: Int): Int {
  if (x == 2) return -1         // returns from the anonymous function only
  return x * 10
})
println(mapped)

Non-local returns, labels, and the anonymous-function alternative are documented in the language guides. (kotlinlang.org)

Function literals with receiver and function references make code concise and expressive in DSLs or collection pipelines. Examples:

val surround: String.(String) -> String = { other -> this + "<" + other + ">" }
println("left".surround("right"))          // uses receiver inside the literal

val lengths = listOf("a", "bb", "ccc").map(String::length)
println(lengths)                          // function reference (::) used instead of a lambda

See the docs on function literals and callable references for details. (kotlinlang.org)

For Java interop or concise single-method types, fun interface + SAM conversions are handy; mark small higher-order helpers inline to avoid allocations and (when appropriate) to enable non-local returns. Also watch closures: lambdas capture variables by reference, so avoid capturing large or mutable state in long-lived callbacks. Examples and behavior are in the fun interface and inline guides. (kotlinlang.org)

(Short troubleshooting tip: if a return compiler error appears inside a lambda, try switching to return@label or an anonymous function — this fixes most cases quickly, which is why replies like ’s often get resolved by that change.)

Klint 0 Newbie Poster

Thanks a lot for information! Was searching it to fix my prob.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.