Slide 1

Slide 1 text


 The elegance of Kotlin Bob Dahlberg

Slide 2

Slide 2 text

Bob Dahlberg Isotop - Team Lead Mobile
 Challenge Accepted - Founder Who’s Bob?
 - Building software
 - CrossFit Instructor
 - Father
 - Loves challenges!

Slide 3

Slide 3 text

Background Android development Kotlin since late 2015 Studied Java 5 in School
 Developed Android with Java 6
 Found Scala..
 Found Kotlin!
 Still stuck on Java 6 in Android

Slide 4

Slide 4 text

Let’s see some code!

Slide 5

Slide 5 text

I’t might be null The java code // Not to unusual java-style snippet public boolean hasQuality(Stream stream) { boolean quality = false; if (stream != null && stream.getUri() != null){ String query = stream.getUri().getQuery(); if (query != null) { quality = query.contains("quality"); } } return quality; }

Slide 6

Slide 6 text

I’t might be null The java code - auto convert to kotlin // Automatically converted to Kotlin fun hasQuality(stream: Stream?): Boolean { var quality = false if (stream != null && stream.uri != null) { val query = stream.uri!!.query if (query != null) { quality = query.contains("quality") } } return quality }

Slide 7

Slide 7 text

I’t might be null The java code - auto convert to kotlin - use the nullable type // Manually improved to use the nullable type fun hasQuality(stream: Stream?): Boolean { var quality = false val query: String? = stream?.uri?.query if (query != null) { quality = query.contains(“quality”) } return quality }

Slide 8

Slide 8 text

I’t might be null The java code - auto convert to kotlin - use the nullable type - if as expression // If as an expression fun hasQuality(stream: Stream?): Boolean { val query: String? = stream?.uri?.query return if(query != null) { query.contains(“quality”) } else false }

Slide 9

Slide 9 text

I’t might be null The java code - auto convert to kotlin - use the nullable type - if as expression - no explicit null-checks // No explicit null-checks fun hasQuality(stream: Stream?): Boolean { return stream?.uri?.query?.contains(“quality”) ?: false }

Slide 10

Slide 10 text

I’t might be null The java code - auto convert to kotlin - use the nullable type - if as expression - no explicit null-checks - three styles of the function // 1. Regular function fun hasQuality(stream: Stream?): Boolean { return stream?.uri?.query?.contains(“quality”) ?: false } // 2. The return type us inferred from the expression fun hasQuality(stream: Stream?) = stream?.uri?.query?.contains(“quality”) == true // 3 Extension function fun Stream.hasQuality() = uri?.query?.contains(“quality”) == true myStream?.hasQuality()

Slide 11

Slide 11 text

Next example

Slide 12

Slide 12 text

If ifs and buts.. The java code public Grade parse(Object from) { if (from instanceof Integer) { if ((int) from <= 5 && (int) from > 0) { return new Grade((int) from); } } else if (from instanceof Character) { if ((char) from <= 'f' && (char) from >= 'a') { return new Grade((char) from); } } else if (from == "G" || from == "VG" || from == "MVG"){ return new Grade((String) from); } return Grade.FAIL; }

Slide 13

Slide 13 text

If ifs and buts.. The java code - translated fun parse(from: Any): Grade { if (from is Int) { if (from as Int <= 5 && from as Int > 0) { return Grade(from as Int) } } else if (from is Char) { if (from as Char <= 'f' && from as Char >= 'a') { return Grade(from as Char) } } else if (from == "G" || from == "VG" || from == "MVG"){ return Grade(from as String) } return Grade.FAIL }

Slide 14

Slide 14 text

If ifs and buts.. The java code - translated - smart cast fun parse(from: Any): Grade { if (from is Int) { if (from <= 5 && from > 0) { return Grade(from) } } else if (from is Char) { if (from <= 'f' && from >= 'a') { return Grade(from) } } else if (from == "G" || from == "VG" || from == "MVG"){ return Grade(from as String) } return Grade.FAIL }

Slide 15

Slide 15 text

If ifs and buts.. The java code - translated - smart cast - ranges fun parse(from: Any): Grade { if (from is Int) { if (from in 1..5) { return Grade(from) } } else if (from is Char) { if (from in 'a'..’f’) { return Grade(from) } } else if (from == "G" || from == "VG" || from == "MVG"){ return Grade(from as String) } return Grade.FAIL }

Slide 16

Slide 16 text

If ifs and buts.. The java code - translated - smart cast - ranges - when fun parse(from: Any): Grade { return when (from) { is Int -> if (from in 1..5) Grade(from) else Grade.FAIL is Char -> if (from in ‘a'..’f’) Grade(from) else Grade.FAIL “G”, “VG”, “MVG" -> Grade(from as String) else -> Grade.FAIL }

Slide 17

Slide 17 text

If ifs and buts.. The java code - translated - smart cast - ranges - when - done fun parse(from: Any) = when (from) { in 1..5 -> Grade(from as Int) in ‘a’..’f’ -> Grade(from as Char) “G”, “VG”, “MVG" -> Grade(from as String) else -> Grade.FAIL }

Slide 18

Slide 18 text

Next example

Slide 19

Slide 19 text

Delegation The java code class Module extends Controller implements Dispatcher { private final Dispatcher _dispatcher; public Module(Dispatcher dispatcher { _dispatcher = dispatcher; } @Override public void addListener(Listener listener) { _dispatcher.addListener(listener); } @Override public void removeListener(Listener listener) { _dispatcher.removeListener(listener); } @Override public void dispatchEvent(Event event) { _dispatcher.dispatchEvent(event); } }

Slide 20

Slide 20 text

Delegation The java code - kotlin class delegation class Module( private val dispatcher: Dispatcher ): Controller(), Dispatcher by dispatcher

Slide 21

Slide 21 text

Delegation The java code - kotlin class delegation - delegation properties class Module { val firstAccess by lazy { System.currentTimeMillis() } }

Slide 22

Slide 22 text

Next example

Slide 23

Slide 23 text

Less is more The java code public class Person { private final String name; private final int age; public Person(String name, int age) { this.name = name; this.age = age; } public int getAge() { return age; } public String getName() { return name; } @Override public boolean equals(Object other) { /*check equality*/ } @Override public int hashCode() { /*generate unique hash*/ } @Override public String toString() { return "Person("+name+", "+age+")"; } }

Slide 24

Slide 24 text

Less is more The java code - the data class data class Person(val name: String, val age: Int)

Slide 25

Slide 25 text

Less is more The java code - the data class - copy data class Person(val name: String, val age: Int) val bob = Person("Bob", 33) val workingBob = bob.copy() val agingBob = bob.copy(age=66)

Slide 26

Slide 26 text

Less is more The java code - the data class - copy - deconstructing data class Person(val name: String, val age: Int) val bob = Person("Bob", 33) val workingBob = bob.copy() val agingBob = bob.copy(age=66) val (_,age) = bob

Slide 27

Slide 27 text

Less is more The java code - the data class - copy - deconstructing - operation overloading data class Person(val name: String, val age: Int) operator fun Person.plus(extra:String) = copy(“$name $extra”) val bob = Person("Bob", 33) val fullNameBob = bob + “Dahlberg”

Slide 28

Slide 28 text

Thank you

Slide 29

Slide 29 text

Bob Dahlberg @mr_bob - twitter @dahlberg.bob - medium.com [email protected] Thanks!