Kotlin Compactness Example from Swift Blog Article

This pro-Swift article came across my RSS feed recently and while I don’t want to do a direct comparison of Swift versus Kotlin since I haven’t done Swift coding I did think it was interesting to point out similar points of efficiency in their simple example built as a product of the Kotlin language compared to others like Java, the language they picked on too.

Now, in their example they were trying to show usage of some simplifying operators compared to Java.  In it we have a Person POJO class that has a name and a favorite sport.  If the sport isn’t null then one should check if the sport isn’t chess, and if both of those conditions are true then one should print out a status line.  Their Java code looks like this:

String favSport = person.getFavoriteSport();
if ((favSport != null) && (!favSport.equals("chess")) {
    System.out.println(person.getFirstName() + "'s favorite sport is " + favSport); 
}

Their Swift code looks like this:

If let favSport = person.getFavoriteSport(),
    favSport != "chess" {
    print("\(person.getFirstName())'s favorite sport is \(favSport\)")
}

This is showing a bunch of advantages over Java, and their main target Objective-C.  In it we have bein gable to conditionally check for null being returned from the method.  We also see the usage of string interpolation of variables.  If we look at the following Kotlin code you’ll see some similar but even more powerful capabilities:

if(person?.favoriteSport?.equals("chess", true)?.not()?:false) {
    println("${person.firstName}'s favorite sport is ${person.favoriteSport}")
} 

First, you see all the question-marks. These aren’t if statements, these are safe call operators as part of Kotlin’s beefed up null safety capabilities . It’s essentially saying “if this object isn’t null call this method, otherwise return null”  At the end of the call is the “?:” operator, known as the Elvis Operator.  This is what is done if the value is null.  By doing this you can create a string of calls which can ultimately lead to the Elvis operator behavior, just as we did here.  This is not at all unique to Kotlin.  You’ll see this in many modern day languages, like C#, but still not Java or Objective-C.

Second you can see the string interpolation syntax in the Kotlin code. Personally, I think it’s far more succinct than Swift’s.  Again you will find string interpolation in C# but not Java.

Third, you’ll see the .not operator.  Because of the way Kotlin’s language is designed it’s very easy to add class extensions easily.  In fact Kotlin allows for functions to be defined outside of classes altogether, like in traditional procedural programming languages. So I can define this printing method out without making some shell class by typing:

fun printData(person:Person) {
    if(person?.favoriteSport?.equals("chess", true)?.not()?:false) {
        println("${person.firstName}'s favorite sport is ${person.favoriteSport}")
    } 
}

Let’s go one step further in looking at the Person data class itself.  Kotlin a concept of data classes which takes out a lot of the heavy lifting that usually went into POJOs.  Let’s say our person class only has two fields, firstName and favoriteSport.  You’ll want to have a field for each, a constructor that takes those values,  getters and setters, overriding equals and hash, and a toString() method.  In traditional Java that looked like this:

public class Person {

    private String firstName;

    private String favoriteSport;

    public Person(String firstName, String favoriteSport) {
        this.firstName = firstName;
        this.favoriteSport = favoriteSport;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getFavoriteSport() {
        return favoriteSport;
    }

    public void setFavoriteSport(String favoriteSport) {
        this.favoriteSport = favoriteSport;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return Objects.equals(firstName, person.firstName) &&
                Objects.equals(favoriteSport, person.favoriteSport);
    }

    @Override
    public int hashCode() {
        return Objects.hash(firstName, favoriteSport);
    }

    @Override
    public String toString() {
        return "Person{" +
                "firstName='" + firstName + '\'' +
                ", favoriteSport='" + favoriteSport + '\'' +
                '}';
    }
}

Thankfully with the extension library Lombok that can be sanely redone as:

@Data
@AllArgsConstructor
public class Person {

    private String firstName;

    private String favoriteSport;
}

Yet Kotlin takes it one step further.  They created a data class system built into the language that takes care of much of this and then some.  That makes the formation of data classes legitimately as small as one line:

data class Person(var firstName:String, var favoriteSport:String?)

It’s the combination of compactness, clarity, and expandability of Kotlin that makes me so keen on this language.  This is a very brief tour of a few highlights of these things.