Tag: kotlin

From Java Builders to Kotlin DSLs

From Java Builders to Kotlin DSLs

From Java Builders to Kotlin DSLs

Introduction

DSLs – Domain Specific Languages – are an ever trending topic in Kotlin circles. They allow us to flex some of the most exciting language features while accomplishing more readable and maintainable solutions in our code.

Today I’d like to show you how to implement a certain kind of DSL – we’re going to be wrapping an existing Java Builder in Kotlin. No doubt you’ve come across the builder pattern in Java before, for example if you’re an Android developer, you must’ve used an AlertDialog.Builder, an OkHttpClient.Builder, or a Retrofit.Builder at some point. Wrapping a builder like this is a good exercise in just pure DSL design. All you have to worry about is designing the API you provide with your wrapper, since all the implementation for whatever your DSL provides its users is already done inside the builder!

Our example case

It just so happens that I’m the creator and maintainer of a library that does this very thing, and a small part of its implementation is what we’re going to be using as our example. The original library is the wonderful and hugely popular MaterialDrawer by Mike Penz, which allows you to create complex, good looking, and customized navigation drawers in your application, all via various Builder objects in Java, with no XML writing involved on your part. This is what my library, MaterialDrawerKt provides a convenient Kotlin DSL wrapper for.

The Builder API

Let’s take a look at the drawer we’re going to be creating in our example.

android_drawer

Here’s the code, using the builders in the original API:

DrawerBuilder()
        .withActivity(this)
        .withTranslucentStatusBar(false)
        .withDrawerLayout(R.layout.material_drawer_fits_not)
        .addDrawerItems(
                PrimaryDrawerItem()
                        .withName("Home")
                        .withDescription("Get started here!"),
                PrimaryDrawerItem()
                        .withName("Settings")
                        .withDescription("Tinker around")
        )
        .withOnDrawerItemClickListener { view, position, drawerItem ->
            when(position) {
                0 -> toast("Home clicked")
                1 -> toast("Settings clicked")
            }
            true
        }
        .withOnDrawerListener(object: Drawer.OnDrawerListener {
            override fun onDrawerSlide(drawerView: View?, slideOffset: Float) {
                // Empty
            }

            override fun onDrawerClosed(drawerView: View?) {
                toast("Drawer closed")
            }

            override fun onDrawerOpened(drawerView: View?) {
                toast("Drawer opened")
            }
        })
        .build()

In this code, we’ve…
– set the Activity we want the drawer to appear in,
– made some layout adjustments so that the drawer is below the ActionBar,
– created just two menu items with names and descriptions,
– set a listener where we can handle item selections by position, using a SAM conversion to implement a single method interface,
– added a listener to detect drawer movement, using an object expression, because the necessary interface has multiple methods.

We saw two different builders used here, namely, the DrawerBuilder and PrimaryDrawerItem classes. While their builder syntax actually looks pretty decent and readable, we’ll see that a DSL can do even better.

Note that you can check out the entire working demo project for this article on GitHub here. See the commit history to follow the article step by step as we build our DSL.

Creating instances

Let’s start small. We’ll want to create a drawer with a drawer {} call, let’s implement just that.

fun Activity.drawer(dummy: () -> Unit) {
    DrawerBuilder()
            .withActivity(this)
            .build()
}

We’ve defined our first function as an extension on Activity, so that it’s available when we’re in one, and it can access the Activity instance as this without us having to pass it in explicitly.

Now, we should add our PrimaryDrawerItem instances. This syntax would be nice for a start:

drawer {
    primaryItem()
    primaryItem()
}

To get this, we’ll need a primaryItem function that’s only available within the drawer block, and that somehow adds an item to the DrawerBuilder we’ve already created.

To be able to call methods on our DrawerBuilder instance before we build() it, we’ll introduce a new wrapper class that holds it:

class DrawerBuilderKt(activity: Activity) {
    val builder = DrawerBuilder().withActivity(activity)

    internal fun build() {
        builder.build()
    }
}

We’ll update our original drawer function to create an instance of this wrapper class. We’ll also modify its parameter – by making the setup function an extension on our own class, the client of the DSL will be placed in a new scope inside the lambda passed to the drawer function, where the methods of DrawerBuilderKt become available, as we’ll see in a moment.

fun Activity.drawer(setup: DrawerBuilderKt.() -> Unit) {
    val builder = DrawerBuilderKt(this)
    builder.setup()
    builder.build()
}

You might have spotted that we’ve marked our own build method internal – this is because the only call to it will be the one inside the drawer function. Hence, there’s no need to expose it to the clients of our library.

The visibility of builder is another story – we’ll have to keep this public so that our library stays extensible. We could make it internal for the purpose of us implementing wrappers around the built-in drawer items, but that would mean that nobody else could add their own custom drawer items to the DSL – something you could do with the original library. This is functionality we don’t want to strip from our clients.

Now we can finally add the primaryItem function we were planning earlier. To make this available inside the lambda passed to drawer, we could make it a member of the DrawerBuilderKt class. Modifying this class for every new drawer item type we add, however, seems like an odd thing to do. The various types of drawer items should in no way affect how the drawer itself works.

We can instead use the same mechanics as clients would use to create custom drawer items. We’ll get a neat, decoupled design by adding primaryItem as an extension function:

fun DrawerBuilderKt.primaryItem() {
    builder.addDrawerItems(PrimaryDrawerItem())
}

We can now add blank drawer items to our drawer!

Setting properties

Before we get to setting the name and description of our drawer items with the DSL, we have the properties of DrawerBuilder to take care of, as we’ve seen in the very first code snippet. This is the syntax we’ll create for these:

drawer {
    drawerLayout = R.layout.material_drawer_fits_not 
    translucentStatusBar = false
}

These, of course, will be properties on the DrawerBuilderKt class so that they’re available in the right scope.

Since the original builder doesn’t let us access the values we’ve set, what we’ll need to create are essentially write-only properties. These properties won’t have backing fields to store values, all they’ll do is forward the calls to the appropriate builder methods.

Unfortunately, Kotlin only has properties that can be both read and written (var) and read-only ones (val). We’ll solve this by using a var, and throwing an exception when someone tries to read these properties. We’ll also include Kotlin’s powerful @Deprecated annotation that lets us mark using the getters an error, so that clients are stopped from doing so at edit/compile time, rather than just getting the runtime exception:

class DrawerBuilderKt(activity: Activity) {
    ...

    var drawerLayout: Int
        @Deprecated(message = "Non readable property.", level = DeprecationLevel.ERROR)
        get() = throw UnsupportedOperationException("")
        set(value) {
            builder.withDrawerLayout(value)
        }
}

Alternatives for setting properties

Now, we can move on to customizing the drawer items themselves. The obvious solution here is to continue with the same syntax style as before:

drawer {
    primaryItem {
        name = "Home"
        description = "Get started here!"
    }
}

We know how to do this by creating a wrapper class around PrimaryDrawerItem, and then adding a couple non-readable properties, just like we did before. But let’s do something more interesting, and create this alternative syntax:

drawer {
    primaryItem(name = "Home", description = "Get started here!")
}

This is also pretty straightforward, we’re just calling a function that has two parameters, and using named parameters for readability. Let’s add these parameters to primaryItem then. We’ll also throw in default values so that they’re each optional:

fun DrawerBuilderKt.primaryItem(name: String = "", description: String = "") {
    val item = PrimaryDrawerItem()
            .withName(name)
            .withDescription(description)
    builder.addDrawerItems(item)
}

This, of course, isn’t a feasible method for adding dozens of properties to an item we’re constructing with our DSL, adding a wrapper around the PrimaryItemClass with separate write-only properties that can be set in a setup lambda is still the way to go for most things.

However, this is a nice way to lift some very basic or commonly set properties to a more prominent position in the code. Here’s what the DSL could look like with some more properties implemented:

primaryItem(name = "Games", description = "Ready, player one?") {
    iicon = FontAwesome.Icon.faw_gamepad
    identifier = 3
    selectable = false
}

Listeners

We know how to add properties to our DSL, now let’s see how we can go about listeners. We’ll start with the easy one, setting the OnDrawerItemClickListener to handle item clicks for a given position in the drawer. Here’s our goal:

drawer {
    onItemClick { position ->
        when (position) {
            0 -> toast("Home clicked")
            1 -> toast("Settings clicked")
        }
        true
    }
}

onItemClick will be a method in DrawerBuilderKt, and it will take a lambda parameter that can be called when the original listener fires:

class DrawerBuilderKt(activity: Activity) {
    ...

    fun onItemClick(handler: (view: View?, position: Int, drawerItem: IDrawerItem<*, *>) -> Boolean) {
        builder.withOnDrawerItemClickListener(handler)
    }
}

We’re making use of SAM conversion with the call to the withOnDrawerItemClickListener method of the builder here. The usual SAM conversion syntax would have us passing in a lambda that gets transformed to the OnDrawerItemClickListener interface, but instead, we’re going just a small step further, and we’re passing in the handler parameter which has the appropriate function type for a conversion.

We’ll simplify the above method a bit, by taking a lambda which only gets the position passed to it, as clients will usually only care about that parameter. We’re using SAM conversion again, this time with a regular lambda, because we want to ignore some parameters when calling our simpler handler parameter.

class DrawerBuilderKt(activity: Activity) {
    ...

    fun onItemClick(handler: (position: Int) -> Boolean) {
        builder.withOnDrawerItemClickListener { _, position, _ -> handler(position) }
    }
}

Of course, having only this version of the method would hide functionality of the original library, so in the real wrapper library, I’ve included both of these.

Complex listeners

Last but not least, let’s see what we can do about the OnDrawerListener in our example. This interface has three methods, so the previous, simple solution won’t work here. As always, let’s start with the syntax we want to achieve. Not that we’re only setting two of the three methods that the interface defines.

