Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The elegance of Kotlin

The elegance of Kotlin

A quick sample of some of the kotlin features that swept me of my feet and many with me.

Bob Dahlberg

February 07, 2018
Tweet

More Decks by Bob Dahlberg

Other Decks in Programming

Transcript

  1. Bob Dahlberg Isotop - Team Lead Mobile
 Challenge Accepted -

    Founder Who’s Bob?
 - Building software
 - CrossFit Instructor
 - Father
 - Loves challenges!
  2. 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
  3. 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; }
  4. 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 }
  5. 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 }
  6. 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 }
  7. 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 }
  8. 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()
  9. 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; }
  10. 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 }
  11. 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 }
  12. 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 }
  13. 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 }
  14. 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 }
  15. 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); } }
  16. Delegation The java code - kotlin class delegation class Module(

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

    properties class Module { val firstAccess by lazy { System.currentTimeMillis() } }
  18. 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+")"; } }
  19. Less is more The java code - the data class

    data class Person(val name: String, val age: Int)
  20. 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)
  21. 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
  22. 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”