Kotlin Koans—Part 9

Java and Kotlin are strongly typed languages. It’s not necessary to cast types when working up an object graph. For example

public void sort(Collection col){
    //todo
}

sort(new ArrayList());
sort(new HashSet());

This is an example of polymorphism in Java. ArrayList and HashSet are both Collections so it’s acceptable to pass either types to the example sort method.

Keep in mind this is not a two way street. This code would not compile.

public void sort(List list){
    //todo
}

Collection col = new ArrayList();
sort(col); //Compile error!
sort((List) col); //OK

Even though col points at an ArrayList and ArrayList implements List, Java forbids you to pass col to sort without a cast. This is because the compiler has no idea that col is pointing at an ArrayList. Keep in mind this is true of Kotlin also.

Although we can get our code to compile with a cast, it’s still dangerous code. Let’s tweak it a little big and have col point at a HashSet instead of ArrayList.

public void sort(List list){
    //todo
}

Collection col = new HashSet();

//Compiles but throws
//ClassCastException
sort((List) col);

Now the code compiles, but it will fail at run time. There is no way to cast HashSet to a List. HashSet does not implement List in anyway so when the code attempts to make the cast, the code will fail. We have to use the instanceof operator to make sure the cast is safe first.

public void sort(List list){
    //todo
}

Collection col = new HashSet();

if (col instanceof List){
    //Now it's safe
    sort((List) col);
}

This code is now safe. It will check if the runtime type of col is a List first. If the object is a List, it will make the cast. Otherwise, the cast will not get made.

Tutorial

This portion of the Kotlin Koans tutorial shows off how Kotlin handles casting compared to Java. Here is the Java code that needs to get rewrote in Kotlin.

public class JavaCode8 extends JavaCode {
    public int eval(Expr expr) {
        if (expr instanceof Num) {
            return ((Num) expr).getValue();
        }
        if (expr instanceof Sum) {
            Sum sum = (Sum) expr;
            return eval(sum.getLeft()) + eval(sum.getRight());
        }
        throw new IllegalArgumentException("Unknown expression");
    }
}

Kotlin has a when keyword that is used for casting. Here is the equivalent Kotlin code.

fun todoTask8(expr: Expr): Int {
    when (expr) {
        is Num -> return expr.value
        is Sum -> return todoTask8(expr.left) + todoTask8(expr.right)
        else -> throw IllegalArgumentException("Unknown expression")
    }
}

As usual, Kotlin is more concise than Java. The when block starts with the when followed by the variable in question. You can have any number of is clauses in this statement followed by the type. The variable is automatically cast to the specified type on the right hand side of the -> operator.

You can click here to see Part 8

Advertisement

Kotlins Koans—Part 8

Kotlin introduces a nullable data type. The idea behind it is to dramatically reduce if not eliminate the NullPointerException. Developers of almost any language have had to fight with some sort of exception that get’s thrown when trying to derefence a null type.

This portion of the Kotlin Koans tutorial has us rewriting the following Java code in Kotlin.

public class JavaCode7 extends JavaCode {
    public void sendMessageToClient(@Nullable Client client, @Nullable String message, @NotNull Mailer mailer) {
        if (client == null || message == null) return;

        PersonalInfo personalInfo = client.getPersonalInfo();
        if (personalInfo == null) return;

        String email = personalInfo.getEmail();
        if (email == null) return;

        mailer.sendMessage(email, message);
    }
}

Readers will see the amount of boilerplate that is in this code. You have three if statements that are dedicated to checking if a reference is null or not.

I do like the @Nullable annotations because it lets me know that these incoming parameters can be null and I need to know to check for a null case. Lombok has a similar @NonNull annotation that does the job of throwing a NullPointerException if the incoming parameters are null.

JDK8 (3rd prior libraries prior to JDK8) did give Java developers an Optional class and JDK7 has the Objects.nonNull method. These classes help with null safety, but at the cost of more boilerplate.

