Tag: functional

Coping with Kotlin’s Scope Functions: let, run, also, apply, with

Coping with Kotlin’s Scope Functions: let, run, also, apply, with

Kotlin Scope Functions

Functions in Kotlin are very important and it’s much fun() to use them. One special collection of relevant functions can be described as “Kotlin Scope Functions” and they are part of the Kotlin standard library: let, run, also, apply and with.
You probably already heard about them and it’s also likely that you even used some of them yet. Most people tend to have problems distinguishing all those functions, which is not very remarkable in view of the fact that their names may be a bit confusing. This post intends to demonstrate the differences between the available scope functions and also wants to discuss relevant use cases. Finally, an example will show how to apply scope functions and how they help to structure Kotlin code in a more idiomatic way.

Disclaimer: The topic of scope functions is under consideration in various StackOverflow posts very often, which I will occasionally refer to throughout this article.

The Importance of Functions

In Kotlin, functions are as important as integers or strings. Functions can exist on the same level as classes, may be assigned to variables and can also be passed to/returned from other functions. Kotlin makes functions “first-class citizens” of the language, which Wikipedia describes as follows:

A first-class citizen […] is an entity which supports all the operations generally available to other entities. These operations typically include being passed as an argument, returned from a function, modified, and assigned to a variable.

As already said, functions are as powerful and significant as any other type, e.g. Int. In addition to that, functions may appear as “higher-order functions”, which in turn is described as the following on Wikipedia:

In mathematics and computer science, a higher-order function (also functional, functional form or functor) is a function that does at least one of the following:
takes one or more functions as arguments (i.e., procedural parameters),
– returns a function as its result.

The boldly printed bullet point is the more important one for the present article since scope functions also act as higher-order functions that take other functions as their argument. Before we dive into this further, let’s observe a simple example of higher-order functions.

Higher-Order Function in Action

A simple higher-order function that’s commonly known in Kotlin is called repeat and it’s defined in the standard library:

As you can see, repeat takes two arguments: An ordinary integer times and also another function of type (Int) -> Unit. According to the previously depicted definition, repeat is a higher-order function since it “takes one or more functions as arguments”. In its implementation, the function simply invokes action as often as times indicates. Let’s see how repeat can be called from a client’s point of view:

In Kotlin, lambdas can be lifted out of the parentheses of a function call if they act as the last argument to the function.

Note that if a function takes another function as the last parameter, the lambda expression argument can be passed outside the parenthesized argument list.

The official documentation is very clear about all lambda features and I highly recommend to study it.

In the shown snippet, a regular lambda, which only prints the current repetition to the console, is passed to repeat. That’s how higher-order function calls look like.

Function Literal with Receiver

Kotlin promotes yet another very important concept that makes functions even more powerful. If you’ve ever seen internal domain specific languages (DSL) in action, you might have wondered how they are implemented. The most relevant concept to understand is called function literal with receiver (also lambda with receiver). Since this feature is also vital for scope functions, it will be discussed next.

Function literals with receiver are often used in combination with higher-order functions. As shown earlier, functions can be made parameters of other functions, which happens by defining parameters with the function type syntax (In) -> Out. Now imagine that these function types can even be boosted by adding a receiver: Receiver.(In) -> Out. Such types are called function literal with receiver and are best understood if visualized as “temporary extension functions”. Take the following example:

