Idiomatic Kotlin: Local functions

Tompee Balauag
Familiar Android
Published in
3 min readJul 9, 2018
“Bars and stores in a narrow alley in Victoria in the evening” by Tj Holowaychuk on Unsplash

This article is a part of the Idiomatic Kotlin series. The complete list is at the bottom of the article.

In this article, we will be talking about local functions and how we can use it in conjunction with Extension functions.

What is a local function?

A local function is a function within a function. Yes you heard that right. It is a function scoped within another function. It is another way to achieve code reuse.

Motivation

Reusable sequences of code are often times extracted to another function to achieve reusability. However, this approach could easily end you up with a class littered with small functions with no clear relationship between each other. Grouping these functions could also net you a lot of boilerplate code. Wouldn’t it be nice to extract these functions and scope them to the function that requires them to make relationships clear without any boilerplate code?

How to create a local function?

Creating a local function is as simple as declaring a variable but this time with the fun keyword.

Local functions must be declared first before they are referenced. Think of it as declaring a variable first before using it. Local functions can also reference the variables local to the function. Let’s see how it is done under the hood.

Local functions under the hood

Let us decompile the above source code.

The local variables are converted to a Ref type available in the kotlin JVM. This allows you to somehow pass (or access) by reference. This feature is called capturing. It allows you to modify non-final variables by wrapping it in a reference. Let’s take a look at where the magic happens.

The local function is represented as a Function object and is called via a method invoke. If you are familiar with functional interfaces, higher-order functions and lambda expressions, then you can say that this is the pre-Java 8 way of achieving those.

Performance overhead

There are things to consider when using local functions. Some are pretty negligible but it is good to know them.

First on the list is the added classes and objects. A function, depending on how it is declared, can be instantiated (or define a class) as many as there are calls to it.

Another overhead is the added function count. A Function adds more than a direct private function definition towards the DEX function count, which makes you closer to the limit (when working with Android). Kotlin has a nice feature to minimize this called inlining but it does not apply to local functions. Inline will be discussed in a future article.

Use with extension function

Local functions can be converted to an extension function. Let us use the code above as an example.

A credential class is created to wrap username and password. Then, a validate function is created as an extension function to validate the credential object. This is useful in cases wherein you do not want to pollute the data class with private functions only a the login package will use.

Check out the other articles in the idiomatic kotlin series. The sample source code for each article can be found here in Github.

  1. Extension Functions
  2. Sealed Classes
  3. Infix Functions
  4. Class Delegation
  5. Local functions
  6. Object and Singleton
  7. Sequences
  8. Lambdas and SAM constructors
  9. Lambdas with Receiver and DSL
  10. Elvis operator
  11. Property Delegates and Lazy
  12. Higher-order functions and Function Types
  13. Inline functions
  14. Lambdas and Control Flows
  15. Reified Parameters
  16. Noinline and Crossinline
  17. Variance
  18. Annotations and Reflection
  19. Annotation Processor and Code Generation

--

--