public class Optionals {

    public void sendMessageToClient(Optional clientOptional,
                                    Optional messageOptional,
                                    Mailer mailer){
        clientOptional.ifPresent(client ->
                messageOptional.ifPresent(message -> {
            PersonalInfo personalInfo = client.getPersonalInfo();
            if (nonNull(personalInfo) &&
                    nonNull(personalInfo.getEmail())){
                mailer.sendMessage(personalInfo.getEmail(), message);
            }
        }));
    }
}

Kotlin has a ?: operator that helps with dealing with the NullPointerException.

fun sendMessageToClient(
        client: Client?, message: String?, mailer: Mailer
) {
    message ?: return
    val email = client?.personalInfo?.email ?: return
    mailer.sendMessage(email, message)
}

The Kotlin code does the same thing as the Java code but there are a few things to discuss. When Kotlin parameters have a ? operator, that means they can be a null type. Unlike Java, the Kotlin compiler forces you to address the null case in such variables. I feel this is a super helpful feature because it’s easy to overlook a null case without compiler checks.

By the time we get to mail.sendMessage the variables email and message have to have values or the code will not compile. This is because the previous two lines force us to check for null values and if they are null, return from the function.

You can click here to see Part 7

Kotlin Koans—Part 7

This portion of the Kotlin Koans showed off a really boss feature of the language: Data Classes. These are special classes whose primary purpose is to hold data.

Here is a Java class that we start with that’s taken directly from the tutorial.

public class Person {
        private final String name;
        private final int age;

        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public int getAge() {
            return age;
        }
    }

It’s not a special class. This is a class with a primary constructor, getters/setters and two private variables. It’s also one of my biggest complaints about the Java language. I can do the same thing in Python like this.

class Person:
    def __init__(self, name=None, age=None):
        self.name = name
        self.age = age

Four lines of code in Python. In all fairness to Java, would could just declare name and age to be public variables, but doing so is not only frowned upon, but many Java libraries look for getter/setter method to access a property of a Java bean. Basically speaking, even though we could allow for public access of a Java property, it’s not really practical at this point.

There is a Java library called Lombok that does a lot to solve this problem.

@Data
public class Person {
    private String name;
    private String age;
}

Lombok has been the solution I have used for most of my projects. It’s not perfect however. For example, I can’t use the @Data annotation to make a read only class. That forces me to use a mix of Lombok annotations or define a stereotype annotation. It’s not a huge problem, but it’s still something to think about.

Kotlin data classes take this to a whole other level. Here is the same class in Kotlin.

data class Person(val name: String, val age: Int)

That’s it! One line of code!!! With this single line of code, we get our two properties, it’s getter methods, hashcode, equals, toString() and a constructor. The class is immutable because the variables are declared with the val keyword. We can make the class mutable by using var instead of val. Finally, we aren’t losing our ability to work with existing Java libaries.

I really don’t see how it can get any better than this. I have used data classes countless times when working with ORM libraries such as hibernate. I’d say 95% of these classes are classes that just hold data and map to a table in the database. Although any IDE can generate constructors, getters/setters, equals, and hashcode, and toString, let’s face it, it’s even better to have this built directly into the language itself.

You can click here to see Part 6

Kotlin Koans—Part 6

Insert Values into String

Kotlin upgrades some of Java’s String capabilities. One of the first things I liked was the ability to insert variables into the String

val a = 1
val b = 2
str = "Here is a String with values a=$a and b=$b)

We could of course have done this with String.format in Java

int a = 1;
int b = 2;
String str = "Here is a String with values a=%d and b=%d".format(a, b);

I think most people agree that the Kotlin approach is more concise.

Multiline Strings

Kotlin supports the “”” for mutliline strings without any need to escape charaters.

str = """
Here is a multiline String
C:\folder\file.txt

"""

The Kotlin Koans tutorial suggested that this was also useful for Regex expressions.

Task

The task for this portion of the tutorial was simple enough. We have a variable named month that we insert into a regex expression.

