avatarGabriel Shanahan

Summary

The provided web content discusses advanced Kotlin programming concepts, including function types, literals, higher-order functions, closures, lexical scope, and the differences between anonymous functions and lambdas.

Abstract

The article delves into Kotlin's treatment of functions as first-class citizens, allowing them to be assigned to variables, passed as arguments, and returned from other functions. It explains function types, such as (Int, String) -> String, and introduces two types of function literals: anonymous functions and lambda functions. The text highlights Kotlin's support for closures, where functions can access variables from their lexical scope. It also clarifies the syntax and use cases for anonymous functions and lambdas, noting that while lambdas are more concise, anonymous functions allow for explicit return type specification when necessary. The article is part of the "Kotlin Primer" series, aimed at facilitating Kotlin adoption in Java-centric organizations, and includes practical examples and exercises for readers to understand and apply these concepts.

Opinions

  • The author suggests that the advanced code examples may be "hardcore" for those not accustomed to this style of programming, implying that while these techniques are powerful, they may not be essential for all Kotlin developers.
  • The inclusion of "hardcore bits" is justified for educational purposes, to demonstrate the language's capabilities and syntax, and to offer challenging exercises for those wishing to deepen their understanding.
  • The article expresses that in most cases, the type of the result in lambdas is inferred, and explicit return type specification is rarely needed, which simplifies the code.
  • The author acknowledges that the distinction between anonymous functions and lambdas exists partly due to Kotlin's support for non-local returns and return-at-labels, features that may be rarely used but are important to be aware of.
  • There is an appreciation for Kotlin's inline functions and the ability to reference functions using ::, which is mentioned as a useful feature for function literals.
  • The article encourages the reader to engage with the provided exercises to practice the concepts discussed, indicating a pedagogical approach to learning Kotlin.
  • The author thanks Etnetera a.s. for their support and expresses gratitude for the opportunity to write the Kotlin Primer as an organizational learning resource.

Function Types & Literals

Higher order functions, function types, function literals, anonymous functions, lambdas, closures, lexical scope, function references and comparing anonymous functions vs. lambdas

— — — — — — — — — — — — — — —

THE CURRENT VERSION OF THIS ARTICLE IS PUBLISHED HERE.

— — — — — — — — — — — — — — —

Tags: #FYI++ #EXERCISE

This article is part of the Kotlin Primer, an opinionated guide to the Kotlin language, which is indented to help facilitate Kotlin adoption inside Java-centric organizations. It was originally written as an organizational learning resource for Etnetera a.s. and I would like to express my sincere gratitude for their support.

It is recommended to read the Introduction before moving on. Check out the Table of Contents for all articles.

In Kotlin, functions are first-class, which means they can be treated the same way as any other value type.

This means:

  • They can be assigned to variables
  • They can be passed as arguments to, and returned from, other functions. Functions accepting or returning other functions are called higher-order functions
  • They have a type

Function types are denoted using e.g.(Int, String) -> String. If a function does not return a value, which is the same as saying it returns Unit, the type is e.g. (Int, String) -> Unit.

If a function does not accept parameters, it’s type is e.g. () -> String.

The function type can be instantiated using two different literals:

  • the anonymous function
  • the lambda function

Kotlin has closures, same as Java — a function can access the lexical scope it was defined it. It’s easier to understand when demonstrated:

Now, we’ll be honest — some of the stuff in the following examples can be a little hardcore for people who are not versed in this style of writing code. It is by no means necessary to be able to write this kind of code to be able to use Kotlin, although you can build some really amazing stuff using these techniques.

In any case, we include these hardcore bits for educational purposes, to show what can be done, what the syntax permits, and offer it as a voluntary exercise to those who wish to stretch their brain-muscles a bit. Keep in mind, the easy stuff is all you really need to know.

Anonymous functions

Anonymous functions are written in the same way as normal function definitions are, but without the name.

Lambda functions

  • Lambda functions are written as a pair of curly braces. Parameters are placed after the opening brace, separated by a comma (with optional types) and followed by ->
  • The last expression in a lambda is returned. Lambda’s can span multiple lines.
  • If a lambda only has a single parameter, the parameter list can be omitted, and the parameter referenced by the name it
  • When passing a lambda as the last argument to a function, the lambda is moved outside the function call. This sentence will probably make no sense when you read it, so just see the examples bellow.

Referencing functions

Function literals are referenced by the name of the variable they were assigned to.

Functions or methods that were defined by a statement can be referenced using ::.

Anonymous functions vs lambdas

You might be asking why Kotlin has two ways of declaring a function literal. The main reason is that, while the syntax of lambdas is more lightweight, it does not easily permit specifying the return type (basically the only thing you can do is an explicit cast). In 99% of the cases, this is not needed, since the type of the result is inferred, but in the small number of cases where that isn’t possible, you can use anonymous functions which allow you to specify the return type, as seen above.

There is another reason that has to do with non-local returns and return-at-labels. We think it is a good idea to be aware that things like that exist, but we don’t think you’ll be needing it very often. If you ever do, come back and study this more thoroughly.

Exercises

Anonymous functions

Implement the following as anonymous functions (not lambdas!).

Lambda functions

Implement the following as lambdas (not anonymous functions!)

Go back to Literals, jump to the Table of Contents, or continue to Inline Functions.

Join me in Etnetera
Kotlin
Java
Lambda
Programming
Higher Order Function
Recommended from ReadMedium