1 of 45

Why Kotlin?

A language focused on developer delight

2 of 45

  • Built by Jetbrains (Intellij, Android Studio)
  • Java bytecode (Full Interop)
  • OO or Functional
  • Concise
  • Developer Focused
  • First class citizen (Spring and Android)
  • Non-nullable and immutable focus�

3 of 45

Usage

  • Built by Jetbrains, but still open source
  • Almost 6 million users in last year. 13th most popular language, top 5 most loved
  • Used in Gradle, Spring
  • Used by Twitter, Reddit, Netflix, Pinterest, Uber, Coursera, Evernote, Slack, Trello, Tinder, Kickstarter
  • Google’s preferred language for Android App Development
  • Google Home reduced Null Pointer Exceptions by 33% by using more Kotlin�

4 of 45

My Story

5 of 45

Why Kotlin?

6 of 45

Kotlin is Concise

7 of 45

DATA CLASSES - JAVA

final class Pixel {

private final float x;

private final float y;

private int index;

public Pixel(float x, float y, int index){

this.x = x;

this.y = y;

this.index = index;

}

...

}

final class Pixel {

...

public float getX(){

return this.x;

}

public float getY(){

return this.y;

}

public int getIndex(){

return this.index;

}

public void setIndex(int newIndex){

this.index = newIndex;

}

}

8 of 45

DATA CLASSES - KOTLIN

  • Name before Type
  • Constructor
  • Val vs Var

class Pixel(val x: Float, val y: Float, var index: Int)

9 of 45

Property Access

Java

Kotlin

float x = pixel.getX();

pixel.setIndex(10);

val x = pixel.x

pixel.index = 10

10 of 45

Data Classes

  • equals(), hashCode(), toString() with all fields, copy() and more

data class Pixel(val x: Float, val y: Float, val index: Int)

11 of 45

A Quick Note on Functions