The function createString can be called a higher-order function as it takes another function block as its argument. This argument is defined as a function literal with receiver type. Now, let’s think of it as an extension function defined for StringBuilder that will be passed to the createString function. Clients will hand on arbitrary functions with the signature () -> Unit, which will be callable on instances of StringBuilder. That’s also shown in the implementation: An instance of StringBuilder is being created and block gets invoked on it. Eventually, the method transforms StringBuilder to an ordinaryString` and to the caller.

What does that mean for the client of such a method? How can you create and pass function literals with receiver to other functions? Since the receiver is defined as StringBuilder, a client will be able to pass lambdas to createString that make use of that receiver. The receiver is exposed as this inside the lambda, which means that clients can access visible members (properties, functions etc.) without additional qualifiers:

The example shows that append, a function defined for the receiver StringBuilder, is being invoked without any qualifiers (e.g. it). The same is possible in the definition of extension functions, which is why I used it as an analogy earlier. The client defines a temporary extension function which gets invoked on the corresponding receiver within createString afterward. For another description of the concept, please consult the associated documentation. I also tried to answer a related StackOverflow question a while ago.

Kotlin Scope Functions

Scope functions make use of the concepts described above. They are defined as higher-order functions, i.e. they take another function as their argument. These arguments may even appear as function literals with receiver in certain cases. Scope functions take an arbitrary object, the context object, and bring it to another scope. In that scope, the context object is either accessible as it (or custom name) or this, depending on the type of function. In the following, the functions let, run, also, apply and with will be introduced and explained.

[let]

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/let.html

One of the most famous scope functions is certainly let. It’s inspired by functional programming languages like Haskell and is used quite often in the Kotlin language, too. Let’s inspect its signature:

  • Defined as an extension on T, the receiver/context object
  • Generic type R defines the function’s return value
  • Result R of block will be the result of let itself, i.e. it can be an arbitrary value
  • block argument with regular function type (T) -> R
  • Receiver T is passed as argument to block

Use Cases

a. Idiomatic replacement for if (object != null) blocks

As you can read in the Kotlin Idioms section, let is supposed to be used to execute blocks if a certain object is not null.

The nullable text variable is brought into a new scope by let if it isn’t null. Its value then gets mapped to its length. Otherwise, the null value is mapped to a default length 0 with the help of the Elvis operator. As you can see, the context object text gets exposed as it inside let, which is the default implicit name for single parameters of a lambda.

b. Map nullable value if not null

The let function is also often used for transformations, especially in combination with nullable types again, which is also defined as an idiom.

c. Confine scope of variable/computation

If a certain variable or computation is supposed to be available only in a confined scope and should not pollute the outer scope, let again can be helpful:

The shown string "stringConfinedToLetScope" is made the context object of let, which uses the value for some simple transformation that is returned as the result of let. The outer scope only uses the transformed value and does not access the temporarily needed string. There’s no variable polluting the outer scope due to confining it to the relevant scope.

[run]

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/run.html

As an alternative to let, the run function makes use of a function literal with receiver as used for the block parameter. Let’s inspect its signature:

  • Defined as an extension on T, the receiver/context object
  • Generic type R defines the function’s return value
  • Result R of block will be the result of run itself, i.e. it can be an arbitrary value
  • block argument defined as function literal with receiver T.() -> R

The run function is like let except how block is defined.

Use Cases

run can basically serve the same use cases as let, whereas the receiver T is exposed as this inside the lambda argument:

a. Idiomatic replacement for if (object != null) blocks

b. Transformation

It’s also good to use run for transformations. The following shows an example that is even more readable than with let since it accesses the context object’s functions without qualifiers:

[also]

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/also.html

The also function is the scope function that got lastly added to the Kotlin language, which happened in version 1.1. Let’s inspect its signature:

  • Defined as an extension on T, the receiver/context object
  • Returns the receiver object T
  • block argument with regular function type (T) -> Unit
  • Receiver T is passed as argument to block

also looks like let, except that it returns the receiver T as its result.

Use Cases

a. Receiver not used inside the block

It might be desired to do some tasks related to the context object but without actually using it inside the lambda argument. An example can be logging. As described in the official Kotlin coding conventions, using also is the recommended way to solve scenarios like the one shown next:

In this case, the code almost reads like a normal sentence: Assign something to the variable and also log to the console.

b. Initializing an object

Another very common scenario that can be solved with also is the initialization of objects. As opposed to the two previously introduced scope functions, let and run, also returns the receiver object after the block execution. This fact can be very handy:

As shown, a Bar instance is created and also is utilized in order to directly initialize one of the instance’s properties. Since also returns the receiver object itself, the expression can directly be assigned to a variable of type Bar.

c. Assignment of calculated values to fields

The fact that also returns the receiver object after its execution can also be useful to assign calculated values to fields, as shown here:

A value is being calculated, which is assigned to a field with the help of also. Since also returns that calculated value, it can even be made the direct inline result of the surrounding function.

[apply]

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/apply.html

The apply function is another scope function that was added because the community asked for it. Its main use case is the initialization of objects, similar to what also does. The difference will be shown next. Let’s inspect its signature first:

  • Defined as an extension on T, the receiver/context object
  • Returns the receiver object T
  • block argument defined as function literal with receiver T.() -> R

The relation between apply and also is the same as between let and run: Regular lambda vs. Function literal with receiver parameter:

Relation (`apply`,`also`) == Relation (`run`,`let`)

Use Cases

a. Initializing an object

The ultimate use case for apply is object initialization. The community actually asked for this function in relatively late stage of the language. You can find the corresponding feature request here.

Although also was already shown as a tool for solving these scenarios, it’s obvious that apply has a big advantage: There’s no need to use “it” as a qualifier since the context object, the Bar instance in this case, is exposed as this. The difference got answered in this StackOverflow post.

b. Builder-style usage of methods that return Unit

As described in the Kotlin Idioms section, apply can be used for wrapping methods that would normally result in Unit responses.

In the example, apply is used to wrap simple property assignments that would usually simply result in Unit. Since the class wants to expose a builder-style API to the client, this approach is very useful as the setter-like methods return the surrounding object itself.

[with]

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/with.html

The with function is the last scope function that will be discussed here. It’s a very common feature in many even older languages like Visual Basic and Delphi.
It varies from the other four functions in that it is not defined as an extension function. Let’s inspect its signature:

  • Defined as an independent function that takes a receiver/context object T as its first argument
  • Result R of block will be the result of with itself, i.e. it can be an arbitrary value
  • block argument defined as function literal with receiver T.() -> R

This function aligns with let and run in regards to its return value R. It’s often said to be similar to apply; the difference got described here. Another simple description of with can be found here (both StackOverflow).

Use Cases

a. Working with an object in a confined scope

Also defined as an idiom, with is supposed to be used when an object is only needed in a certain confined scope.

The StringBuilder passed to with is only acting as an intermediate instance that helps in creating the more relevant String that gets created in with. It’s obvious that with is utilized for wrapping the calls to StringBuilder without exposing the instance itself to the outer scope.

b. Using member extensions of a class

Extension functions are usually defined on package level so that they can be imported and accessed from anywhere else with ease. It’s also possible to define these on class or object level, which is then called a “member extension function”. These kinds of extension functions can easily be used inside that class but not from outside. In order to make them accessible from anywhere outside the enclosing class, that class has to be brought “into scope”. The with function is very useful here:

The shown object Foo defines a sweet member extension function random(), which can be used only in the scope of that object. With the help of with, this can easily be achieved. Note that this strategy is especially recommendable if particular extension functions are to be grouped meaningfully.

Comparison and Overview

After the five different scope functions have been discussed, it’s necessary to see them all next to each other:

The scope functions also and apply both return the receiver object after their execution. In apply, the block parameter is defined as a function literal with receiver and T gets exposed as this, whereas in also, it’s a regular function type and T gets exposed as it.

The scope functions let and run on the other hand both return an arbitrary result R, i.e. the result of the block itself. Again, run works with a function literal with receiver, whereas let uses the simple function type.

Last but not least, with is kind of a misfit amongst the scope functions since it’s not defined as an extension on T. It defines two parameters, one of which represents the receiver object of this scope function. Same as apply and run, with works with function literal with receiver.

returns receiver objectreturns arbitrary result
exposed as `it``also``let`
exposed as `this``apply``run` & `with`1

1Not an extension.

IDE Support

As of version 1.2.30, the IntelliJ IDEA Kotlin plugin offers intentions that can convert between let and run and also between also and apply calls. Read more about it here.

Example: Requesting a REST API

In this section, I’m going to show an example that applies the previously discussed scope functions on a pretty basic use case: Calling an HTTP REST endpoint. The goal is to provide functionality for requesting information about contributors of the jetbrains/kotlin GitHub project. Therefore we define the appropriate GitHub endpoint and a simplified representation of a Contributor that is annotated for Jackson:

The following shows the code that provides the desired functionality in its initial form:

The depicted snippet shows a singleton object GitHubApiCaller with an OkHttpClient (OkHttp), a Jackson mapper and a simple Map that’s used for caching results. The code of getKotlinContributor can be decomposed into the following sub-tasks:
* When the result is already cached, return it immediately and skip the rest
* Create a request object using the ENDPOINT
* Get the response by executing the request on the client
* Extract the JSON data from the response object (Error handling omitted)
* De-serialize the JSON to an Array
* Filter for the contributor that is searched for
* Cache the result and return it to the client

In my opinion, this code is very comprehensive and everybody is able to make use of it. Nevertheless, it can be taken as a good basis for a little refactoring.

Reviewing the Code

Let’s now try to find some appropriate use cases for scope functions in the previously shown function.

Refactoring No. 1

The first thing that we can improve is the if block in the very beginning:

As shown earlier, the let function is normally used for resolving these kinds of if blocks. Applied to the concrete example, we get the following:

The problem here is that let is defined with a generic return type R so that the it needs to be written at the end in order to make it the return value of the expression. Another obvious insufficiency is the missing else statement. The first problem can be addressed pretty easily. We just need to use a scope function that returns its receiver, i.e. the cached result, directly from the block. Additionally, it should still expose the receiver as it, which makes also the best suitable candidate:

The Elvis operator, shown before, is very often used for handling the else case, i.e. when the receiver is null. In order to make the code more readable, a private function requestContributor now handles the cache miss.

That’s it, the if block was replaced with an easy also invocation. A more idiomatic solution.

Refactoring No. 2

The next portion that is worth reconsidering contains an unnecessary local variable that represents the request object:

It’s literally only used for getting a response object from the client and could therefore simply be inlined. Alternatively, the shown actions can be thought of as a basic transformation, which we learned to express with the let function:

The request has been made the context object of let and directly gets executed in a straightforward transformation. It makes the local request variable obsolete without affecting readability negatively.

Refactoring No. 3

The following snippet points at another if (obj != null) block, which in this case can actually be solved with let:

Again, the Elvis operator handles the null scenario very nicely.

Refactoring No. 4

Moving on to the next two statements of the code, we observe that the responseAsString variable is being logged and finally used for the Jackson de-serialization. Let‘s group them together:

Refactoring No. 5

After the first few refactorings, the situation looks as follows: We have a response, a responseAsString and a contributors variable and still need to filter the Contributors for the desired entry. Basically, the whole requesting and response handling is not relevant for the last step of filtering and caching. We can smoothly group these calls and confine them to their own scope. Since these actions happen with the help of the OkHttpClient, it makes sense to make the client the context object of that scope:

There isn’t any new code here, the previous edits have simply be wrapped in a call of with and are therefore not visible to the surrounding scope (function requestContributors) anymore. It made sense to use with in this case since it exposes client as this and the newCall invocation can therefore omit its qualifier. As described earlier, with can have an arbitrary result R. In this case, the last statement inside the lambda, the result of the last let call, becomes that R.

Refactoring No. 6

Now a single variable contributors is available in the outer scope and we can apply the filtering:

The previous version of the above code consisted of four independent statements that are now grouped in a simple also call with the filtered Contributor as its receiver. That receiver is put in the cache and also logged for debugging purposes. Of course, since also returns its receiver directly, the whole statement can be made the return of the function.

The entire function looks like this:

In my opinion, the code looks very well structured and still readable. Yet, I don’t want to encourage the readers to apply scope functions in every situation after reading this article. It’s very important to know that this set of functions is so powerful that they could even be used to chain an unlimited amount of expressions and make them a single expression. You don’t want to do that because it messes up the code very quickly. Try to find a balance here and don’t apply scope functions everywhere.

Conclusion

In this article, I discussed the powerful set of scope functions of the Kotlin standard library. Many situations can be solved in a very idiomatic way with the help of these functions and it’s vital to have a rough idea of the differences between them. Try to memorize that there are scope functions that can return arbitrary values (let, run, with) and those that return the receiver itself (apply, also). Then there are functions, which expose their receiver as it (let, also) and others, which expose their receiver as this (run, apply, with). The concluding example demonstrated how easily scope functions may be used for refactoring appropriate code sections according to the earlier learned concepts. You shouldn’t get the impression that every single opportunity should actually be embraced; it’s still necessary to reason about the application of scope functions. Also, you shouldn’t try to use all of the shown functions at any price since most of them can be used interchangeably sometimes. Try to find your own favorites 🙂

You can find the shown code examples in this GitHub Repo.

Feel free to contact me and follow on Twitter. Also, check out my Getting Started With Kotlin cheat sheet here.

If you want to read more about Kotlin’s beautiful features I highly recommend the book Kotlin in Action and my other articles to you.

Simon is a software engineer based in Germany with 7 years of experience writing code for the JVM and also with JavaScript. He’s very passionate about learning new things as often as possible and a self-appointed Kotlin enthusiast.

Please follow and like this Blog 🙂
Kotlin Features I miss most in Java – Kotlin vs Java

Kotlin Features I miss most in Java – Kotlin vs Java

Let’s write an article that covers “Kotlin vs Java” topics – I want to tell you which Kotlin features I miss most when going back to Java.

My Life as a Java Dev

Although I’m a big supporter of the Kotlin programming language, I still do a lot of Java programming on a daily basis for my employer. Since I’m aware of the great functionalities of Kotlin, I’m often struggling with Java as it has some “pitfalls”, requires additional boilerplate and misses many features.
In this post, I’d like to describe which Kotlin features I miss most when coding in Java.

new and Semicolon

Ever since I’m doing Kotlin, there are two things I always forget when coding in Java: the new keyword for constructor invocations and the annoying ; to complete statements. Kotlin doesn’t have new and even semicolons are optional. I really appreciate this decision because it reduces the “syntactic noise“.

Data classes

In Kotlin, data classes are used for simple data containers, representing JSON objects or returning compound objects from functions amongst other use cases. Of course, Java doesn’t support this special type of classes yet. As a result, I often have to implement my own data class, which means a lot of boilerplate in Java.

One special use case is compound objects returned from functions. For example, let’s imagine a function that needs to return two objects. In Kotlin we could use a data class, or simpler, a Pair directly. In Java, I tend to create a value object, which is a class with several final fields, each of which instantiated through the constructor. Similar to Kotlin, I don’t implement getters and setters, but use the class’s fields directly as public properties. Unfortunately, this is not what we learned as best practice and most Java code style checkers will complain about it. I do not see any encapsulation issues here and it’s the least verbose approach in Java. The following shows such a compound object, the inner class Multi. In Kotlin this would be a one-liner.

public class MultiReturn {

    public static void main(String[] args) {
        new MultiReturn().useMulti();
    }

    public void useMulti() {
        Multi multi = helper();
        System.out.println("Multi with " + multi.count + " and " + multi.name);
    }

    private Multi helper() {
        return new Multi(2, "test");
    }
    
    private static class Multi {
        private final int count;
        private final String name;

        public Multi(int count, String name) {
            this.count = count;
            this.name = name;
        }
    }
}

Local Functions

In many situations, we tend to create private methods that are only used inside another single method in order to make this one more readable. In Kotlin, we can use local functions, i.e. functions inside functions (inside functions…), which enables some kind of scope. For me, this is a much cleaner approach, because the function is only accessible inside the function that actually uses the local one. Let’s look at an example.


fun deployVerticles() {

    fun deploy(verticleClassName: String) {
        vertx.deployVerticle(verticleClassName, opt, { deploy ->
            LOG.info("$verticleClassName has been deployed? ${deploy.succeeded()}")
        })
    }

    deploy("ServiceVerticle")
    deploy("WebVerticle")
}

It’s taken from a sample vert.x application and defines a local function that is reused twice afterward. A great way to simplify your code.

Single Expression Functions

We can create single expression functions in Kotlin, i.e. functions without an actual body. Whenever a function contains only a single expression, it can be placed after a = sign following the function declaration:


fun trueOrFalse() = Random().nextBoolean()

In Java, on the other hand, we always have to use a function body enclosed in {}, which ranges over at least three lines. This is also “syntactic noise” I don’t want to see anymore. To be fair, Java 1.8 makes it possible to define lambdas which can also solve this, less readable though (Can also be applied to local functions):


public class SingleExpFun {

    private BooleanSupplier trueOrFalse = new Random()::nextBoolean;

    private boolean getNext(){
        return trueOrFalse.getAsBoolean();
    }
}

Default Parameters

One very annoying part of Java is the way methods have to be overloaded. Let’s see an example:

public class Overloade
    public static void main(String[] args) {
        Overloader o = new Overloader();
        o.testWithoutPrint(2);
        o.test(2);
    }

    public void test(int a, boolean printToConsole) {
        if (printToConsole) System.out.println("int a: " + a);
    }

    public void testWithoutPrint(int a) {
        test(a, false);
    }

    public void test(int a) {
        test(a, true);
    }

}

We can see a class with a method test(int, boolean) that is overloaded for the default case and also a convenience method is available. For more complex examples, it can lead to a lot of redundant code, which is simpler in Kotlin by using default parameters.


fun test(a: Int, printToConsole: Boolean = true) {
    if (printToConsole) println("int a: " + a)
}

fun testWithoutPrint(a: Int) = test(a, false)

fun main(args: Array) {
    testWithoutPrint(2)
    test(2)
}

Calling multiple methods on an object instance (with)

Obviously, Kotlin is more functional than Java. It makes use of higher-order functions in incredibly many situations and provides many standard library functions that can be used as such. One of my favorites is with, which I miss a lot whenever I can’t use Kotlin. The with function can be used to create scopes that actually increase the readability of code. It’s always useful when you sequentially call multiple functions on a single object.


class Turtle {
    fun penDown()
    fun penUp()
    fun turn(degrees: Double)
    fun forward(pixels: Double)
}

with(Turtle()) {
    penDown()
    for(i in 1..4) {
        forward(100.0)
        turn(90.0)
    }
    penUp()
}

The great thing is the usage of lambdas with receiver, which you can read about in one of my other posts.

Null-Safety

Whenever I work with nullable types since the time I started with Kotlin, I actually miss the type system’s tools to prevent null-related errors. Kotlin did a very good job by distinguishing nullable types from not-nullable ones. If you strictly make use of these tools, there is no chance you’ll ever see a NullpointerException at runtime.

Lambdas and Collection Processing

Kotlin places a lot of value on its lambdas. As shown in the with example earlier, there’s special syntax available for lambdas that makes its usage even more powerful. I want to underline that the way functions and especially lambdas are treated in the language makes it dramatically superior to Java. Let’s see a simple example of Java’s Streams, which were introduced along with lambdas in Java 1.8:

List list = people.stream().map(Person::getName).collect(Collectors.toList());

It’s a rather simple example of a Stream that is used to get a list of names from a list of persons. Compared to what we did before 1.8, this is awesome. Still, it’s too noisy compared to a real functional approach as pursued by Kotlin:

val list = people.map { it.name }

Or yet another example, in which salaries of employees are summed up to a total amount:

int total = employees.stream()
                      .collect(Collectors.summingInt(Employee::getSalary)));

So much simpler in Kotlin:

val total = employees.sumBy { it.salary }

The Kotlin examples show how simple it can be. Java isn’t a functional language and has a hard time trying to adopt functional features like lambdas and streams as we can easily observe in the snippets. It really sucks to go back to Java, if you ever experienced the beauty of Kotlin. Have you ever tried to use Eclipse after being familiar with IntelliJ? You know what I mean then.

Wrap-up

In this short post, I presented you my top Kotlin features I always miss when coding in Java. It’s just a selection of things, which will hopefully find their way into the Java language soon. But to be honest, there’s no reason to always wait for Java, when there already is a much sweeter language available… I want to point out, that starting with Kotlin really made me a much better programmer because I began wondering about certain features in both languages and also try to find ways to use Kotlin-dedicated things in Java by finding workarounds like arranging my code differently.

I’d be interested in the features you like most, feel free to comment.
Also, if you like, have a look at my Twitter account and follow if you’re interested in more Kotlin stuff 🙂 Thanks a lot.

If you want to read more about Kotlin’s beautiful features I recommend the book Kotlin in Action and my other articles to you.

Simon is a software engineer based in Germany with 7 years of experience writing code for the JVM and also with JavaScript. He’s very passionate about learning new things as often as possible and a self-appointed Kotlin enthusiast.

Please follow and like this Blog 🙂
Spring WebFlux with Kotlin – Reactive Web

Spring WebFlux with Kotlin – Reactive Web

Spring 5.0 – even fancier

In this article I will show how Spring and Kotlin can be used together. If you’re not familiar with my recent articles, have a look at the other Kotlin related posts here. Besides Kotlin, I’ve always been interested in working with Spring ever since I started with Java back in 2011. I still like the framework although it’s getting bigger and bigger and you often don’t quite know which feature to choose amongst all the alternatives. As the framework itself is growing, the documentation, which is one of best you’ll ever get to see, also is.

The thing I like most about Spring is that you can focus on your business logic from day one and don’t have much technical, infrastructural stuff to set up before kicking off. Spring does that by encapsulating a lot of boilerplate that’s necessary for certain tasks and provides simple annotations we can apply in order to make use of these features. One of the most famous modules certainly is Spring Web MVC, which is widely used whenever it comes to web services on the JVM.

Reactive Programming – The non-blocking way

You might have noticed that Reactive Programming is getting more attention recently. There are many frameworks emerging that want to encourage this style of programming, namely RxJava, Vert.X or Akka for example. If you’ve never come across these, you can read my post on Kotlin with Vert.X as a first step.

Spring reactive

What does this have to do with Spring though? Well, of course, there’s yet another library for building reactive systems, which in fact is powered by Spring: [Project Reactor] https://projectreactor.io). Reactor is used in the current Spring Release 5.0, available since September 2017, which introduces a reactive web framework called WebFlux.
This fact on its own is a good reason for me to dive into it as it sounds fairly fantastic knowing Web MVC as Spring’s outstanding module already. But, there’s yet another great reason to take this expansion into account: Spring is greatly supporting Kotlin and even introduced Kotlin dedicated features with the recent major release 🙂 This was achieved by making use of extension functions in order to extend existing APIs and also by introducing Kotlin DSLs, a feature you can read about in my post on creating a DSL with Kotlin. One of these new DSLs goes hand in hand with Spring WebFlux: A functional DSL for describing the WebFlux-backed web service. This, in fact, is what I am going to present to you in a very short example up next…

WebFlux and Kotlin in Action

Let’s have a look at a very basic application using Spring WebFlux in a Kotlin application. The initial setup can easily be downloaded as a SpringBoot application from Spring Initializr, if you choose Kotlin as the programming language and also enable the “Reactive Web” dependency, which is available since SpringBoot 2.0.0.

spring boot initilizr

As soon as we’ve imported this project into our IDE, we can start with creating a reactive web service. For the sake of brevity, I chose a very simple, not very useful, example: An internally managed repository of simple Strings that is populated through the web interface and also is searchable from it. Thanks to Kotlin and also Spring, there’s not much code that has to be written:

Repo and Handler

@Component
class ReactiveHandler(val repo: StringRepo) {
    fun getText(search: String): Mono<String> =
        repo.get(search).toMono().map { "Result: $it!" }
    fun addText(text: String): Mono<String> =
        repo.add(text).toMono().map { "Result: $it!" }
    fun getAllTexts(): Flux<String> =
        repo.getAll().toFlux().map { "Result: $it" }
}

@Component
class StringRepo {
    private val entities = mutableListOf<String>()
    fun add(s: String) = entities.add(s)
    fun get(s: String) = entities.find { it == s } ?: "not found!"
    fun getAll() = listOf(entities)
}

We simply create a repository that maintains a list of Strings and another class ReactiveHandler, which is responsible for delegating to the repository and providing “reactive types” defined in Reactor. These are mandatory for WebFlux: Flux and Mono (Read about them here). Regardless of their intention, have a look at how they are created: toMono() and toFlux() are examples of extension functions added in Spring 5.0, a feature dedicated to Kotlin. The much more interesting part though is where the web routing is defined. This part in particular is where the already mentioned functional DSL comes into play. Let’s observe how it works.

Functional WebFlux DSL.

@Configuration
class RoutingConfiguration {

    @Bean
    fun routerFunction(handler: ReactiveHandler): RouterFunction<ServerResponse> = router {
        ("/reactive").nest {
            val searchPathName = "search"
            val savePathName = "save"
            GET("/{$searchPathName}") { req ->
                val pathVar = req.pathVariable(searchPathName)
                ServerResponse.ok().body(
                        handler.getText(pathVar)
                )
            }
            GET("/") {
                ServerResponse.ok().body(handler.getAllTexts())
            }
            PUT("/{$savePathName}") { req ->
                val pathVar = req.pathVariable(savePathName)
                ServerResponse.ok().body(
                        handler.addText(pathVar)
                )
            }
        }
    }
}

The router function is the entry point of the new DSL, which can be inspected on GitHub. The shown solution is just one out of many since the DSL provides more ways you can choose from. With my definition, the server starts a web service under “/reactive” and accepts two GET and one PUT request, each of which is delegated to the previously shown ReactiveHandler (see method parameter) before the results are put into a ServerResponse. Of course, you’d have to handle errors in a real-world scenario and “ok” wouldn’t be the only response.

Benefit

If you ask me, this approach is very clean structured and even provides the opportunity of using any Kotlin code for defining variables, loops, conditions, whatsoever inside the actual DSL code. Given that, you have a very powerful tool that can be utilized in a very natural programmatic way.

If your like to check this out, the code is available in this GitHub repository.

Wrap-up and Perspective

I’ve presented a small project that’s making use of Spring 5.0 and its new module WebFlux in combination with Kotlin. I think, the fact, that Spring officially uses and supports Kotlin is a very important one, I’d like to emphasize once again.

Kotlin – It’s not only Android!

We all know that Kotlin made its way into Android, which was possible because Google announced the official support a few months ago. On the server-side though, people and especially companies hesitate when it comes to Kotlin. They tend to have doubts as to whether Kotlin’s really mature enough already.
When you ask me, there’s no good reason for hesitation. Many projects use Kotlin already, frameworks support Kotlin and even extend their libraries with dedicated Kotlin features. Spring, as one of the most common Java frameworks, seems to think the same as they quickly adopted Kotlin as an alternative to Java and Groovy for SpringBoot applications. The most recent developments, which are part of Spring 5.0, are the next step, some of which we’ve observed in this little article. If you’re, same as me, interested in spreading Kotlin as an alternative to Java, talk about it and tell your colleagues about Spring’s support and what’s actually
happening 😉

Special Thanks

As you can read in this article, Spring’s introducing quite a few Kotlin features. There’s one guy, Sébastien Deleuze, who’s highly responsible for this development in the Spring Framework. He has also been a guest on talkingkotlin
already. It’s really great to have such influencers in the Kotlin community, many thanks! Keep up the great work.

If you like to have a look at my examples, the code is available here:
Git. Feel free to give any feedback, I’m always happy to help. Also, if you like, have a look at my Twitter account and follow if you’re interested in more Kotlin stuff 🙂 Thanks a lot.

Simon is a software engineer based in Germany with 7 years of experience writing code for the JVM and also with JavaScript. He’s very passionate about learning new things as often as possible and a self-appointed Kotlin enthusiast.

Please follow and like this Blog 🙂
Kotlin Operator Overloading – Working by Convention

Kotlin Operator Overloading – Working by Convention

Kotlin Operator Overloading and Conventions

Introduction

Kotlin supports a technique called conventions, everyone should be familiar with. For example, if you define a special method plus in your class, you can use the + operator by convention: Kotlin Operator Overloading.
In this article, I want to show you which conventions you can use and I will also provide a few Kotlin code examples that demonstrate the concepts.

Read More Read More

Simon is a software engineer based in Germany with 7 years of experience writing code for the JVM and also with JavaScript. He’s very passionate about learning new things as often as possible and a self-appointed Kotlin enthusiast.

Please follow and like this Blog 🙂