val month = "(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)"

fun task5(): String{
    return """\d{2}\ $month \d{4}"""
}

This a use case for the triple quote Strings. In Java, we would have needed to escape all of the backslashes in the regex expression. I know that I am not the first developer who has gotten burned by typing \ when I should have typed \\, so the triple quote String is a nice feature.

You can click here to see Part 5.

Kotlin Koans—Part 5

Many modern programming lanugages have support for functional programming. I remember when Java got support for functional programming in JDK8. I have to say it was awesome to finally get support for functional programming.

Of course, Java has supported functional programming to a certain degree for a while now through anonymous inner classes. The syntax was verbose…

public class Window extends JFrame {
    
    public Window(){
        JButton jButton = new JButton("Button");
        jButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Clicked");
            }
        });
    }
}

Java 8 simplified this mess when it officially supported functional programming.

public class Window extends JFrame {

    public Window(){
        JButton jButton = new JButton("Button");
        jButton.addActionListener(e -> System.out.println("Clicked"));
    }
}

Readers can see that the above code is far more consise than the previous example so many Java developers, including myself, were greatful for the change. Android developers weren’t so lucky and unless things have changes, Android developers still have to live with anonymous inner class syntax.

That is until Kotlin came along and is now supported for Android. In this portion of the Kotlin Koans tutorial, I had to rewrite this Java code into Kotlin.

public class JavaCode4 extends JavaCode {
    public boolean task4(Collection collection) {
        return Iterables.any(collection, new Predicate() {
            @Override
            public boolean apply(Integer element) {
                return element % 42 == 0;
            }
        });
    }
}

Of course, JDK 8 developers get the Stream API and lambda syntax, while Android developers were out of luck. Here is the equivalent Kotlin code.

fun task4(collection: Collection): Boolean{
    return collection.any { element -> element % 42 == 0 }
}

You can click here to see Part 4

Kotlin Koans—Part 4

Kotlin does indeed use default arguments and named parameters. This was something I really enjoy in Python but isn’t supported in Java.

For those people who aren’t familiar with the term, named arguments is a feature in a programming language where a developer can specify the name of a parameter and assign it a value when calling a function. It helps improve code readability. Here is a little Python to show off named arguments.

def func(arg1, arg2, arg3):
    pass

# Which is more clear?
# Named arguments?
func(arg1=1, arg2=2, arg3=3)

# Non-named arguments?
func(1, 2, 3)

In the above code snippet, the developer calls each argument in the function by it’s name and assigns a value to the parameter. It’s a lot nicer because you can instantly see what each value in the function is doing.

Many people have probably heard of default arugments. This is a feature in many programming languages where a developer can specify a default value for a parameter. When calling the function, the client code can choose to specify a value or just use the default. Here is another little Python teaser.

def func(arg1='Hello World'):
    pass

# Using default
func()

# Using custom value
func('Thunderbiscuit')


Java does not support either of these concepts. It does support function overloading. In this portion of Kotlin Kroans, we have to translate this Java code into Kotlin.

package i_introduction._3_Default_Arguments;

import util.JavaCode;

public class JavaCode3 extends JavaCode {
    private int defaultNumber = 42;

    public String foo(String name, int number, boolean toUpperCase) {
        return (toUpperCase ? name.toUpperCase() : name) + number;
    }

    public String foo(String name, int number) {
        return foo(name, number, false);
    }

    public String foo(String name, boolean toUpperCase) {
        return foo(name, defaultNumber, toUpperCase);
    }

    public String foo(String name) {
        return foo(name, defaultNumber);
    }
}

Readers will notice that the function foo is overloaded three times with different versions specify default arguments. It works, but it's also super verbose. Kotlin cuts through all of that noise. Here is the same code in Kotlin.

fun foo(name: String, number: Int = 42, toUpperCase: Boolean=false): String {
    if (toUpperCase) {
        return name.toUpperCase() + number
    } else {
        return name + number
    }
}

