Kotlin - why kotlin and lesson learned
Nodirbek Usmanov
Developer @ DKB Code Factory GmbH
Berlin, 06.09.2019
Table of Contents
1 Table of Contents
2 Introduction
3 Philosophy
4 Java vs Kotlin
5 Variables
6 New instance
8 Collection api
9 Nullsafe
10 Code - a max function
11 Code - finding the oldest person
12 Smartcast
13 Summary
What is Kotlin
Introduction
• since 2010 (release 1.0 on 15.02.2016)
• JVM language*
• developed by Jetbrains (IntelliJ)
• open source
Why Kotlin
Introduction
• 100% interoperable with Java
• statically typed
• concise and less boilerplate code
• target platforms: server-side, android, native, everywhere
where java runs
Why Kotlin
Introduction
• object oriented and functional programming
• solves nullability problem
• higher order functions
• smart casts
Kotlin
Philosophy
pragmatic, concise and safe language
Java
Class with getter/setter/equals/hashcode/toString
1public class Person {
2
3private String name;
4private int age;
5
6public Person(String name, int age) {
7this.name = name;
8this.age = age;
9}
10
11public Person(String name) {
12this.name = name;
13}
14
15public String getName() {
16return name;
17}
18
19public int getAge() {
20return age;
21}
22
23public void setAge(int age) {
24this.age = age;
25}
26
27public boolean equals(Object object) {
28if (this == object) return true;
29if (object == null || getClass() != object.getClass()) return false;
30if (!super.equals(object)) return false;
31Person personJava = (Person) object;
32return age == personJava.age &&
33java.util.Objects.equals(name, personJava.name);
34}
35
36public int hashCode() {
37return Objects.hash(super.hashCode(), name, age);
38}
39
Kotlin
Class with getter/setter/equals/hashcode/toString
1data class Person(val name: String,
2var age: Int? = null)
Kotlin
Variables
1// immutable, not nullable, read-only
2val name: String
3
4// immutable, not mullable, read-only
5val age: Int
Kotlin
Variables
1// immutable, not nullable, read-only
2val name: String
3
4// mutable (can be initialized multiple times), not nullable
5var age: Int
Kotlin
Variables
1// immutable, not nullable, read-only
2val name: String
3
4// mutable, nullable
5var age: Int?
Kotlin
Variables
1// immutable, not nullable, read-only
2val name: String
3
4// mutable, nullable, default value
5var age: Int? = null
Kotlin
new instance
1val person: Person = Person("Bob")
Kotlin
new instance
1val person = Person("Bob")
Kotlin
functions
In mathematics:
f : Z × Z → Z, f (a, b) = a + b (1)
Kotlin
functions
In mathematics:
f : Z × Z → Z, f (a, b) = a + b (2)
In Kotlin:
fun f(a: Int, b: Int) : Int = a + b
Kotlin
functions
1fun f(a:Int, b:Int) : Int {
2return a + b
3}
Kotlin
functions with a return value + type (inference)
1fun f(a:Int, b:Int) = a + b
Kotlin
collection api - creating a read-only list of persons
1val people = listOf(Person("Bob"),
2Person("Tim", age = 40))
Kotlin
collection api - creating a read-only set of persons
1val people = setOf(Person("Bob"),
2Person("Tim", age = 40))
Java
stream - collection processing
List<String> list = people.stream()
.map(Person::getName)
.collect(Collectors.toList());
Java
stream - collection processing
List<String> list = people.stream()
.map(Person::getName)
.collect(Collectors.toList());
Kotlin
real functional approach
val list = people.map{it.name}
Java
stream - collection processing
int total = employees.stream()
collect(Collectors.summingInt(Employee::getSalary)));
Java
stream - collection processing
int total = employees.stream()
collect(Collectors.summingInt(
Employee::getSalary)));
Kotlin
real functional approach
val total = employees.sumBy{it.salary}
Kotlin
Nullsafe - when to return a null
When do you return a null?
(no matter which language)
Kotlin
Nullsafe - when to return a null
• Effective Java suggestion:
• an empty collection instead of null
Kotlin
Nullsafe - when to return a null
• Effective Java suggestion:
• an empty collection instead of null
• What about a function which returns an object and not a
collection?
• Optional with extra overhead for avoiding null
Kotlin
find the problem
fun foo() = length(null)
fun length(s: String): Int {
return s.length
}
Kotlin
No more NPE - if else
fun foo() = length(null)
// <<Compiler>>: Null can not be a value of a non-null type
String
fun length(s: String): Int {
return s.length
}
Kotlin
No more NPE - if else
fun foo() = length(null)
fun length(s: String?): Int {
return if (s != null) s.length else 0
}
Kotlin
No more NPE - elvis operator
fun foo() = length(null)
fun length(s: String?): Int {
return s?.length ?: 0
}
Kotlin
Let’s code - expression over statement
// find the max of two given integer numbers
Kotlin
Let’s code
1fun max(a:Int, b:Int):Int{
2return if (a > b) a else b
3}
Kotlin
Let’s code - concise
1fun max(a:Int, b:Int):Int = if (a > b) a else b
Kotlin
Let’s code - concise
1fun max(a:Int, b:Int) = if (a > b) a else b
Kotlin
Let’s code
1// find the oldest person in a list of persons
2
3data class Person(val name: String,
4val age: Int? = null)
5
6
7fun main(args: Array<String>) {
8
9// 1 - create a list with two persons
10
11// 2 - find the oldest person
12
13// 3 - print the result
14
Kotlin
Let’s code
// find the oldest person
data class Person(val name: String,
val age: Int? = null)
fun main() {
val persons = listOf( ... )
val oldest =
}
// find the oldest person SOLUTION
data class Person(val name: String,
val age: Int? = null)
fun main() {
val persons = listOf(Person("Bob"),
Person("Tim", age = 30))
val oldest = persons.maxBy{ it.age ?: 0 }
println("The oldest is: $oldest")
}
Kotlin
smart cast
1
2open class Vehicle
3
4
5class Boat : Vehicle() {
6fun swim() {
7println("swim")
8}
9}
10
11class Car : Vehicle() {
12fun drive() {
13println("drive")
14}
15}
16
17fun move(veh: Vehicle) {
18if (veh is Car) {
19veh.drive()
20} else if (veh is Boat) {
21veh.swim()
22} else {
23throw IllegalArgumentException()
24}
25}
Kotlin
smart cast
1fun move(veh: Vehicle) {
2if (veh is Car) {
3veh.drive()
4} else if (veh is Boat) {
5veh.swim()
6} else {
7throw IllegalArgumentException()
8}
9}
Kotlin
smart cast with when-constructor
1fun move(veh: Vehicle) {
2when (veh) {
3is Car -> veh.drive()
4is Boat -> veh.swim()
5else -> throw IllegalArgumentException()
6}
7}
Lesson learned
• you can implement a spaghetti code even with kotlin
Lesson learned
• you can implement a spaghetti code even with kotlin
• review in short period and motivate developers to read kotlin
spec./doc
Lesson learned
• you can implement a spaghetti code even with kotlin
• review in short period and motivate developers to read kotlin
spec./doc
• don’t use type? everywhere
Lesson learned
• you can implement a spaghetti code even with kotlin
• review in short period and motivate developers to read kotlin
spec./doc
• don’t use type? everywhere
• avoid .?let
Lesson learned
• you can implement a spaghetti code even with kotlin
• review in short period and motivate developers to read kotlin
spec./doc
• don’t use type? everywhere
• avoid .?let
• no arrow code
Lesson learned
• you can implement a spaghetti code even with kotlin
• review in short period and motivate developers to read kotlin
spec./doc
• don’t use type? everywhere
• avoid .?let
• no arrow code
• fluent testing lib: kotlin-test (especially for param. tests)
Summary I
• Kotlin is a compiled, statically typed language
Summary I
• Kotlin is a compiled, statically typed language
• Interoperable with the ecosystem of Java libraries
• Seamless bi-directional interoperability with Java
Summary I
• Kotlin is a compiled, statically typed language
• Interoperable with the ecosystem of Java libraries
• Seamless bi-directional interoperability with Java
• Code will fail fast — during compilation rather than runtime
• Kotlin offers more compile time safety when compared to a lot of
other statically typed languages
Summary II
• Easy to learn
• Fast and pleasing learning curve for Java developers
• Moving from Java to Kotlin is not only fast, it’s also enjoyable
Summary II
• Easy to learn
• Fast and pleasing learning curve for Java developers
• Moving from Java to Kotlin is not only fast, it’s also enjoyable
• Freedom to mix the imperative and functional styles of
programming
Summary II
• Easy to learn
• Fast and pleasing learning curve for Java developers
• Moving from Java to Kotlin is not only fast, it’s also enjoyable
• Freedom to mix the imperative and functional styles of
programming
• Jetbrains claims that Kotlin code is 40% more concise than
Java
References I
Dmitry Jemerov, Svetlana Isakova.
Kotlin in Action.
Manning Publications Co., 02.2017.
Dr. Venkat Subramaniam.
Programming Kotlin.
O’Reilly UK Ltd., 07.2019.
Pierre-Yves Saumont.
The Joy of Kotlin.
Manning Publications Co., 05.2019.

Kotlin

  • 1.
    Kotlin - whykotlin and lesson learned Nodirbek Usmanov Developer @ DKB Code Factory GmbH Berlin, 06.09.2019
  • 2.
    Table of Contents 1Table of Contents 2 Introduction 3 Philosophy 4 Java vs Kotlin 5 Variables 6 New instance 8 Collection api 9 Nullsafe 10 Code - a max function 11 Code - finding the oldest person 12 Smartcast 13 Summary
  • 3.
    What is Kotlin Introduction •since 2010 (release 1.0 on 15.02.2016) • JVM language* • developed by Jetbrains (IntelliJ) • open source
  • 4.
    Why Kotlin Introduction • 100%interoperable with Java • statically typed • concise and less boilerplate code • target platforms: server-side, android, native, everywhere where java runs
  • 5.
    Why Kotlin Introduction • objectoriented and functional programming • solves nullability problem • higher order functions • smart casts
  • 6.
  • 7.
    Java Class with getter/setter/equals/hashcode/toString 1publicclass Person { 2 3private String name; 4private int age; 5 6public Person(String name, int age) { 7this.name = name; 8this.age = age; 9} 10 11public Person(String name) { 12this.name = name; 13} 14 15public String getName() { 16return name; 17} 18 19public int getAge() { 20return age; 21} 22 23public void setAge(int age) { 24this.age = age; 25} 26 27public boolean equals(Object object) { 28if (this == object) return true; 29if (object == null || getClass() != object.getClass()) return false; 30if (!super.equals(object)) return false; 31Person personJava = (Person) object; 32return age == personJava.age && 33java.util.Objects.equals(name, personJava.name); 34} 35 36public int hashCode() { 37return Objects.hash(super.hashCode(), name, age); 38} 39
  • 8.
    Kotlin Class with getter/setter/equals/hashcode/toString 1dataclass Person(val name: String, 2var age: Int? = null)
  • 9.
    Kotlin Variables 1// immutable, notnullable, read-only 2val name: String 3 4// immutable, not mullable, read-only 5val age: Int
  • 10.
    Kotlin Variables 1// immutable, notnullable, read-only 2val name: String 3 4// mutable (can be initialized multiple times), not nullable 5var age: Int
  • 11.
    Kotlin Variables 1// immutable, notnullable, read-only 2val name: String 3 4// mutable, nullable 5var age: Int?
  • 12.
    Kotlin Variables 1// immutable, notnullable, read-only 2val name: String 3 4// mutable, nullable, default value 5var age: Int? = null
  • 13.
    Kotlin new instance 1val person:Person = Person("Bob")
  • 14.
  • 15.
    Kotlin functions In mathematics: f :Z × Z → Z, f (a, b) = a + b (1)
  • 16.
    Kotlin functions In mathematics: f :Z × Z → Z, f (a, b) = a + b (2) In Kotlin: fun f(a: Int, b: Int) : Int = a + b
  • 17.
    Kotlin functions 1fun f(a:Int, b:Int): Int { 2return a + b 3}
  • 18.
    Kotlin functions with areturn value + type (inference) 1fun f(a:Int, b:Int) = a + b
  • 19.
    Kotlin collection api -creating a read-only list of persons 1val people = listOf(Person("Bob"), 2Person("Tim", age = 40))
  • 20.
    Kotlin collection api -creating a read-only set of persons 1val people = setOf(Person("Bob"), 2Person("Tim", age = 40))
  • 22.
    Java stream - collectionprocessing List<String> list = people.stream() .map(Person::getName) .collect(Collectors.toList());
  • 23.
    Java stream - collectionprocessing List<String> list = people.stream() .map(Person::getName) .collect(Collectors.toList()); Kotlin real functional approach val list = people.map{it.name}
  • 24.
    Java stream - collectionprocessing int total = employees.stream() collect(Collectors.summingInt(Employee::getSalary)));
  • 25.
    Java stream - collectionprocessing int total = employees.stream() collect(Collectors.summingInt( Employee::getSalary))); Kotlin real functional approach val total = employees.sumBy{it.salary}
  • 26.
    Kotlin Nullsafe - whento return a null When do you return a null? (no matter which language)
  • 27.
    Kotlin Nullsafe - whento return a null • Effective Java suggestion: • an empty collection instead of null
  • 28.
    Kotlin Nullsafe - whento return a null • Effective Java suggestion: • an empty collection instead of null • What about a function which returns an object and not a collection? • Optional with extra overhead for avoiding null
  • 29.
    Kotlin find the problem funfoo() = length(null) fun length(s: String): Int { return s.length }
  • 30.
    Kotlin No more NPE- if else fun foo() = length(null) // <<Compiler>>: Null can not be a value of a non-null type String fun length(s: String): Int { return s.length }
  • 31.
    Kotlin No more NPE- if else fun foo() = length(null) fun length(s: String?): Int { return if (s != null) s.length else 0 }
  • 32.
    Kotlin No more NPE- elvis operator fun foo() = length(null) fun length(s: String?): Int { return s?.length ?: 0 }
  • 33.
    Kotlin Let’s code -expression over statement // find the max of two given integer numbers
  • 34.
    Kotlin Let’s code 1fun max(a:Int,b:Int):Int{ 2return if (a > b) a else b 3}
  • 35.
    Kotlin Let’s code -concise 1fun max(a:Int, b:Int):Int = if (a > b) a else b
  • 36.
    Kotlin Let’s code -concise 1fun max(a:Int, b:Int) = if (a > b) a else b
  • 37.
    Kotlin Let’s code 1// findthe oldest person in a list of persons 2 3data class Person(val name: String, 4val age: Int? = null) 5 6 7fun main(args: Array<String>) { 8 9// 1 - create a list with two persons 10 11// 2 - find the oldest person 12 13// 3 - print the result 14
  • 38.
    Kotlin Let’s code // findthe oldest person data class Person(val name: String, val age: Int? = null) fun main() { val persons = listOf( ... ) val oldest = }
  • 39.
    // find theoldest person SOLUTION data class Person(val name: String, val age: Int? = null) fun main() { val persons = listOf(Person("Bob"), Person("Tim", age = 30)) val oldest = persons.maxBy{ it.age ?: 0 } println("The oldest is: $oldest") }
  • 40.
    Kotlin smart cast 1 2open classVehicle 3 4 5class Boat : Vehicle() { 6fun swim() { 7println("swim") 8} 9} 10 11class Car : Vehicle() { 12fun drive() { 13println("drive") 14} 15} 16 17fun move(veh: Vehicle) { 18if (veh is Car) { 19veh.drive() 20} else if (veh is Boat) { 21veh.swim() 22} else { 23throw IllegalArgumentException() 24} 25}
  • 41.
    Kotlin smart cast 1fun move(veh:Vehicle) { 2if (veh is Car) { 3veh.drive() 4} else if (veh is Boat) { 5veh.swim() 6} else { 7throw IllegalArgumentException() 8} 9}
  • 42.
    Kotlin smart cast withwhen-constructor 1fun move(veh: Vehicle) { 2when (veh) { 3is Car -> veh.drive() 4is Boat -> veh.swim() 5else -> throw IllegalArgumentException() 6} 7}
  • 43.
    Lesson learned • youcan implement a spaghetti code even with kotlin
  • 44.
    Lesson learned • youcan implement a spaghetti code even with kotlin • review in short period and motivate developers to read kotlin spec./doc
  • 45.
    Lesson learned • youcan implement a spaghetti code even with kotlin • review in short period and motivate developers to read kotlin spec./doc • don’t use type? everywhere
  • 46.
    Lesson learned • youcan implement a spaghetti code even with kotlin • review in short period and motivate developers to read kotlin spec./doc • don’t use type? everywhere • avoid .?let
  • 47.
    Lesson learned • youcan implement a spaghetti code even with kotlin • review in short period and motivate developers to read kotlin spec./doc • don’t use type? everywhere • avoid .?let • no arrow code
  • 48.
    Lesson learned • youcan implement a spaghetti code even with kotlin • review in short period and motivate developers to read kotlin spec./doc • don’t use type? everywhere • avoid .?let • no arrow code • fluent testing lib: kotlin-test (especially for param. tests)
  • 49.
    Summary I • Kotlinis a compiled, statically typed language
  • 50.
    Summary I • Kotlinis a compiled, statically typed language • Interoperable with the ecosystem of Java libraries • Seamless bi-directional interoperability with Java
  • 51.
    Summary I • Kotlinis a compiled, statically typed language • Interoperable with the ecosystem of Java libraries • Seamless bi-directional interoperability with Java • Code will fail fast — during compilation rather than runtime • Kotlin offers more compile time safety when compared to a lot of other statically typed languages
  • 52.
    Summary II • Easyto learn • Fast and pleasing learning curve for Java developers • Moving from Java to Kotlin is not only fast, it’s also enjoyable
  • 53.
    Summary II • Easyto learn • Fast and pleasing learning curve for Java developers • Moving from Java to Kotlin is not only fast, it’s also enjoyable • Freedom to mix the imperative and functional styles of programming
  • 54.
    Summary II • Easyto learn • Fast and pleasing learning curve for Java developers • Moving from Java to Kotlin is not only fast, it’s also enjoyable • Freedom to mix the imperative and functional styles of programming • Jetbrains claims that Kotlin code is 40% more concise than Java
  • 55.
    References I Dmitry Jemerov,Svetlana Isakova. Kotlin in Action. Manning Publications Co., 02.2017. Dr. Venkat Subramaniam. Programming Kotlin. O’Reilly UK Ltd., 07.2019. Pierre-Yves Saumont. The Joy of Kotlin. Manning Publications Co., 05.2019.