drawer {
    onClosed {
        toast("Drawer closed")
    }
    onOpened {
        toast("Drawer opened")
    }  
}

As you can see, it would be nice to be able to specify either one or multiple of the methods of the interface independently of each other. We know that we’ll want to define three methods to take the appropriate handler lambdas, very similarly to what we did before:

class DrawerBuilderKt(activity: Activity) {
    ...

    fun onOpened(handler: (drawerView: View) -> Unit) {
        // TODO implement
    }

    fun onClosed(handler: (drawerView: View) -> Unit) {
        // TODO implement
    }

    fun onSlide(handler: (drawerView: View, slideOffset: Float) -> Unit) {
        // TODO implement
    }
}

The question is how to pass these handlers to the builder we’re holding. We can’t make a withOnDrawerListener call in each of them and create an object that wraps just that one handler, as the object created there would always implement just one of the three methods.

What I came up with for this is an object property in our DrawerBuilderKt wrapper class that implements the OnDrawerListener interface, and delegates each of these calls to one of its properties.

class DrawerBuilderKt(activity: Activity) {
    ...

    private val onDrawerListener = object : Drawer.OnDrawerListener {
        var onSlide: ((View, Float) -> Unit)? = null

        override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
            onSlide?.invoke(drawerView, slideOffset)
        }

        var onClosed: ((View) -> Unit)? = null

        override fun onDrawerClosed(drawerView: View) {
            onClosed?.invoke(drawerView)
        }

        var onOpened: ((View) -> Unit)? = null

        override fun onDrawerOpened(drawerView: View) {
            onOpened?.invoke(drawerView)
        }
    }
}

All our previous methods have to do then is to set these properties when they’re called:

class DrawerBuilderKt(activity: Activity) {
    ...

    fun onOpened(handler: (drawerView: View) -> Unit) {
        onDrawerListener.onOpened = handler
    }

    fun onClosed(handler: (drawerView: View) -> Unit) {
        onDrawerListener.onClosed = handler
    }

    fun onSlide(handler: (drawerView: View, slideOffset: Float) -> Unit) {
        onDrawerListener.onSlide = handler
    }
}

Of course, we’ll still have to pass this object to the builder at some point – we’ll do that after the setup lambda passed to drawer has already done its work, and it calls our DrawerBuidlerKt.build() method:

class DrawerBuilderKt(activity: Activity) {
    val builder = DrawerBuilder().withActivity(activity)

    internal fun build() {
        builder.withOnDrawerListener(onDrawerListener)
        builder.build()
    }

    ...
}

Result

As a reminder, here’s the builder code we started the article with:

DrawerBuilder()
        .withActivity(this)
        .withTranslucentStatusBar(false)
        .withDrawerLayout(R.layout.material_drawer_fits_not)
        .addDrawerItems(
                PrimaryDrawerItem()
                        .withName("Home")
                        .withDescription("Get started here!"),
                PrimaryDrawerItem()
                        .withName("Settings")
                        .withDescription("Tinker around")
        )
        .withOnDrawerItemClickListener { view, position, drawerItem ->
            when(position) {
                0 -> toast("Home clicked")
                1 -> toast("Settings clicked")
            }
            true
        }
        .withOnDrawerListener(object: Drawer.OnDrawerListener {
            override fun onDrawerSlide(drawerView: View?, slideOffset: Float) {
                // Empty
            }

            override fun onDrawerClosed(drawerView: View?) {
                toast("Drawer closed")
            }

            override fun onDrawerOpened(drawerView: View?) {
                toast("Drawer opened")
            }
        })
        .build()

And then here’s the final DSL we’ve put together:

drawer {
    drawerLayout = R.layout.material_drawer_fits_not
    translucentStatusBar = false

    primaryItem(name = "Home", description = "Get started here!")
    primaryItem(name = "Settings", description = "Tinker around")

    onItemClick { position ->
        when (position) {
            0 -> toast("Home clicked")
            1 -> toast("Settings clicked")
        }
        true
    }
    onClosed {
        toast("Drawer closed")
    }
    onOpened {
        toast("Drawer opened")
    }
}

I hope this serves as a good example of how much better looking and more expressive a DSL can be than builder style solutions. Another benefit is how much easier making changes in the DSL is, which of course becomes apparent when you’re actually making them (but worrying about placing commas in the right places, for example, is in the past).

Conclusion

Thank you for sticking with me for this entire journey. I hope you got a good feel for how to design your own DSLs (always write down your desired syntax first!), and how to structure your DSL implementations.

If you’re interested in more, I recommend checking out the source of the actual MaterialDrawerKt library, as it deals with many more advanced concepts that I couldn’t fit in this post. Among other things, it uses generics and inheritance heavily to deal with MaterialDrawer‘s complex hierarchy of built-in drawer item types, restricts function calls and property accesses to the appropriate levels of the DSL hierarchy, and much more. I might cover these in a future article.

Additionally, you can find another article covering the process of writing a DSL here, and another article about more general DSL design here.

But this is it for now, and with that, it’s now your time to go and start creating your own DSLs. Good luck!

Márton is a Kotlin enthusiast from Hungary, currently working as an Android developer at AutSoft, while still pursuing a master’s degree in computer engineering. Brags a lot about being ranked third in the top users list of the Kotlin tag on Stack Overflow.

Please follow and like this Blog 🙂
Android KTX – Android development with Kotlin

Android KTX – Android development with Kotlin

Introduction

Android KTX is an open source library or set of functionalities designed to make the Android development with Kotlin even more pleasant. You can find its website here. The abbreviation KTX stands for Kotlin Extensions, so this library is basically a set of extension functions, extension properties and other top-level functions. In this article, we take a look at what’s inside this library and how we can take advantage of it. This library’s goal is not to add new features to the existing Android APIs, but rather make those APIs easier to use by leveraging the features of the Kotlin language.

Structure of Android KTX

A very important thing to note at the beginning is that Android KTX provides functionalities which would be added to many individual projects by the developers most of the time anyway. Arguably, there are also many things that will get included by adding the dependency, which are not going to be used. Thanks to the ProGuard, all the unused code will get stripped out, so there should be no worry regarding the library footprint. Now, let’s take a look at some of the very important and crucial concepts of the Kotlin language which are used for building the Android KTX.

Extension functions

An extension function is one of the Kotlin features that allows us to add a functionality to an existing class without modifying it directly. By adding extension functions to a class, they are represented as simple static methods on bytecode level. Then, we can call those functions on the objects of that class type, just as they were part of the class’s API initially. Here is an example to give a little better insight into the way it’s done. Say, we want to add an extension function to the String class to print itself. Here is how we can do it:

fun String.printSelf() {
    println(this)
}

Inside the extension function, we can use this to refer to the current object on which the function is being executed. Then, this function becomes available to be called on any object of String type. So we can do:

fun usage() {
    "Kotlin Rocks".printSelf()
}

Extension properties

Similarly to extension function, Kotlin supports extension properties. Also, the way we define them is quite the same:

val String.isLongEnough: Boolean
    get() = this.length > 5

Then, we can use this extension property on any object of String type:

"Kotlin".isLongEnough

The behavior of the extension property can only be defined by explicitly providing getter (plus setter for vars). Initializing those properties the ordinary way doesn’t work. The reason behind this is that an extension property does not insert members into the type, so there is no efficient way for it to have a backing field.

Top level functions

In Kotlin, a function is a first-class citizen. We are allowed to define functions in Kotlin files (.kt) which could afterward be accessed and used from other Kotlin files. This is a very powerful concept. If we define a file inside a package com.example and define functions in it, they can be used simply by importing them into the usage side. Here is an example:

package com.example

fun sum(x: Int, y: Int): Int = x + y

now this function can be accessed and used from any other Kotlin file by simply importing it like this:

import com.example.sum

fun test() {
    println(sum(1, 2))
}

An important note here is the access modifier. In the example above, the function sum does not have defined an access modifier, and in Kotlin it’s public by default. Being public, it makes the sum function accessible from any other Kotlin file. Kotlin also has an internal access modifier keyword, which would make this function accessible only in the module where this file exists (a module could contain many different packages). Ultimately, the function could also be private which will make it accessible only from inside the file where it is defined.

Default arguments

Most probably, you are familiar with the overloading concept like in Java already. Overloading is a concept that allows us to define constructors or methods with the same signature, only differing in their parameter list (both types and number of parameters could be different). In Kotlin, this concept is taken a step further, so we could achieve the same result by defining a single function, by specifying default values to some or all of the arguments. Eventually, it boils down to the approach used in Java again. Let’s take a look at the following example:

fun greet(firstName: String, lastName: String = "") {
    println("Hello $firstName $lastName")
}

In this example, the function takes two arguments, but the lastName is optional because by default its value is going to be an empty String. So, when calling this function we are only required to supply a firstName, and we can call it this way:

greet("John")

Kotlin also supports named arguments, so we could call a function supplying the arguments by their names:

greet("John", lastName = "Doe")

This is particularly useful when we have a function with multiple optional arguments and we want to call it with supplying only specific ones, or in a different order.

You can read more about Kotlin’s awesome features in this article.

Deep Dive into Android KTX

Now, as we know what the Android KTX library is based on, let’s dig and observe some of the most common extension functions.

Converting URL to URI

To begin with, there is a very simple extension function on the Uri class. Many times in Android, we need to convert a String URL into a Uri object, for instance when creating an Intent with data etc. The way we are usually doing this is by calling Uri.parse("string_url"). Android KTX defines an extension function that does the job. Here is how it looks like:

inline fun String.toUri(): Uri = Uri.parse(this)

so we can use it by calling toUri() on any string, like this:

"any_sting_url".toUri()

Editing shared preferences