Readers will see that Kotlin is much more consice. One Kotlin function can do the same job as four functions in Java. We can call this function using this code.

fun task3(): String {
    return (foo("a") +
            foo("b", number = 1) +
            foo("c", toUpperCase = true) +
            foo(name = "d", number = 2, toUpperCase = true))
}

In this code snippet, we make four distinct calls to foo. Each time, we only specify the arguments that we need. I am also a huge fan of using the named arguments also. It makes it much easier to read the code.

You can click here to see Part 3 or Part 5

Kotlin Spring MVC

Kotlin makes Spring MVC projects a total breeze. This is a simple web application that combines a few different Kotlin techniques into a Spring Boot project. Here are few screen shots of the finished example and then we will dive into the code that makes it possible.

 

package com.stonesoupprogramming.kotlinspringmvc

import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod

@SpringBootApplication //This performs magic under the hood to launch a spring web application
class KotlinSpringMvcHelloWorldApplication

//Entry point to the application
fun main(args: Array) {
    SpringApplication.run(KotlinSpringMvcHelloWorldApplication::class.java, *args)
}

//This is a class that we are using for our form
//Kotlin let's us one line it!
data class Registration(var firstName: String = "", var lastName: String = "")

@Controller //Tells Spring this is a controller class
@RequestMapping("/") //Tells Spring to handle web requests at the root
class Controller {

    //This function will handle HTTP Get Requests
    @RequestMapping(method = arrayOf(RequestMethod.GET))
    fun doIndexGet(model: Model): String{
        //Send a new instance of Registration back to the view
        model.addAttribute("registration", Registration())

        //Render the index.html page
        return "index"
    }

    //This method handles HTTP Post
    @RequestMapping(method = arrayOf(RequestMethod.POST))
    fun doIndexPost(formParams: Registration, model: Model): String {
        //Send a greeting message to the view
        model.addAttribute("greet", "Hello ${formParams.firstName} ${formParams.lastName}")

        //Render the greet.html page
        return "greet"
    }

    //This handles GET requests for /greet.html
    @RequestMapping(path = arrayOf("/greet"), method=arrayOf(RequestMethod.GET))
    fun doGreetGet(): String = "greet" //Just tell it to render the greet.html page
}

Initializing the Application

Many readers are no doubt familiar with Spring Boot. Our first class in this project appears on line 11 with this code.

@SpringBootApplication //This performs magic under the hood to launch a spring web application
class KotlinSpringMvcHelloWorldApplication

Kotlin focuses on begin concise and in this is literally an empty class that is annotated with @SpringBootApplication. The annotation performs some Spring magic that does the job of initializing the Spring environment for us. Our next segment of code is the entry point to the application.

//Entry point to the application
fun main(args: Array) {
    SpringApplication.run(KotlinSpringMvcHelloWorldApplication::class.java, *args)
}

Once again, there isn’t much code here, but a lot is happening under the hood that is invisible to us. We are calling the static SpringApplication.run function and passing into it the KotlinSpringMvcHelloWorldApplication class along with the supplied command line arguments. Once again, we will leave it up to Spring to prepare our environment.

Data Class

Many Java developers have no doubt made classes the are simply holders for properties along with a constructor, getters and setters, hashcode(), equals(), and toString(). Two common applications of such classes are ORM model classes and classes that can be passed back to the view. In this case we are making a class that gets passed to the view, but we are going to define it using Kotlin’s data class. The code for such a class is extremely brief.

data class Registration(var firstName: String = "", var lastName: String = "")

Using this single line of code, we make a Registration class with two properties, a default constructor, and an overloaded constructor. The class comes packed with hashcode(), equals(), toString() and when used in Java code, it will have getters and setters. We are going to pass this code back to the view in the controller class.

Controller

The Controller is another portion of Spring MVC. We use it to map HTTP requests to the appropriate methods in the class. Spring will also inject a Model class when needed so that we can pass data back to the view. Here is the controller class written in Kotlin.