public boolean doThing(Pixel pixel) {

fun doThing(pixel: Pixel) : Boolean {

12 of 45

When Statements

public String evaluate(int number, boolean specialCase) {

if (number <= 0){

return "Bad Value";

} else {

return "Default";

}

}

13 of 45

When Statements

public String evaluate(int number, boolean specialCase) {

if (number <= 0){

return "Bad Value";

} else if (number == 2){

return "Double";

} else {

return "Default";

}

}

14 of 45

When Statements

public String evaluate(int number, boolean specialCase) {

if (number <= 0){

return "Bad Value";

} else if (number == 1){

if (specialCase){

return "Special number one!";

}

} else if (number == 2){

return "Double";

} else {

return "Default";

}

}

15 of 45

When Statements

public String evaluate(int number, boolean specialCase) {

if (number <= 0){

return "Bad Value";

} else if (number == 1){

if (specialCase){

return "Special number one!";

} else {

return "Single";

}

} else if (number == 2){

return "Double";

} else {

return "Default";

}

}

16 of 45

When Statements

fun evaluate(number: Int, specialCase: Boolean): String {

return when {

number <= 0 -> "Bad Value"

number == 1 && specialCase -> "Special number one!"

number == 1 -> "Single"

number == 2 -> "Double"

else -> "Default"

}

}

17 of 45

When Statements

fun evaluate(number: Int): String {

return when (number) {

1 -> "Single"

2 -> "Double"

else -> "Default"

}

}

18 of 45

Why Kotlin?

19 of 45

Kotlin is Interoperable

20 of 45

Interoperability

/*

Use any existing library on the JVM, as there’s 100% compatibility, including SAM support.

*/

import io.reactivex.Flowable

import io.reactivex.schedulers.Schedulers

Flowable

.fromCallable {

Thread.sleep(1000) // imitate expensive computation

"Done"

}

.subscribeOn(Schedulers.io())

.observeOn(Schedulers.single())

.subscribe(::println, Throwable::printStackTrace)

21 of 45

Interoperability

  • Java Bytecode
  • Java + Kotlin in the same project (strangler pattern)
  • Copy Java from Stack Overflow, get Kotlin
  • IDE Integration suggests better code

22 of 45

Why Kotlin?

23 of 45

Kotlin can be Non-Nullable

24 of 45

The Billion Dollar Mistake

var output: String

output = null // Compilation error

25 of 45

The Billion Dollar Mistake

var output: String

output = null // Compilation error

// Kotlin protects you from mistakenly operating on nullable types

val name: String? = null // Nullable type

println(name.length()) // Compilation error

26 of 45

The Billion Dollar Mistake

var output: String

output = null // Compilation error

// Kotlin protects you from mistakenly operating on nullable types

val name: String? = null // Nullable type

println(name.length()) // Compilation error

println(name?.length ?: "None")

27 of 45

The Billion Dollar Mistake

var output: String

output = null // Compilation error

// Kotlin protects you from mistakenly operating on nullable types

val name: String? = null // Nullable type

println(name.length()) // Compilation error

println(name?.length ?: "None")

// And if you check a type is right, the compiler will auto-cast it for you

fun calculateTotal(obj: Any) {

if (obj is Game)

obj.calculateTotal()

}

28 of 45

Why Kotlin?

29 of 45

Kotlin can be Functional

30 of 45

Maps and Filters

@Test

fun mapFilterTest() {

val list = listOf(1, 2, 3, 4, 5)

list.map { number -> number + 1 }

list.map { it + 1 }

assertEquals(listOf(2,3,4,5,6), list.map { it + 1 })

val expected = listOf(4, 5, 6)

val actual = list.map { it + 1 }.filter { it > 3 }

assertEquals(expected, actual)

}

31 of 45

Maps and Filters

@Test

fun mapFilterTest() {

val list = listOf(1, 2, 3, 4, 5)

list.map { number -> number + 1 }

list.map { it + 1 }

assertEquals(listOf(2,3,4,5,6), list.map { it + 1 })

val expected = listOf(4, 5, 6)

val actual = list.map { it + 1 }.filter { it > 3 }

assertEquals(expected, actual)

}

32 of 45

Maps and Filters

@Test

fun mapFilterTest() {

val list = listOf(1, 2, 3, 4, 5)

list.map { number -> number + 1 }

list.map { it + 1 }

assertEquals(listOf(2,3,4,5,6), list.map { it + 1 })

val expected = listOf(4, 5, 6)

val actual = list.map { it + 1 }.filter { it > 3 }

assertEquals(expected, actual)

}

33 of 45

Maps and Filters

@Test

fun mapFilterTest() {

val list = listOf(1, 2, 3, 4, 5)

list.map { number -> number + 1 }

list.map { it + 1 }

assertEquals(listOf(2,3,4,5,6), list.map { it + 1 })

val expected = listOf(4, 5, 6)

val actual = list.map { it + 1 }.filter { it > 3 }

assertEquals(expected, actual)

}

34 of 45

Maps and Filters

@Test

fun mapFilterTest() {

val list = listOf(1, 2, 3, 4, 5)

list.map { number -> number + 1 }

list.map { it + 1 }

assertEquals(listOf(2,3,4,5,6), list.map { it + 1 })

val expected = listOf(4, 5, 6)

val actual = list.map { it + 1 }.filter { it > 3 }

assertEquals(expected, actual)

}

35 of 45

Maps and Filters

@Test

fun mapFilterTest() {

val list = listOf(1, 2, 3, 4, 5)

list.map { number -> number + 1 }

list.map { it + 1 }

assertEquals(listOf(2,3,4,5,6), list.map { it + 1 })

val expected = listOf(4, 5, 6)

val actual = list.map { it + 1 }.filter { it > 3 }

assertEquals(expected, actual)

}

36 of 45

Maps and Filters

@Test

fun mapFilterTest() {

val list = listOf(1, 2, 3, 4, 5)

list.map { number -> number + 1 }

list.map { it + 1 }

assertEquals(listOf(2,3,4,5,6), list.map { it + 1 })

val expected = listOf(4, 5, 6)

val actual = list.map { it + 1 }.filter { it > 3 }

assertEquals(expected, actual)

}

37 of 45

Maps and Filters

@Test

fun mapFilterTest() {

val list = listOf(1, 2, 3, 4, 5)

list.map { number -> number + 1 }

list.map { it + 1 }

assertEquals(listOf(2,3,4,5,6), list.map { it + 1 })

val expected = listOf(4, 5, 6)

val actual = list.map { it + 1 }.filter { it > 3 }

assertEquals(expected, actual)

}

38 of 45

First Class Functions

  • No need for classes if you don’t want them
  • Write functions outside of classes, and import and call them elsewhere
  • Pass functions as params to other functions

fun transformList(list: List<String>, transformation: (String) -> String) : List<String> {

return list.map { transformation(it) }

}

val presentTenses = listOf("Jump", "Leap", "Hammer")

39 of 45

First Class Functions

  • No need for classes if you don’t want them
  • Write functions outside of classes, and import and call them elsewhere
  • Pass functions as params to other functions

fun transformList(list: List<String>, transformation: (String) -> String) : List<String> {

return list.map { transformation(it) }

}

val presentTenses = listOf("Jump", "Leap", "Hammer")

val makePastTense: (String) -> String = {present -> present + "ed"}

40 of 45

First Class Functions

  • No need for classes if you don’t want them
  • Write functions outside of classes, and import and call them elsewhere
  • Pass functions as params to other functions

fun transformList(list: List<String>, transformation: (String) -> String) : List<String> {

return list.map { transformation(it) }

}

val presentTenses = listOf("Jump", "Leap", "Hammer")

val makePastTense: (String) -> String = {present -> present + "ed"}

val pastTenses = transformList(presentTenses, makePastTense)

41 of 45

Why Kotlin?

42 of 45

Kotlin is Productive

43 of 45

Other Features

  • Lambdas
  • Extension functions
  • DSLs
  • Smart Cast
  • Objects (essentially singletons)
  • Coroutines (easier* concurrency)
  • Default Arguments
  • Named Arguments

44 of 45

Summary

  • Concise
  • Clean
  • Flexible

45 of 45

Thank you!