Next, let’s take a look at an extension function defined on the SharedPreferences interface. The usual way of putting values into the SharedPreferences in Android is to call edit() in order to obtain the SharedPreferences.Editor instance. Then, we can insert the values by calling editor.putType("key", typeValue). After that, it is very important to call apply() or commit() on the editor, in order for the values to be stored in the SharedPreferences. Many times we forget doing so, and we waste some time debugging until we notice what is happening. A usual example of storing values in the SharedPreferences looks like this:

val editor = sharedPreferences.edit()
editor.putString("key", value)
editor.apply()

By using the Android KTX extension on the SharedPreferences the code shortens and simplifies quite a lot, and it becomes:

sharedPreferences.edit {
    putString("key", value)
}

The relevant extension function looks like this:

inline fun SharedPreferences.edit(
    commit: Boolean = false,
    action: SharedPreferences.Editor.() -> Unit
) {
    val editor = edit()
    action(editor)
    if (commit) {
        editor.commit()
    } else {
        editor.apply()
    }
}

The first parameter to this function is a Boolean value that controls the call to the editor, whether it would use the commit() or the apply() call. Clearly, by default this value is set to false which means by default the function will call apply() on the editor. A more interesting parameter is the second one. It’s a function literal with a receiver, and the receiver is of type SharedPreferences.Editor. It means that when calling this function, we can use lambda over the receiver, so we can directly call functions that are exposed by the receiver type without additional qualifiers. This is shown with the putString call.

Operating on view before drawing

Most of the apps we are using every day are having some sort of lists where some images are being loaded. Often, those images are of a different size, and the image sizes are usually provided in the response. Since the images are normally loaded in the background, we want to allocate the space required for the image to be displayed, and once it’s loaded we already have the space allocated, so we would avoid UI expanding when the image is being displayed, which prevents the UI flickering effect. This is usually done by using a ViewTreeObserver which provides an OnPreDrawListener. This listener has a callback that is being called before the view drawing. For our images example, usually we set the view sizes that are provided in the response inside this callback, and we apply some default background (for example gray). That is one of the many use cases of the ViewTreeObserver observer and its OnPreDrawListener. Here is a snippet that shows the way we normally approach it:

view.viewTreeObserver.addOnPreDrawListener(
    object : ViewTreeObserver.OnPreDrawListener {
        override fun onPreDraw(): Boolean {
            viewTreeObserver.removeOnPreDrawListener(this)
            performSomethingOverTheView()
            return true
        }
    })

Android KTX has defined an extension function on the View type named doOnPreDraw() that simplifies the above snippet, so it would become:

view.doOnPreDraw {
     performSomethingOverTheView()
}

There are also some other nice extensions defined on the View type which are working with the view visibility, updating view padding or layout params etc.

Working with bundle

Bundles are a very common thing in Android, but working with bundles is often quite a boilerplate. The way we normally compose a bundle looks like this:

val bundle = Bundle()
bundle.putString("key", "value")
bundle.putString("keyBoolean", true)
bundle.putString("keyInt", 1)

Android KTX defines a top-level function named bundleOf(), and by using it, composing bundle becomes a lot nicer:

val bundle = bundleOf("key" to "value", "keyBoolean" to true, "keyInt" to 1)

There is also a persistableBundleOf() function for creating a PersistableBundle but it’s available for API version 21 and up. Similarly, there is a contentValuesOf() function that could be used in the same way as the functions for creating bundle above, and it returns a ContentValues object.

Iteration over view group

Working with ViewGroup in Android is quite a common thing. The ViewGroup is a kind of container that could contain other views called children. Many times we need to loop through its children, but the traditional way to do so could be quite a mess. Android KTX has defined an extension property that exposes its children, and here is how it looks like:

val ViewGroup.children: Sequence<View>
    get() = object : Sequence<View> {
        override fun iterator() = this@children.iterator()
    }

As we can see, the children property is returning a sequence of child views, and it allows us to write very concise loops over any ViewGroup type:

viewGroup.children.forEach {
    doSomething(it)
}

Displaying toast

One of the most common ways of displaying some sort of short info to the user is a Toast. When displaying a toast by using the standard API, we have to pass the Context, the actual message that we want to be displayed, whether it is a String or a resource reference to load value from the strings.xml, and the toast duration. Since we cannot display a toast without having a Context, and since most of the time the toast duration is its Toast.LENGTH_SHORT constant, it would be great to have an option to display a toast by simply calling a function and passing the actual message argument. A common way to achieve this is by defining some sort of base class that defines such method, and then it would be called from the subclasses. However, Android KTX defines an extension functions to the Context type for displaying toasts. It takes 2 arguments, the message and the duration, while the duration is being set to Toast.LENGTH_SHORT by default. So we can call to display toast wherever we have a Context by simply passing the message argument, whether it is a String type or a reference to the string resources:

toast("Hello")
toast(R.string.hello)

Wrap Up

Android KTX is a very nice part of the Android JetPack project, and as we’ve seen it contains quite some nice ways to improve the Android development we are used to. As told before, it doesn’t provide any new functionalities, but rather simplifies the APIs which are already provided by the Android SDK. Here is a nice talk from the Google I/O 2018 by Jake Wharton, where he elaborates more on the Android KTX. This article only scratches the surface, and there are many more fun things to be revealed inside the Android KTX, related to animation, database, location, graphics, text and so on. Also, the team is welcoming new contributions, which is great, so if you have an idea that is not there yet, feel free to submit it.

Jovche is an Android developer based in The Netherlands, working on Android for the last 8 years. He has a big passion for clean code, TDD, getting things done, professional behavior, and software craftsmanship.

Please follow and like this Blog 🙂
Kotlin Nullability Features

Kotlin Nullability Features

Null-Safe Programming – The Kotlin Way

Disclaimer: This ktor article was originally published in the Dzone Java Guide 2018, which can be downloaded here.

In this article, we will review the problems that may be caused by null pointers and how to avoid them in Java. After that, the article demonstrates how Kotlin nullability features work and how they improve your code.

As Java developers, we’re very accustomed to NullPointerExceptions (NPE) that are thrown at the runtime of an application. This almost always happens unintentionally in consequence of a bug, which is based on unrecognized references to null. The null reference is often used to indicate absent values, which isn’t obvious to the programmer in many cases. Although Java relies on strong static typing, it doesn’t let you distinguish between reference types that can and cannot hold a null reference. Have a look at the following code example:

Device audio = new DeviceProvider().getAudioDevice();
String audioName = audio.getName();

The method getAudioDevice returns an object of type Device but might return null in order to denote the absence of that device on particular systems. Well documented methods will describe exactly that behavior, which still requires the developer to be very attentive. Not knowing about the possibility of a returned null reference is going to cause an awful NullPointerException in the subsequent call to getName. Wouldn’t it actually be nice if we were able to identify the method’s returned Device type as nullable (or non-nullable respectively) firsthand?

Null-Safety in Java

We have to find strategies that help us avoiding unwanted bugs due to NPEs. A common approach is to defensively check for null references and handle these cases in a way that makes more sense, such as providing default values or throwing more meaningful exceptions. Applying this to the previous example brings us to the following solution:

Device audio = new DeviceProvider().getAudioDevice();
String audioName;
if (audio != null) {
    audioName = audio.getName();
} else {
    throw new IllegalStateException("This system does not provide an audio device.");
}

Constructs like these are part of any Java project and the approach works well unless you forget to add checks for certain variables. It’s a fairly error-prone approach and doesn’t mitigate the fact that using null as a representative for absent things is risky.

Does Java offer any more sophisticated solutions to this problem? It does, at least in some situations. The Java SE 8 introduced the Optional type that acts as a “container object which may or may not contain a non-null value”. This sounds very promising and needs to be considered next.

Java SE 8 Optional

The Optional type is a container that wraps another object, which can theoretically be null. Code that works on instances of Optional needs to handle the possible nullability in a rather explicit way:

Optional audio = new DeviceProvider().getAudioDevice();
String audioName = audio
    .flatMap(Device::getName)
    .orElseThrow(() -> new IllegalStateException("This system does not provide an audio device."));

The getAudioDevice method was adjusted to return an Optional, which doubtlessly indicates to the client that the device can be absent. Instead of carelessly accessing that nullable type, the Optional type can be used for handling the possible nullability in various ways. These include providing default values and throwing exceptions with the help of simple methods like orElse and orElseThrow respectively. Furthermore, it literally forces the client to think about the potential null case.

Unfortunately, the whole Optional story already ends with this use case very suddenly. As stated by Java language architect Brian Goetz in this StackOverflow post, the Optional type was not intended as a “general purpose Maybe […] type” but a way to let libraries and APIs express the absence of a return type (as we saw in the previous example).

For further usage examples of Optional, you should find a suitable article in your preferred search engine.

After all, the Optional type is a great way to provide more explicit APIs that let the corresponding callers know exactly when null handling is required just by observing the method’s signature. Nevertheless, it’s not a holistic solution since it isn’t meant to replace each and every null reference in the source code. Aside from that, can you safely rely on method return types, which are not marked as Optional?

Kotlin Nullability: Null-Safety in Kotlin

After we have seen the rather unsafe null handling in the Java language, this section will introduce an alternative approach: The Kotlin programming language, as an example, provides very sophisticated means for avoiding NullPointerExceptions.

The language’s type system differentiates between nullable and non-nullable types and every class can be used in both versions. By default, a reference of type String cannot hold null, whereas String? allows it. This distinction on its own doesn’t make a very big difference obviously. Therefore, whenever you choose to work with nullable types, the compiler forces you to handle possible issues, i.e. potential NPEs, appropriately.

//declare a variable with nullable String type, it's OK to assign `null` to it
var b: String? = "possiblyNull"

// 1. does not compile, could throw NPE
val len = b.length

// 2. Check nullability before access
if (b != null){
    b.length
}

// 3. Use safe operator
val len = b?.length

This code example shows different ways of working with nullable types (String? in this case). As demonstrated first, it’s not possible to access members of nullable types directly since this would lead to the same problems as in Java. Instead, traditionally checking whether that type is not null makes a difference. This action persuades the compiler to accept invocations on the variable (inside the if-block) as if it were not nullable. Note that this does not work with mutable vars because they could possibly be set to null from another thread between the check and first action in the block.
As an alternative to explicit checks, the safe call operator ?. can be used. The expression b?.length can be translated to “call length on b if b is not null, otherwise return null“. The return type of this expression is of type Int? because it may result in null. Chaining such calls is possible and very useful because it lets you safely omit a great number of explicit checks and makes the code much more readable:

person?.address?.city ?: throw IllegalStateException("No city associated to person.")

Another very useful operator is the elvis operator ?: that perfectly complements the safe call operator for handling else cases. If the left-hand expression is not null, the elvis operator returns it, otherwise, the right-hand expression will be called.

The last operator that you need to know is called not-null assertion operator !!. It converts any reference to a non-null type. This unchecked conversion may cause an NPE if that reference is null after all. The not-null assertion operator should only be used with care:

person!!.address!!.city //NPE will be thrown if person or address is null

In addition to the shown operators, the Kotlin library provides plenty of helpful functions like String?::IsNullOrEmpty(), String::toDoubleOrNull() and List::filterNotNull(), to name just a few. All of them support the developer in proper nullability handling and make NPEs almost impossible.

Interop between both languages

One of the key attributes of Kotlin is its fantastic interoperability with Java source code. You can easily mix both languages in a project and call Kotlin from Java and vice versa. How does that work in the case of null safety, though?

As learned earlier in this article, every Java reference can be null, which makes it hard for Kotlin to apply its safety principles to them meaningfully. A type coming from Java is called platform type, denoted with an exclamation mark, e.g. String!. For these platform types, the compiler isn’t able to determine whether it’s nullable or not due to missing information. As a developer, when a platform type is e.g. assigned to a variable, the correct type can be set explicitly. If you assign a platform type String! to a variable of the non-nullable type String, the compiler allows it and, as a consequence, safe access to that variable isn’t being enforced. Nevertheless, if that decision turns out to be wrong, i.e. a null reference is returned, NPEs will be thrown at runtime. Fortunately, there’s a solution that allows providing more information to the Kotlin compiler by applying certain annotations to the corresponding Java methods. This enables the compiler to determine actual nullability information and makes platform types unneeded.

Bottom Line

It’s important to understand that Kotlin does not try to avoid null references as such but raises the attention for null-related issues and especially NPEs enormously. If you take care of platform types and defensively decide to use them as nullable ones or apply the mentioned annotations to your Java libraries, you should be safe. NullPointerExceptions will be a thing of the past. As set out above, the Kotlin language provides many useful operators and other functions that simplify working with nullable types tremendously by making use of its clever type system. We can hope to see similar solutions in future Java versions soon.

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 🙂
Run Kotlin Scripts (kts) from regular Kotlin Programs

Run Kotlin Scripts (kts) from regular Kotlin Programs

Run Kotlin Scripts from Kotlin Programs

This article presents a way to run Kotlin scripts from Kotlin programs in order to leverage the power of DSLs.

Kotlin can be used as a scripting language. Simply write top-level executable code inside a file with .kts extension and run it with the kotlinc as described in the documentation. That’s also the format of Gradle build files that are used in combination with the Gradle Kotlin DSL like this gradle.build.kts. Gradle shows a fantastic example of a domain specific language that can be written standalone in .kts files to be read by the gradle tool later on. When we try to find a way to do the same with custom DSLs (Tutorial can be found here), we first need to know how to run Kotlin scripts from Kotlin programs. The article reveals how to do so.

The Java Scripting API (JSR-223)

The Java Scripting API is a tool for using scripting engines (such as Nashorn) from Java code. It enables users to write customizable scripting code that can be picked up by the Java application at runtime. In a way, the API is a neat way of writing extensible applications.

As of Kotlin 1.1, the corresponding JSR-223 is supported for Kotlin Scripts, too. That means that it’s possible to run Kotlin scripts from regular Kotlin programs in order to make applications customizable through these scripts.

Using the Kotlin Script Engine

In order to use the mentioned Kotlin script engine, a file called javax.script.ScriptEngineFactory has to be placed inside META-INF/services of your application. It should contain the following entry: org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory.
After that, the javax.script.ScriptEngineManager will be able to find the corresponding engine when looked up via ScriptEngineManager().getEngineByExtension("kts"). This code now finds the Kotlin ScriptEngine implementation, an instance that can be used to evaluate String-based scripts such as "5 + 2", or directly read scripts from the file system. Here’s a short example:

with(ScriptEngineManager().getEngineByExtension("kts")) {
    eval("val x = 3")
    val res2 = eval("x + 2")
    assertEquals(5, res2)
}

You could also compile scripts and evaluate them later:

val script = compile("""listOf(1,2,3).joinToString(":")""")
assertEquals(listOf(1, 2, 3).joinToString(":"), script.eval())

Wrapping the glue code in a library

As shown, executing Kotlin scripts from Kotlin programs is pretty easy due to the Java scripting API implementation for Kotlin. Nevertheless, since it’s a bit cumbersome to integrate the support into an application, I wrote a tiny library that encapsulates the Scripting API glue code. It is called KtsRunner and can be found on GitHub.

The KtsRunner is a lightweight tool for executing Kotlin scripts from your custom applications. The API, as of the very first version, provides a slim KtsObjectLoader class whose usage is shown in the following example:

data class ClassFromScript(val x: String)
import de.swirtz.ktsobjectloader.ClassFromScript

ClassFromScript("I was created in kts")

The previous snippets show the definition of some arbitrary data class and the code that instantiates an object of it. The object instantiation is basically what we write into a .kts file.

val scriptReader = Files.newBufferedReader(Paths.get("path/classDeclaration.kts"))
val loadedObj: ClassFromScript = KtsObjectLoader().load<ClassFromScript>(scriptReader)
assertEquals("I was created in kts", loadedObj.x)

Using the KtsObjectLoader makes it simple to load the correspoding object of ClassFromScript from the script file. Alternatively, the script could also be provided as a String:

val scriptContent = "5 + 10"
val result: Int = KtsObjectLoader().load<Int>(scriptContent))
assertEquals(15, result)

Adequate Usage Scenario

As mentioned in the beginning, it can make sense to make your application customizable through external scripts, similar to how Gradle can be extended with any custom build script. Imagine an application that provides a test suite runtime. The actual test cases are provided by technical testers who write their test scripts using a domain specific language that is provided by the main application. Since you don’t want testers to add source files (defining new test cases) to your application all the time, the test case creation is made in independent .kts files in which the DSL is utilized by the testing team. The test suite main application can use the presented KtsRunner library for loading the test cases provided in .kts files and process them further afterward.

An example

A pretty popular DSL for Kotlin is kotlinx.html, a language for describing type-safe HTML. You let the client of your application provide some arbitrary HTML that you want to render at a later time. The HTML DSL code is provided as .kts script files and might look like this:

import kotlinx.html.*
import kotlinx.html.dom.create
import org.w3c.dom.Element
import java.io.OutputStream
import java.io.OutputStreamWriter
import javax.xml.parsers.DocumentBuilderFactory

val document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()
document.create.html {
    head {
        title("Hello world")
    }
    body {
        h1("h1Class") {
            style = "background-color:red"
            +"My header1"
        }
        p("pClass") {
            +"paragraph1"
        }
    }
}

When executed, an instance of org.w3c.dom.Element is created that contains the described HTML code in an XML document:

<?xml version="1.0" encoding="UTF-8"?><html>
    <head>
        <title>Hello world</title>
    </head>
    <body>
        <h1 class="h1Class" style="background-color:red">My header1</h1>
        <p class="pClass">paragraph1</p>
    </body>
</html>

That’s straightforward but the interesting part is that the script should actually be executed from the main program. For this purpose, we add the KtsRunner to the application by adding a repository and the dependency itself to the Gradle build file:

maven { 
    setUrl("https://dl.bintray.com/s1m0nw1/KtsRunner")
}
dependencies {
    //...
    compile("de.swirtz:ktsRunner:0.0.x")
}  

The final code for loading the Element from the external script looks as follows:

KtsObjectLoader().load<Element>(script)

Simple, isn’t it? Unfortunately, the shown Scripting API implementation for Kotlin is rather slow and you’ll definitely notice some performance constraints. Altogether, the KtsRunner is a very tiny tool that only encapsulates the glue code for enabling Kotlin Scripting support in random applications. The library is published on bintray and can therefore easily be used from your own application.

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 🙂
Why you should start contributing to StackOverflow

Why you should start contributing to StackOverflow

A little History

A few years back, when I started getting into programming, I googled a lot of the problems I was facing during the day and mostly found my answers on StackOverflow. The place that every programmer is kind of dependent on. I still face problems and I still find my answers on StackOverflow. Something has changed, though. I don’t only consume content on the website but also contribute to it. Until May 2017, I didn’t even have an account on StackOverflow. At this time, I was getting interested in knowing how it’s like to answer questions instead of just reading them. I enjoyed helping others to solve their Kotlin-related problems ever since I started learning the Kotlin programming language. This was my initial motivation for creating an account and contributing to StackOverflow.

The Kotlin Gold Badge

A few weeks back, after 10 months of answering about 400 questions, I was awarded the golden Kotlin badge, which means that I spend quite some time on the platform already. I was always motivated to receive the badge since only three other people got it by then. You can become kind of addicted to answering actually… 😉

stackoverflow-kotlin-gold-s1m0nw1

Lessons Learned

Teaching improves yourself

When I began with contributing to StackOverflow, I had to realize that it can be quite hard to give answers on the fly. It’s not that easy. You most often need to think about the way of looking at the problem from the questioner’s point of view. Regularly, you’ll find yourself researching for answers by studying the documentation, forums and other resources. Most questions also require you to solve the presented problem in your own IDE before coming up with a solution. It can be really time-consuming if you really try to understand other people’s problems. Nevertheless, the whole effort was totally worth it since I learned so many things about the Kotlin language itself and also about problem-solving in general. You don’t always know the answer to up-showing questions immediately and therefore have to put in some thoughts. This is always helpful and very valuable.

Give something back

What I also learned during that time is the fact that you shouldn’t always just take. In the case of StackOverflow, it’s almost disgraceful if you only read posts without telling the authors that their work helped you. I did the same for many years myself. You don’t need to feel bad about it but please take into consideration how much effort has been put into the questions and answers posted there. It really isn’t that hard to actually vote on these posts. If you don’t do this yet, create an account right away and give something back to the people you learn from.

Why you should start contributing

In my opinion, contributing to StackOverflow is a good thing for many reasons. It’s obvious that you’ll learn something from teaching and help others inescapably. Whatever topic you choose to participate in, you’ll be better at it afterward. More importantly, you’ll learn to value the contributions of the fellow answerers. You’ll recognize that it sucks if you don’t get up-voted by the people that consume your knowledge for free and you’ll probably never leave good answers (to the problems you searched for) without voting for them anymore. Even if you don’t want to answer questions, voting should be the least you should start with. If you’re willing to become an answerer though, I’d recommend choosing a niche topic like I did with Kotlin (which still needs expert contributors!). Entering tags like Java, on the other hand, is much more difficult because so many people are already involved in it.

Interestingly, I started a quick poll on Twitter which confirmed my assumptions: Most developers consume but don’t offer knowledge on StackOverflow.

twitter-stackoverflow-poll-s1m0nw1

I hope this makes sense and provokes a few readers to follow my advice.

EDIT:

I have to admit that I have experienced the StackOverflow community for just a short period of time and in the niche area of Kotlin, a language that still isn’t mainstream. I understand that StackOverflow is not just good and there are reasons you can criticise it for. If, after reading this article, you’re willing to learn from StackOverflow users, that have experienced the bad habits of the website, you should definitely read this post: My Love-Hate Relationship with StackOverflow.

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 🙂
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 🙂
Publish Kotlin Library on Bintray using Gradle Kotlin DSL and Travis CI

Publish Kotlin Library on Bintray using Gradle Kotlin DSL and Travis CI

Distribute a Library on Bintray using Gradle Kotlin DSL

In my latest blog post, published a few weeks back, I informed about the usage of the Gradle Kotlin DSL and how it helps with describing build scripts. In another earlier post, I introduced a small library that can be utilized for simplifying the creation of TLS/SSL sockets using a custom Kotlin DSL: SeKurity.

In this post, we’ll investigate how such a library can be made available to others that actually want to make use of it inside other projects. Ultimately, it should be possible to list the SeKurity library as a simple dependency in a build script like Maven or Gradle. Since the library itself is already backed by Gradle, I’ll show a way of publishing the resulting artifacts at the end of that build.

Where to publish?

In order to make a library available to anybody else, it needs to be published to a publicly accessible e.g. Maven repository like the famous Maven Central. Unless you’re absolutely certain about the quality of your library, it’s recommended to share it on custom repositories rather than THE central one directly as you’ll kinda lose control of it once it’s out there. One alternative is called Bintray and it will also be used in the present article. After creating an account or simply signing in with your GitHub, Google or Twitter account, you can create your own repositories there.

Automating the Build

Before enabling our build to publish the built artifacts, the process should be automated in a CI tool like Travis CI, which interacts nicely with GitHub. To make it work, it must be enabled in the GitHub repo settings by adding it as a service (see Settings -> Integrations & services). Travis expects the repository to incorporate a .travis.yml configuration that tells it what to do. For a simple Java/Kotlin project using Gradle, the following will be sufficient:

language: java

before_install:
- chmod -R +x src
- chmod +x gradlew

script: ./gradlew clean build
deploy:
  provider: script
  script: ./gradlew bintrayUpload -PbintrayUser=$BINTRAY_USER
  -PbintrayApiKey=$BINTRAY_KEY
    on:
      branch: master

It’s normally not necessary to specify the script command explicitly as long as you’re using the default instructions. In the shown case, Gradle runs the build task first before it deploys via the gradle bintrayUpload taks, which we will learn about later. The deployment only happens for the master branch. The gradle deploy takes two arguments $BINTRAY_USER and $BINTRAY_KEY, which contain private data and are therefore securely stored in Travis directly. When the build is run, Travis takes care of replacing them.
You can finally enable the repository in Travis and it will start a build on every push immediately. For further information on Travis, the documentation is highly recommended.

The Gradle Build

As shown earlier, the bintrayUpload Gradle task gets invoked in the build. Where does it come from? Let’s have a look at the relevant parts of the gradle.build.kts file.

The Plugins


plugins {
    kotlin("jvm") version "1.2.30"
    id("com.github.johnrengelman.shadow") version "2.0.2"
    `maven-publish`
    id("com.jfrog.bintray") version "1.8.0"
}
  • The shadow plugin is used because we need the library to be bundled with all its dependencies in order to avoid classpath conflicts.
  • The maven-publish plugin helps with creating the relevant artifact and a relevant pom.xml file that will also be published.
  • The bintray plugin does all the heavy work at the end of the build. It refers to the maven-publish result and pushes the artifacts to Bintray.

Plugin Configuration

The build file also adds custom configurations for all previously shown plugins as shown next:

I Shadow


val artifactID = "sekurity"

val shadowJar: ShadowJar by tasks
shadowJar.apply {
    baseName = artifactID
    classifier = null
}

The shadow plugin uses the project’s name as the artifact’s baseName and the “all” qualifier by default, which is overridden here.

II Maven-Publish


fun MavenPom.addDependencies() = withXml {
    asNode().appendNode("dependencies").let { depNode ->
        configurations.compile.allDependencies.forEach {
            depNode.appendNode("dependency").apply {
                appendNode("groupId", it.group)
                appendNode("artifactId", it.name)
                appendNode("version", it.version)
            }
        }
    }
}

val publicationName = "tlslib"
publishing {
    publications.invoke {
        publicationName(MavenPublication::class) {
            artifactId = artifactID
            artifact(shadowJar)
            pom.addDependencies()
        }
    }
}

This one is a bit tricky. We reuse the result of shadow and add it to the publication which will be published under the artifactId that corresponds to the JAR’s baseName. By default, the generated POM does not list the library dependencies, which is done by mapping each compile dependency to a valid dependency XML node.

III Bintray


fun findProperty(s: String) = project.findProperty(s) as String?

bintray {
    user = findProperty("bintrayUser")
    key = findProperty("bintrayApiKey")
    publish = true
    setPublications(publicationName)
    pkg(delegateClosureOf {
        repo = "SeKurity"
        name = "SeKurity"
        userOrg = "s1m0nw1"
        websiteUrl = "https://kotlinexpertise.com"
        vcsUrl = "https://github.com/s1monw1/TlsLibrary"
        setLabels("kotlin")
        setLicenses("MIT")
    })
}

The bintray plugin is most important since it takes care of actually uploading the generated artifacts to Bintray itself. The user and key are obtained from the Gradle project properties, which are passed by Travis later on as already shown earlier. By referring to the publication created in maven-publish, all artifacts will be uploaded as specified. The pkg block describes the library’s attributes and where, i.e. to what repository, the publishing happens.

The Result

All these blocks merged result in a pretty nice Gradle build script, which can be observed in this Gist and also the SeKurity repository itself. The resulting artifact is made available here: https://bintray.com/s1m0nw1/SeKurity/SeKurity

Referring to the published Library

Now that the library is being uploaded to Bintray, it can be listed as a dependency in arbitrary build files. If we have another Gradle-backed project, we first need to add the relevant repository to the list of repositories:


repositories {
    mavenCentral()
    jcenter()

    maven {
        setUrl("https://dl.bintray.com/s1m0nw1/SeKurity/")
    }
}

After that, the library can be added as a simple compile dependency like this:


dependencies {
//...other dependencies
    compile("de.swirtz:sekurity:0.0.2")
}

Recap

As shown, Gradle plugins can be used for setting up a proper build that publishes a custom library to Bintray easily. In order to automate the whole process, CI tools like Travis can be used for executing the build whenever a new change has been made.

I hope the little tutorial helps with your build as well! 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 Tutorial – Quick Reference – Getting Started with Kotlin

Kotlin Tutorial – Quick Reference – Getting Started with Kotlin

Introduction

Disclaimer: This reference has originally been published as a DZone Refcard.

Kotlin has become one of the most popular JVM languages in the past few months. One special reason is that it experienced a lot of attention in the Android community after Google made Kotlin an official language for Android development. Kotlin is being developed by JetBrains, who are responsible for the most famous IDEs out there, most notably IntelliJ IDEA. Nevertheless, it’s an open source language, which can be found on GitHub.

The language is said to be very concise, safe in terms of error frequency, interoperable with Java and also offers many features that enable functional programming, writing type-safe DSLs and much more. Beside the JVM, Kotlin can compile for most Android versions, down to machine code using LLVM and can also be transpiled to JavaScript.
Kotlin has already been adopted in many popular frameworks and tools such as Spring and Gradle. It continues to gain traction in multiple domains, and there has never been a better time to get started with Kotlin.

Where to Start Coding

When you want to start writing your first Kotlin code there are quite a few ways to do that. Apparently, the recommended way is to work with IntelliJ IDEA, which offers the best support. As an alternative, one could also start with the command line or use JetBrains’ Kotlin web IDE to do some Kotlin Koans. Whichever way you prefer, corresponding tutorials can be found here: kotlinlang.org/docs/tutorials/.

Basic Syntax

Kotlin was inspired by many modern programming languages like C#, Groovy, Scala and also Java. Even more, Kotlin can be seen as an extension to the Java language, making it better by adding functionality to existing standard classes (e.g. String, List) and of course by providing great features, which are in large part enabled by applying compiler-supported techniques. As in Java, Kotlin programs are entered via a main method, such as the following:

fun main(args: Array): Unit {
    val inserted = "Kotlin"
    println("Let's get started with $inserted")
}

What we can see in this snippet is:

  • Functions are initiated by the keyword fun, followed by a name
  • Parameters and also variables in Kotlin are declared by defining a name and a type, both separated by a colon as you can see in args: Array
  • The return type of the main is Unit, also prefaced by a colon. In case of a Unit return, which corresponds to Java’s void, the compiler does not require you to explicitly define the return type, so the part : Unit could be omitted
  • Kotlin does not require you to use semicolons for separating statements (in most cases)
  • Type inference is supported in many situations as shown with val inserted, which also could be declared with an explicit type as val inserted: String
  • String templates can be used, which means that it’s possible to include variables and even expressions in Strings directly using $varname or ${statement} syntax
  • main is declared without a wrapping class around it. Functions and variables in Kotlin may be declared at “top-level”, i.e directly inside a package
  • No visibility modifier is used here. Functions, classes, variables etc. are public by default. When different visibility is needed, choose from:
KeywordEffect on Top-Level declarations [1]Effect on Class Members
publicvisible everywherevisible everywhere if class is accessible
privatevisible inside the file onlyvisible inside the class only
protectedvisible in class and subclasses
internalvisible inside the same module [2]visible in the same module, if class is accessible

1: Functions, properties and classes, objects and interfaces can be declared on the “top-level”
2: A module is a set of Kotlin files compiled together: an IntelliJ IDEA module, a Maven project, a Gradle source set

  • Variables defined as val cannot be re-assigned, i.e. are read-only. Alternatively, if mutability is inevitable, var can be utilized, as shown in the next example:
var mutableVar = StringBuilder("first")
mutableVar = StringBuilder("second")
  • Constructor is invoked without the new keyword, which is omitted from kotlin

Control Flow: Conditions

In Kotlin you can make use of if, when, for and while for controlling the behavior of your code. Let’s look at conditions first.

If-Statement

val min: Int
if (x < y) {
    min = x
} else {
    min = y
}

It’s important to know, that many statements in Kotlin can also be used as expressions, which for instance makes a ternary operator obsolete and apparently shortens the code in most cases:

val min = if (x < y) x else y 

When-Statement A when statement is very similar to switch operators and could, in theory, easily replace if-statements as they are much more powerful.

val y = when (x) { 
    0 -> "is zero"
    1 -> "is one"
    2, 3 -> "two or three"
    is Int -> "is Int"
    is Double -> "is Double"
    in 0..100 -> "between 0 and 100"
    else -> "else block"
}

In a when statement, which can also be used as an expression, all branches are tried to match the input until one condition is satisfied. If no branch matches, the else is executed. As shown in the snippet, when branch conditions can be values, types, ranges and more.

Control Flow: Loops

For-Loop

In Kotlin, there’s no conventional for-loop, as you know it from C or Java. Instead, foreach loops are the default.

for (c in "charSequence") {
    println(c)
}

In many cases, looping with an index is necessary, which can easily be achieved with the indices property that is defined for arrays, lists and also CharSequences for example.

for (i in "charSequence".indices) {
    println("charSequence"[i])
}

Another way of iterating with indices is possible by using withIndix().

for ((i,c) in "charSequence".withIndex()) {
    println("$i: $c")
}

Last but not least, Kotlin has ranges, which can also be utilized for indexed iterations as the following shows:

(0 .. "charSequence".length-1).forEach {
    print("charSequence"[it])
}

The range in this example is expressed with the common .. syntax. To create a range which does not include the end element (s.length), the until function is used: (0 until s.length).

While-Loop

Constructs with while or do-while loops are straight-forward, all works as known from other common languages.

Basic Types

In Kotlin everything looks like an object to the user, even primitive types. This means, member functions can be called on every type, although some will be represented as JVM primitives at runtime.

Numbers

The default number types are: Double, Float, Long, Int, Short, Byte
* Underscores can be used to make large numbers more readable: val million = 1_000_000
* Number types offer conversion methods like toByte(): Byte, toInt(): Int , toLong(): Long
* Characters are no number type in Kotlin

Chars

A Char represents characters and cannot be treated as a number.
* They are declared within single quotes, e.g. '42'
* An explicit conversion from a Char to an Int can be accomplished with the toInt() method

Booleans

Booleans can have the two common values true and false
* They can be operated on with: ||, &amp;&amp; and !

Strings

Strings are immutable sequences of characters.
* They offer an index operator [] for accessing characters at specified positions
* A string literal in Kotlin looks like "Hello World" or """Hello World with "another String" in it"""
* The latter is called raw string that can contain any character without needing to escape special symbols
* Strings in Kotlin may contain template expressions

Arrays

An array is represented by the class Array, which offers very useful methods to the client.
* Values can be obtained via get(index) or [index]
* Values can be set via set(index, value) or [index]=value
* Arrays are invariant, i.e. an Array cannot be assigned to a variable of type Array
* Special types for arrays of primitive types exist as IntArray or ShortArray for instance. Using those will reduce the boxing overhead.

Classes

A simple class can be declared like in this snippet:

class Person constructor(name: String) {}

The primary constructor is part of the class header, secondary constructors can be added in the class body. In the shown case, the constructor keyword could also be omitted, since it’s only mandatory if you want to add annotations or visibility modifiers (default: public).
Constructor parameters such as name can be used during the initialization of an object of this class. For this purpose, an init block would be necessary, because primary constructors can’t contain code directly. Constructor arguments can also be used in property initializers that are declared in the class body, as shown here.

class Person(name: String, age: Int) {
    init {
        println("new Person $name will be born.")
    }

    val ageProp = age
}

As mentioned, Kotlin classes can contain properties, which are accessed by simply calling obj.propertyName to get a property’s value and obj.propertyName = "newValue" to modify the value of a mutable (var) property. Declaring properties for classes can also be done in the primary constructor directly, which makes the code even more concise. Like in all methods, Kotlin supports default parameters for parameters, set with “=“.

class Person(val name: String, val age: Int = 50)

Same as with local variables, instead of val, a property can be declared mutable using var instead. Note that you don’t have to write an empty class body if no content is defined.

Special Classes

Besides ordinary classes, Kotlin knows a few special class declarations, which are worth knowing. The following will give a quick overview.

TypeExplanation
data classAdds standard functionality for toString, equals, hashCode etc.
sealed classRestricts class hierarchies to a set of subtypes. Useful with when
Nested classClasses can be created in other classes, also known as “inner class”
enum classCollect constants that can contain logic
object declarationsUsed to create Singletons of a type

Of course, Kotlin also supports inheritance through interfaces and abstract classes.

Function Types and Lambdas

In order to be able to understand idiomatic Kotlin code, it’s essential to recognize how function types and especially lambdas look like. Just as you can declare variables of type Int or String, it’s also possible to declare variables of function types, e.g. (String) -> Boolean.

val myFunction: (String) -> Boolean = { s -> s.length > 3 }
myFunction("HelloWorld")

The variable is declared as a function type that takes a String argument and returns a Boolean. The method itself is defined as a lambda enclosed in curly braces. In the shown lambda, the String parameter is declared and named before the -> symbol, whereas the body follows after it.

Lambda Special Syntax

The language designers decided on some special lambda features, which make the usage even more powerful.

  1. it: implicit name of single parameters

In many cases, lambdas are used with single parameters like in the previous example. In such situations, you don’t have to give the parameter an explicit name. Instead, the implicit name it can be used.

val myFunction: (String) -> Boolean = { it.length > 3 }
myFunction("HelloWorld")
  1. For unused parameters, use _

In some cases, it might be unnecessary to make use of every possible available parameter in a lambda. The compiler warns the developer about such unused variables, which can be avoided by naming it with an underscore.

val myFunction: (String, Int) -> Boolean = { s, _ -> s.length > 3 }
myFunction("HelloWorld", 42)

Higher-Order Functions

If a function takes another function as an argument or returns another function as its result, it’s called a higher-order function. Such functions are essential in Kotlin as many library functions rely on this concept. Let’s see an example.

fun main(args: Array) {
    myHigherOrderFun(2, { it.length > 2 })
}

fun myHigherOrderFun(iterations: Int, test: (String) -> Boolean){
    (0 until iterations).forEach {
        println("$it: ${test("myTestString")}")
    }
}

The function myHigherOrderFun defines two parameters, one of which is another function test. The function takes test and applies a String to it multiple times depending on what the first argument iterations is. By the way, the example uses a range to imitate an indexed for loop here.

The shown main function demonstrates the usage of a higher-order function by calling it with an anonymous function. The syntax looks a bit messy, which is why the language designers decided on a very important convention: If a lambda is the last argument to a function, it can be placed after the closing parentheses or, if it’s the only argument, the parentheses can be omitted completely like shown with forEach above. The following snippet demonstrates this convention applied to an invocation of myHigherOrderFun.

//Lambda after closing parentheses
myHigherOrderFun(2) {
    it.length>2
}

Top Features

There are some features in Kotlin, everybody should be familiar with. These are essential for many libraries, standard functions and also advanced features like Domain Specific Language support.

Null-Safety

The type system differentiates between nullable and non-null types. By default, a class like String cannot reference null, which raises the attention for null-related problems. As opposed to String, the type String? can hold null. This does not make a big difference on its own. Therefore, working with nullable types implies having to handle nullable values in a special way.

var b: String? = "couldBeNull"
b = null //okay

// 1. Access directly: does not compile, could throw NPE
// val len = b.length

//2. Use safe-operator
val len = b?.length

//3. Check nullability before accessing
if(b != null){
    b.length
}

It’s possible to check whether a variable is not null before accessing it. In such cases, the compiler permits the usage without special safety measures. Alternatively, b?.length expresses: call length on b if it’s not null, otherwise the expression returns null. The return is of type Int? because null may be returned. Chaining such calls is possible, which is very useful. Other operators used with nullable types are shown in the following overview.

OperatorUse caseExample
!!Ignore warnings of compiler and overcome null checks. Use cautiously only.x!!.length
?:The elvis operator is used to give an alternative for null results.val len: Int = b?.length ?: 0
as?A safe cast tries to cast a variable in a type and results in null if the cast is not possible.val i: Int? = s as? Int

Extensions

Another essential feature of Kotlin is extensions. An extension is used to extend a class with new functionality without having to inherit from that class. Extensions can have the form of properties and functions. The Kotlin standard library contains a lot of such extensions, like the following defined on String:

public fun String.substring(range: IntRange): String = 
    substring(range.start, range.endInclusive + 1)

//usage
"myString".substring(0..3)

In this example String is the receiver of the defined substring(range: IntRange) function. An extension function can use visible members of its receiver without additional qualifiers since this refers to the receiver. In the snippet, String‘s standard method substring(startIndex: Int, endIndex: Int) is called in that way. The extension is called on a String as if it was a regular method.

It’s also possible to extend a class with properties. For example, Int can be extended with a property that represents its version of BigDecimal. This might be useful if otherwise, the constructor of BigDecimal had to be used many times.

val Int.bd
    get() = BigDecimal(this)

val bd: BigDecimal = 5.bd

Extensions are mostly defined on top-level and can be used in other files after they have been imported explicitly.

Lambda with Receiver

Higher-order functions can be even more powerful if used with “lambdas with receiver”. It’s possible to call function literals with a specific receiver object, similar to the extension functions. As a result, members of the receiver can directly be accessed inside the lambda without having to use additional qualifiers. This feature is the foundation for Kotlin’s fantastic support for writing Type-Safe Builders, also known as Domain Specific Languages.

fun T.apply(block: T.() -> Unit): T {
    block()
    return this
}

This snippet shows a slightly simplified version of the apply function, which is part of Kotlin’s standard library. It’s an extension function on the generic type T, thus can be used with any object. The function takes a function literal with T as its receiver and executes the block before this (the receiver of apply) is being returned.

data class GuiContainer(
    var width: Int = 0,
    var height: Int = 0,
    var background: String = "red"
) {
    fun printMe() = println(this)
}

fun main(args: Array) {
    val container = GuiContainer().apply {
        width = 10
        height = 20
        background = "blueish"
        printMe()
    }
}

In this example, the data class GuiContainer is created with default parameters and then the apply method is called on it. It’s possible to set mutable properties and call methods of the receiver GuiContainer like shown with the invocation of printMe() in the end. Since apply returns the receiver after it completes, it can directly be assigned to a variable.

Idiomatic Kotlin

Kotlin tries to encourage particular coding idioms to be used. These are partially listed in the documentation and also in some community driven articles. The following will present some of these idioms by example.

  1. Use when as an expression if possible
fun analyzeType(obj: Any) =
        when(obj){
            is String -> "is String"
            else -> "no String"
        }
  1. Use elvis operator with throw and return to handle nullable values

class Person(val name: String?, val age: Int?) fun process(person: Person) { val pName = person.name ?: throw IllegalArgumentException("Name must be provided.") println("processing $pName") val pAge = person.age ?: return println("$pName is $pAge years old") }
  1. Make use of range checks
fun inLatinAlphabet(char: Char) = char in 'A'..'Z'
  1. Prefer default parameters to function overloads
fun greet(person: Person, printAge: Boolean = false) {
    println("Hello ${person.name}")
    if (printAge)
      println("${person.name} is ${person.age} years old")
}
  1. Use type aliases for function types
typealias StringPredicate = (String) -> Boolean

val pred: StringPredicate = {it.length > 3}
  1. Use data classes for multiple return values
data class Multi(val s: String, val i: Int)

fun foo() = Multi("one", 1)

fun main(args: Array){
    val (name, num) = foo()
}
  1. Prefer extension functions to utility-style functions
fun Person.greet(printAge: Boolean = false) {
    println("Hello $name")
    if (printAge)
        println("$name is $age years old")
}
  1. Use apply for object initialization
data class GuiContainer(
    var width: Int = 0,
    var height: Int = 0,
    var background: String = "red"
) {
    fun printMe() = println(this)
}

fun main(args: Array) {
    val container = GuiContainer().apply {
        width = 10
        height = 20
        background = "blueish"
        printMe()
    }
}

  1. Use compareBy for complex comparisons
fun sort(persons: List): List =
    persons.sortedWith(compareBy(Person::name, Person::age))
  1. Use mapNotNull to combine map and filter for non-null values
fun getPersonNames(persons: List): List =
    persons.mapNotNull { it.name }
  1. Use object to apply Singleton pattern
object PersonRepository{
    fun save(p: Person){}
    //...
}

//usage
val p = Person("Paul", 40)
PersonRepository.save(p)
  1. Do not make use of !!
//Do not use !!, there's always a better solution
person!!.address!!.street!!.length
  1. Prefer read-only data structures
//Whenever possible, do not use mutable Data Structures

val mutableList: MutableList = mutableListOf(1, 2, 3)
mutableList[0] = 0

val readOnly: List = listOf(1, 2, 3)
readOnly[0] = 0 // Does not compile
  1. Use let to execute code if receiver is not null
fun letPerson(p: Person?) {
    p?.let {
        println("Person is not null")
    }
}

Resources

Language References:
Official Reference Documentation: https://kotlinlang.org/docs/reference/
GitHub repository: https://github.com/JetBrains/kotlin
Collection of Tools and Frameworks: https://kotlin.link
Operators and Keywords Overview: https://kotlinlang.org/docs/reference/keyword-reference.html

Community:
Slack: https://kotlinlang.slack.com
Twitter: https://twitter.com/kotlin
Newsletter: http://kotlinweekly.net
Discussion: https://discuss.kotlinlang.org

Blogs:
JetBrains: https://blog.jetbrains.com/kotlin/
Simon Wirtz: https://kotlinexpertise.com

Misc:
Kotlin in Action Book: Kotlin in Action
Books: https://kotlinlang.org/docs/books.html
Online IDE: https://try.kotlinlang.org

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 🙂
The Power of Gradle Kotlin DSL

The Power of Gradle Kotlin DSL

-The following is based on Gradle 4.3.1-

A few weeks ago I started migrating most of my Groovy-based gradle.build scripts to Kotlin-backed gradle.build.kts scripts using the Kotlin DSL. Why would I do that? Kotlin is my language of choice and I love the idea of using a single language to do all my work. I never learned programming with Groovy and only know the bloody basics, which always makes me think: “This can’t be the best way to do things…”. Kotlin, on the other hand, is a language I use on a daily basis and therefore I know how to use the language appropriately. Additionally, Kotlin is a statically-typed language, whereas Groovy isn’t. IDEs are having hard times offering code completion and error detection at compile time when a Groovy build script is being edited. As for the Kotlin DSL, this isn’t true. Especially IntelliJ knows how to help us with Kotlin development, even in gradle.build.kts files. All these reasons made me take a deeper look at the new style Gradle offers.

Minor Impediments

It can sometimes be a bit tedious to rewrite your gradle.build into gradle.build.kts files, especially in the IDE with all its caches malfunctioning during that process. I often had to reopen my project or even reimport it before IntelliJ understood what was going on. It also often helps to use “Refresh all Gradle projects” button in the Gradle view.

Let’s take a look

The following snippet shows the first part of a working example. It was taken from one of my projects, which is a Kotlin web application based on the Vert.x toolkit. Learn more about the technology in this post I wrote earlier.

The script first defines a few global variables, mostly containing version numbers, which are used throughout the build file. Next, we can observe the plugins block that simply defines a few plugins used for the build. Most importantly, the Kotlin Gradle plugin for JVM applications is included, which we can do with the DSL-specific function kotlin(module: String), that takes its module argument and appends it to "org.jetbrains.kotlin.", which then is put into the id(plugin: String) method, the default api for applying plugins. Last but not least, we can see the listing of dependencies, which again provides a kotlin convenience method we can use to reduce redundant declarations. A similar approach can be seen with the definition of the io.vertx dependencies. In order to only once write the "io.vertx.vertx" String, which is part of every single Vert.x dependency, it’s used as a receiver of let. A first example of real idiomatic code within the build script.

//imports

//taken from the `plugins` defined later in the file
val kotlinVersion = plugins.getPlugin(KotlinPluginWrapper::class.java).kotlinPluginVersion
val kotlinCoroutinesVersion = "0.19.3"

val vertxVersion = "3.5.0" //
val nexusRepo = "http://x.x.x.x:8080/nexus/content/repositories/releases"

plugins {
    kotlin("jvm").version("1.2.0")
    application
    java
    `maven-publish`
}

dependencies {
    compile(kotlin("stdlib", kotlinVersion))
    compile(kotlin("reflect", kotlinVersion))
    compile("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutinesVersion")

    "io.vertx:vertx".let { v ->
        compile("$v-lang-kotlin:$vertxVersion")
        compile("$v-lang-kotlin-coroutines:$vertxVersion")
        compile("$v-web:$vertxVersion")
        compile("$v-mongo-client:$vertxVersion")
        compile("$v-health-check:$vertxVersion")
        compile("$v-web-templ-thymeleaf:$vertxVersion")
    }

    compile("org.slf4j:slf4j-api:1.7.14")
    compile("ch.qos.logback:logback-classic:1.1.3")
    compile("com.fasterxml.jackson.module:jackson-module-kotlin:2.9.0.pr3")

    testCompile(kotlin("test", kotlinVersion))
    testCompile(kotlin("test-junit", kotlinVersion))
    testCompile("io.vertx:vertx-unit:$vertxVersion")
    testCompile("org.mockito:mockito-core:2.6.2")
    testCompile("junit:junit:4.11")
}

// Part 2
}

The second part of the example project starts with defining repositories, which are used to find dependencies and plugins declared earlier. Again, we see an example of simplifying the code with the help of using the language: The custom Maven repositories are defined using the functional method forEach, and thus shortens the boilerplate. After that, the plugins are being configured, which for instance is necessary for enabling coroutine support or defining the application properties. Finally, we can observe a sequence of task configurations that control the behavior of single build steps, e.g. tests.

// ...Part 1

repositories {
    mavenCentral()
    jcenter()
    listOf("https://www.seasar.org/maven/maven2/",
        "https://plugins.gradle.org/m2/",
        nexusRepo).forEach {
        maven { url = uri(it) }
    }
}

kotlin {
    experimental.coroutines = Coroutines.ENABLE
}

application {
    group = "de.swirtz"
    version = "1.0.0"
    applicationName = "gradle-kotlindsl"
    mainClassName = "de.swirtz.ApplicationKt"
}

publishing {
    repositories {
        maven {
            url = uri(nexusRepo)
        }
    }
    if (!project.hasProperty("jenkins")) {
        println("Property 'jenkins' not set. Publishing only to MavenLocal")
    } else {
        (publications) {
            "maven"(MavenPublication::class) {
                from(components["java"])
            }
        }
    }
}

tasks {
    withType {
        kotlinOptions.jvmTarget = "1.8"
    }

    withType {
        testLogging.showStandardStreams = true
    }

    withType {
        manifest {
            attributes["Main-Class"] = application.mainClassName
        }
        from(configurations.runtime.map { if (it.isDirectory) it else zipTree(it) })
    }

    withType {
        finalizedBy("publishToMavenLocal")
    }
}

The Result

We’ve seen a rather simple build script written with the Gradle Kotlin DSL. I made use of a few idiomatic Kotlin functions in order to show the power of such .kts files. Especially for Kotlin developers, it can make much sense to completely switch to the shown approach. IntelliJ does support the creation of new build.gradle.kts files by default when you open the “New” option in “Project” view.

There will be situations, which make you want to ask somebody for help. I recommend reaching out directly in the corresponding Kotlin Slack channel: gradle.

I hope I could inspire you to give it a try! Good Luck 🙂

The whole script as a Gist

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 🙂
Web Applications with Kotlin ktor

Web Applications with Kotlin ktor

Introduction

Disclaimer: This ktor article was originally published in the Dzone Web Development Guide, which can be downloaded here.

When Google made Kotlin an official language for Android a few months ago at Google I/O, the language gained a lot of popularity in the Android world quickly. On the server side though, Kotlin is not as broadly adopted yet and some people still seem to be cautious when backend services are involved. Other developers are convinced that Kotlin is mature enough and can safely be used for any server application in which Java could play a role otherwise.
If you want to develop web apps with Kotlin, you can choose from various web frameworks like Spring MVC/WebFlux, Vert.x, Vaadin and basically everything available for the JVM. Besides the mentioned frameworks there’s also a Kotlin specific library available for creating web applications, called Kotlin ktor. After reading this article, you’ll know what ktor and its advantages are and how you can quickly develop a web application in Kotlin.

Kotlin ktor

The web application framework ktor, itself written in Kotlin, is meant to provide a tool for quickly creating web applications with Kotlin. The resulting software may be hosted in common servlet containers like Tomcat or standalone in a Netty for example. Whatever kind of hosting you choose, ktor is making heavy use of Kotlin Coroutines, so that it’s implemented 100% asynchronously and mainly non-blocking. ktor does not dictate which frameworks or tools to be used, so that you can choose whatever logging, DI, or templating engine you like. The library is pretty light-weight in general, still being very extensible through a plugin mechanism.
One of the greatest advantages attributed to Kotlin is its ability to provide type-safe builders, also known as Domain Specific Languages (DSL). Many libraries already provide DSLs as an alternative to common APIs, such as the Android lib anko, the Kotlin html builder or the freshly released Spring 5 framework. As we will see in the upcoming examples, ktor also makes use of such DSLs, which enable the user to define the web app’s endpoints in a very declarative way.

Example Application

In the following, a small RESTful (Not sure, if everyone will agree) web service will be developed with ktor. The service will use an in-memory repository with simple Person resources, which it exposes through a JSON API. Let’s look at the components.

Person Resource and Repository

According to the app’s requirements, a resource “Person” is defined as a data class and the corresponding repository as an object, Kotlin’s way of applying the Singleton pattern to a class.


data class Person(val name: String, val age: Int){
    var id: Int? = null
}

The resource has two simple properties, which need to be defined when a new object is constructed, whereas the id property is set later when stored in the repository.
The Person repository is rather unspectacular and not worth observing. It uses an internal data store and provides common CRUD operations.

Endpoints

The most important part of the web application is the configuration of its endpoints, exposed as a REST API. The following endpoints will be implemented:

EndpointHTTP MethodDescription
/personsGETRequests all Person resources
/persons/{id}GETRequests a specific Person resource by its ID
/personsDELETERequests all Person resources to be removed
/persons/{id}DELETERequests a specific Person resource to be removed by its ID
/personsPOSTRequests to store a new Person resource
/GETDelivers a simple HTML page welcoming the client

The application won’t support an update operator via PUT.

Routing with Ktor

Now ktor comes into play with its structured DSL, which will be used for defining the previously shown endpoints, a process often referred to as “routing”. Let’s see how it works:


fun Application.main() {
    install(DefaultHeaders)
    install(CORS) {
        maxAge = Duration.ofDays(1)
    }
    install(ContentNegotiation){
        register(ContentType.Application.Json, GsonConverter())
    }

    routing {
        get("/persons") {
            LOG.debug("Get all Person entities")
            call.respond(PersonRepo.getAll())
        }
    }
    // more routings
}

The fundamental class in the ktor library is Application, which represents a configured and eventually running web service instance. In the snippet, an extension function main() is defined on Application, in which it’s possible to call functions defined in Application directly, without additional qualifiers. This is done by invoking install() multiple times, a function for adding certain ApplicationFeatures into the request processing pipeline of the application. These features are optional and the user can choose from various types. The only interesting feature in the shown example is ContentNegotiation, which is used for the (de-)serialization of Kotlin objects to and from JSON, respectively. The Gson library is used as a backing technology.
The routing itself is demonstrated by defining the GET endpoint for retrieving all Person resources here. It’s actually straight-forward since the result of the repository call getAll() is just delegated back to the client. The call.respond() invocation will eventually reach the GsonSupport feature taking care of transforming the Person into its JSON representation. The same happens for the remaining four REST endpoints, which will not be shown explicitly here.

The HTML builder

Another cool feature of ktor is its integration with other Kotlin DSLs like the HTML builder, which can be found on GitHub. By adding a single additional dependency to a ktor app, this builder can be used with the extension function call.respondHtml(), which expects type-safe HTML code to be provided. In the following example, a simple greeting to the readers is included, which the web service exposes as its index page.


get("/") {
    call.respondHtml {
        head {
            title("ktor Example Application")
        }
        body {
            h1 { +"Hello DZone Readers" }
            p {
                +"How are you doing?"
            }
        }
    }
}

Starting the Application

After having done the configuration of a ktor application, there’s still a need to start it through a regular main method. In the demo, a Netty server is started standalone by doing the following:


fun main(args: Array) {
    embeddedServer(Netty, 8080, module = Application::main).start(wait = true)
}

The starting is made pretty simple by just calling the embeddedServer() method with a Netty environment, a port and the module to be started, which happens to be the thingy defined in the Application.main() extension function from the previously shown example.

Testing

A web framework or library is only applicable if it comes with integrated testing means, which ktor actually does. Since the GET routing for retrieving all Person resources was already shown, let’s have a look at how the endpoint can be tested.


@Test
fun getAllPersonsTest() = withTestApplication(Application::main) {
    val person = savePerson(gson.toJson(Person("Bert", 40)))
    val person2 = savePerson(gson.toJson(Person("Alice", 25)))
    handleRequest(HttpMethod.Get, "/persons") {
        addHeader("Accept", json)
    }.response.let {
        assertEquals(HttpStatusCode.OK, it.status())
        val response = gson.fromJson(it.content, Array::class.java)
        response.forEach { println(it) }
        response.find { it.name == person.name } ?: fail()
        response.find { it.name == person2.name } ?: fail()
    }
    assertEquals(2, PersonRepo.getAll().size)
}

This one is quite simple: Two resource objects are added to the repository, then the GET request is executed and some assertions are done against the web service response. The important part is withTestApplication(), which ktor offers through its testing module and makes it possible to directly test the Application.
The article presented basically everything worth knowing in order to get started with ktor web applications. For more details, I recommend the ktor homepage or the samples included in the ktor repository.

Takeaways

In this article we had a look at the Kotlin web service library ktor that provides simple tools for writing a light-weight web application in Kotlin very quickly. ktor makes heavy use of Kotlin’s beautiful features, especially DSLs, Coroutines and extension functions, all of which make the language and ktor itself so elegant. This mainly separates ktor from other powerful frameworks, which in fact can be used with Kotlin very smoothly, but, since not completely written in Kotlin, lack certain features you can find in ktor. It’s a great place to start with web applications because of its simplicity and ability to be extended with custom features if needed, following the principle “simple is easy, complex is available”.
The complete source code of the developed web application can be found on GitHub, it’s backed by a Gradle build.

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 🙂