@Controller //Tells Spring this is a controller class
@RequestMapping("/") //Tells Spring to handle web requests at the root
class Controller {

    //This function will handle HTTP Get Requests
    @RequestMapping(method = arrayOf(RequestMethod.GET))
    fun doIndexGet(model: Model): String{
        //Send a new instance of Registration back to the view
        model.addAttribute("registration", Registration())

        //Render the index.html page
        return "index"
    }

    //This method handles HTTP Post
    @RequestMapping(method = arrayOf(RequestMethod.POST))
    fun doIndexPost(formParams: Registration, model: Model): String {
        //Send a greeting message to the view
        model.addAttribute("greet", "Hello ${formParams.firstName} ${formParams.lastName}")

        //Render the greet.html page
        return "greet"
    }

    //This handles GET requests for /greet.html
    @RequestMapping(path = arrayOf("/greet"), method=arrayOf(RequestMethod.GET))
    fun doGreetGet(): String = "greet" //Just tell it to render the greet.html page
}

The first line is the @Controller annotation. Our Spring boot environment has component scanning enabled, so we only need to annotate our controller class to make Spring aware of it’s existence. On line 2, we have the @RequestMapping annotation that tells Spring that the default request mapping for this class is the root of the web application (‘/’). The class contains three functions: doIndexGet, doIndexPost, and doGreetGet. Let’s talk about each in detail.

doIndexGet

This method is annotated with @RequestMapping and it handles HTTP Get requests to the ‘/’ endpoint. The function has one parameter, model : Model, and it returns a String. The model parameter is injected by Spring.

On the first line of the function, we add a “registration” attribute to the model with a new instance of Registration. Notice that in Kotlin, we do not need the new keyword and since we define default arguments for our Regsitration class, we do not need to supply an parameters. The function ends by returning the String “index” which will tell Spring and Thymeleaf (which is our template engine) which page to render.

doIndexPost

This function handles HTTP post methods as indicated by @RequestMapping(method = arrayOf(RequestMethod.POST)). It’s two arguments, formParams: Registration, and model : Model, are injected into this method by Spring. In the view, we have the following http form.
form copy
Inside of this html code you will see things like ${registration}, th:field=”*{firstName}”, and th:field=”*{lastName}”. These special tags map these input fields to the properties our Registration object that we sent back to the view in the doIndexGet function. When we click on the submit button the setter methods of the registration object are called and the values of the input boxes in the form are inserted into Registration::firstName and Registration::lastName. Then the Registration object is sent back to the server and routed to our doIndexPost method.

Once we are inside of the doIndexPost method, we can add a String to our model class.

model.addAttribute("greet", "Hello ${formParams.firstName} ${formParams.lastName}")

The second argument is the portion that I wish to discuss. Kotlin has String templating which lets us build a String using inline variables. Thus the ${formParams.firstName} will get replaced with the first name entered by the user and ${formParams.lastName} gets replaced with the last name the user entered. Then the function returns with the String “greet” which tells the web application to show the greet page.

doGreetGet

This final function is the shortest. It’s simply a function that handles the request mapping for HTTP Get when the browser navigates to the greet page. However, Kotlin let’s us define functions inline, so it’s worth talking about.

@RequestMapping(path = arrayOf("/greet"), method=arrayOf(RequestMethod.GET))
fun doGreetGet(): String = "greet" //Just tell it to render the greet.html page

All this code does is return the string “greet” so that the web application knows to render the greet.html page. Since it’s literally just returning one value, we can legally write String = “greet” in Kotlin and omit the method body.

Web Pages

For reference purposes, I have included screen shots of the web pages (they don’t seem to render properly when I use the code formatter 😦 sorry readers)!

index.html

index copy
We have already discussed how the Registration object is bound to the html form on this page. However, it’s worth pointing out that this page uses Bootstrap for page layout. Most of the code in this page was auto-generated by Intellij also, which has world class support for Bootstrap.

greeting.html

greet_page copy
This is the other page that get’s returned by the controller after the user enters their name. We built a String in doPostIndex and mapped it to the key “greet” in the model. On this page, we can show that custom greeting by using th:text=”${greet}”. The template engine is smart enough to insert this greeting between the header tags.

Source

You can get the complete source code for this project from my Bitbucket page. Happy coding!

Kotlin Koans—Part 3

The last tutorial’s challange was to take a collection and assemble it into a string using StringBuilder. Java 8 finally gave developers a way to join a String, but Kotlin seems to make it even easier.

This partion of the Kotlin Koans tutorial has us using collection::joinToString. Using Kotlin, we can assemble an entire collection into a String using just one line of code.

fun task2(collection: Collection): String {
    return collection.joinToString(", ", "{", "}")
}

This code is functionally equivalent to what we did in part 2. I also learned a little bit more about the language. Kotlin let’s us have default parameters in our methods. I have to say, while I appreciate Java’s method overloading capabilities, there are times where it’s simplier to use default parameters.

You can click here to see Part 2 or Part 4

Kotlin Koans—Part 2

After doing the first tutorial on Kotlin, I was impressed, but let’s face it, anyone can do a simple “hello world” style program. Nevertheless, I decided to continue with the Kotlin tutorial found at kotlinlang.org. When I moved onto part two of the tutorial, I was really impressed.

It wasn’t that I was super impressed with the language itself. It was IntelliJ’s support of Kotlin that blew me away. When you copy and paste Java code into the IDE, it will offer to translate it to Kotlin for you.

You can see in the video that IntelliJ just did the work of taking the Java code that I copied and pasted into my Kotlin class. I thought this was incredibly slick because it gave me the change to see the differences between Java and Kotlin.

Of course, I wanted to do the exercise myself so that I can get the hang of writing Kotlin code. The problem in this portion of the tutorial was to take this Java code and rewrite as Kotlin code.

public class JavaCode1 extends JavaCode {
    public String task1(Collection collection) {
        StringBuilder sb = new StringBuilder();
        sb.append("{");
        Iterator iterator = collection.iterator();
        while (iterator.hasNext()) {
            Integer element = iterator.next();
            sb.append(element);
            if (iterator.hasNext()) {
                sb.append(", ");
            }
        }
        sb.append("}");
        return sb.toString();
    }
}

It’s not too painful of code. Here is what I ended with when I wrote the code as Kotlin code on my own.

fun todoTask1(collection: Collection): Nothing = TODO(
    """
        Task 1.
        Rewrite JavaCode1.task1 in Kotlin.
        In IntelliJ IDEA, you can just copy-paste the code and agree to automatically convert it to Kotlin,
        but only for this task!
    """,
    references = { JavaCode1().task1(collection) })


fun task1(collection: Collection): String {
    val sb = StringBuilder()
    sb.append("{")
    val iterator = collection.iterator()
    while (iterator.hasNext()){
        val element = iterator.next()
        sb.append(element)
        if (iterator.hasNext()){
            sb.append(", ")
        }
    }
    sb.append("}")
    return sb.toString()
}

There was one thing I noticed about the Kotlin code that I liked. It looks as if we are allowed to have free standing functions in Kotlin outside of a class definition. While I appreciate OOP, there are frankly times where I’m not sure if OOP is the best approach to a problem. This was one of things I really like about Python is that I can break out of OOP when I want.

Now I know that it’s perfectly true that we can use static imports in Java, but I have always felt that was a clumsy approach. Static functions and static imports always seemed more like an after thought to the language that got tacked on after enough people complained. Of course, that’s just a matter of opinion, but anyway, I do like having a choice in Kotlin about when to use classes or just when to use function. Kotlin seems to have included this choice as part of the design of the language right from the get go.

You can click here to see Part 1 and here to see Part 3.

%d bloggers like this: