Slide 1

Slide 1 text

Welcome to Kotlin Wonderland! Magda Miu @magdamiu Squad Lead Developer at Orange Android Google Developer Expert

Slide 2

Slide 2 text

Agenda Introduction Kotlin Basics Functions Classes Kotlin Essentials

Slide 3

Slide 3 text

Agenda Introduction Kotlin Basics Functions Classes Kotlin Essentials

Slide 4

Slide 4 text

What is Kotlin?

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

What is Kotlin?

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

What is Kotlin? ● General-purpose ● FP + OOP ● Open source (Apache 2.0) ● Developed by JetBrains ● Static typing

Slide 9

Slide 9 text

Kotlin Philosophy To create a modern and pragmatic language for the industry, not an academic one.

Slide 10

Slide 10 text

2010 Project started 2016 Kotlin 1.0 2017 Official on Android 2018 Kotlin 1.3 Aug 2019 Kotlin 1.3.50 Nov 2019 Kotlin 1.3.60 Kotlin timeline

Slide 11

Slide 11 text

Kotlin popularity In the latest Stack Overflow developer survey, it ranks as the 4th most loved programming language.

Slide 12

Slide 12 text

Current adoption Since the release of Kotlin 1.0 in 2016, the number of users has risen to 2.2M.

Slide 13

Slide 13 text

Kotlin in numbers 70+ people Kotlin development team at JetBrains 250+ people independent contributors

Slide 14

Slide 14 text

Kotlin in numbers 57% of users use Kotlin in production 154,525,768 lines of code written in Kotlin on GitHub

Slide 15

Slide 15 text

Build Applications for...

Slide 16

Slide 16 text

Unified tooling Kotlin/JVM Kotlin/JS Kotlin/Native Multiplatform

Slide 17

Slide 17 text

Android apps built with Kotlin

Slide 18

Slide 18 text

Conventions ● The same conventions like on Java ● Uppercase for types ● Lower camelCase for methods and properties ● Semicolons are optional ● Reverse notation for packages ○ A file could contain multiple classes ○ The folder names not have to match the package name

Slide 19

Slide 19 text

Development tools ● JDK ○ JVM 1.6+ ● Kotlin Compiler ● Editor or IDE ○ IntelliJ IDEA, Android Studio, NetBeans, Eclipse

Slide 20

Slide 20 text

*.kt *.java Kotlin compiler Java compiler *.class *.jar App Kotlin is 100% interoperable with Java Kotlin runtime

Slide 21

Slide 21 text

Build tools ● Maven ● Gradle ● Kobalt ● Ant ● Command Line

Slide 22

Slide 22 text

Agenda Introduction Kotlin Basics Functions Classes Kotlin Essentials

Slide 23

Slide 23 text

Basic Types Type Size Double 64 Float 32 Long 64 Int 32 Short 16 Byte 8

Slide 24

Slide 24 text

val vs var ● val is immutable (read-only) and you can only assign a value to them exactly one time. ● var is mutable and can be reassigned. // immediate assignment val countOfEvenNumbers: Int = 10 // `Int` type is inferred var sumOfNumbers = 0 // type required when no initializer is provided var countOfPrimeNumbers: Int // deferred assignment countOfPrimeNumbers = 3 countOfPrimeNumbers = 24

Slide 25

Slide 25 text

String interpolation ● Simple reference uses $ ● Complex references uses ${} ● Raw Strings """ val firstWord = "Learn " val secondWord = "Kotlin" var bothWords = "$firstWord $secondWord" println("$bothWords has ${bothWords.length}") println(""""$bothWords" has ${bothWords.length}""")

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

Null safety ● In an effort to rid the world of NullPointerException, variable types in Kotlin don't allow the assignment of null. ● In order to use a variable that can be null, declare it nullable by adding ? at the end of its type.

Slide 28

Slide 28 text

But wait... The only possible causes of NPE's may be: ● An explicit call to throw NullPointerException() ● Usage of the !! operator (not-null assertion operator) ● Some data inconsistency with regard to initialization ● Java interoperation

Slide 29

Slide 29 text

// check for null in conditions val trainingName: String? = "Learn Kotlin in 45 minutes" if (trainingName != null && trainingName.isNotEmpty()) { print("String of length ${trainingName.length}") } else { print("Empty string") }

Slide 30

Slide 30 text

val platform: String? = null val language = "Kotlin" println(platform?.length) // safe call println(language.length) // unnecessary safe call val lengthOfWord = platform!!.length // !! operator val numberOfLetters: Int? = lengthOfWord as? Int // safe cast

Slide 31

Slide 31 text

val platform: String? = null val language = "Kotlin" println(platform?.length) // safe call println(language.length) // unnecessary safe call val lengthOfWord = platform!!.length // !! operator val numberOfLetters: Int? = lengthOfWord as? Int // safe cast

Slide 32

Slide 32 text

val platform: String? = null val language = "Kotlin" println(platform?.length) // safe call println(language.length) // unnecessary safe call val lengthOfWord = platform!!.length // !! operator val numberOfLetters: Int? = lengthOfWord as? Int // safe cast

Slide 33

Slide 33 text

// Elvis operator val name: String? = null val lengthOfName = name?.length ?: -1 println(lengthOfName)

Slide 34

Slide 34 text

// Elvis operator val name: String? = null val lengthOfName = name?.length ?: -1 println(lengthOfName) // => -1

Slide 35

Slide 35 text

Agenda Introduction Kotlin Basics Functions Classes Kotlin Essentials

Slide 36

Slide 36 text

Let’s have some fun

Slide 37

Slide 37 text

// Kotlin syntax for main function fun main() { println("Hello Kotlin!") }

Slide 38

Slide 38 text

fun add(a: Int, b: Int): Int { return a + b } Function name Parameters Return type Function body

Slide 39

Slide 39 text

// equivalent Kotlin syntax fun add(a: Int, b: Int): Int { return a + b } fun add(a: Int, b: Int): Int = a + b fun add(a: Int, b: Int) = a + b

Slide 40

Slide 40 text

// equivalent Kotlin syntax fun add(a: Int, b: Int): Int { return a + b } fun add(a: Int, b: Int): Int = a + b fun add(a: Int, b: Int) = a + b

Slide 41

Slide 41 text

// equivalent Kotlin syntax fun add(a: Int, b: Int): Int { return a + b } fun add(a: Int, b: Int): Int = a + b fun add(a: Int, b: Int) = a + b

Slide 42

Slide 42 text

// default parameter values fun displayTitleAndName(name: String, prefix: String = "dr") { println("$prefix $name") }

Slide 43

Slide 43 text

// named arguments fun getFullName(firstName: String, lastName: String): String { return "$firstName $lastName" } getFullName(lastName = "Miu", firstName = "Magda")

Slide 44

Slide 44 text

class Utility { // infix functions = functions with a single parameter infix fun String.onto(other: String) = Pair(this, other) } fun main(args: Array) { val blueShoes = "blue".onto("shoes") val yellowScarf = "yellow" onto "scarf" println(blueShoes) // => (blue, shoes) println(yellowScarf) // => (yellow, scarf) }

Slide 45

Slide 45 text

// functions with varargs parameters fun varargExample(vararg names: Int) { println("Argument has ${names.size} elements") } varargExample() // => Argument has 0 elements varargExample(1) // => Argument has 1 elements varargExample(1, 2, 3) // => Argument has 3 elements

Slide 46

Slide 46 text

// high order function = fun with fun or fun returns a fun fun add(a: Int, b: Int): Int { return a + b } fun returnAddFunction(): ((Int, Int) -> Int) { return ::add }

Slide 47

Slide 47 text

Lambda ● A lambda expression or an anonymous function is a “function literal”, i.e. a function that is not declared, but passed immediately as an expression ● A lambda expression is always surrounded by curly braces ● Its parameters (if any) are declared before -> (parameter types may be omitted) ● The body goes after -> (when present)

Slide 48

Slide 48 text

val sum: (Int, Int) -> Int = { a, b -> a + b } println(sum(3,4))

Slide 49

Slide 49 text

val sum: (Int, Int) -> Int = { a, b -> a + b } println(sum(3,4)) // => 7

Slide 50

Slide 50 text

// returning from a lambda val calculateGrade = { grade : Int -> when(grade) { in 0..40 -> "Fail" !is Int -> "Just a grade" in 41..70 -> "Pass" in 71..100 -> "Distinction" else -> false } } println(calculateGrade(57))

Slide 51

Slide 51 text

// returning from a lambda val calculateGrade = { grade : Int -> when(grade) { in 0..40 -> "Fail" !is Int -> "Just a grade" in 41..70 -> "Pass" in 71..100 -> "Distinction" else -> false } } println(calculateGrade(57)) // => Pass

Slide 52

Slide 52 text

Extension functions ● An extension function is a member function of a class that is defined outside the class. ● Extensions are resolved statically and can also be defined with the class type that is nullable. ● If a class contains a companion object, then we can also define extension functions and properties for the companion object.

Slide 53

Slide 53 text

fun String.removeFirstLastChar(): String = this.substring(1, this.length - 1) Receiver type Receiver object

Slide 54

Slide 54 text

fun String.removeFirstLastChar(): String = this.substring(1, this.length - 1) println("Kotlin".removeFirstLastChar())

Slide 55

Slide 55 text

fun String.removeFirstLastChar(): String = this.substring(1, this.length - 1) println("Kotlin".removeFirstLastChar()) // => otli

Slide 56

Slide 56 text

Agenda Introduction Kotlin Basics Functions Classes Kotlin Essentials

Slide 57

Slide 57 text

fun reportError(): Nothing { throw RuntimeException() } fun displayHelloMessage(): Unit { println("Hello from Kotlin! :)") }

Slide 58

Slide 58 text

fun reportError(): Nothing { throw RuntimeException() } fun displayHelloMessage(): Unit { println("Hello from Kotlin! :)") }

Slide 59

Slide 59 text

Basic Data Types Numbers Characters Booleans Arrays Strings Any Nothing Unit

Slide 60

Slide 60 text

Class ● There are primary and secondary constructors. For secondary we should add the keyword constructor ● The primary constructor cannot contain any code.

Slide 61

Slide 61 text

// primary constructor with fullName property (setter & getter) class Person(val fullName: String) { /*...*/ }

Slide 62

Slide 62 text

class Person(val fullName: String) { val age: Int get() { return 18 } // secondary constructor constructor(fullName: String, age: Int) : this(fullName) {} } // instance of the class val john = Person("John", 24)

Slide 63

Slide 63 text

Inheritance ● Inheritance: use open keyword for class ● Overriding methods and properties: use the open modifier open class Person { open val name = "Tom" open fun displaySkills() { } } // inheritance and override class Student : Person() { override val name = "Jerry" override fun displaySkills(){ } }

Slide 64

Slide 64 text

// "object" keyword can be used to create singleton objects. object TheObject { fun hello() = "hello" override fun toString() = "Hello, it's me, ${TheObject::class.simpleName}" } fun useSingletonObject() { println(TheObject.hello()) // => hello val someRef: Any = TheObject println(someRef) // => Hello, it's me, TheObject }

Slide 65

Slide 65 text

Delegation ● Composition over Inheritance design pattern ● Native support for delegation (implicit delegation) ● Zero boilerplate code

Slide 66

Slide 66 text

interface PetAction { fun eat() } interface PetColor { val color: String } object YellowColor : PetColor { override val color = "yellow" }

Slide 67

Slide 67 text

class PrintingPetAction(val food: String) : PetAction { override fun eat() { println(food) } } class Cat(petColor: PetColor = YellowColor) : PetAction by PrintingPetAction("eats a lot of fish"), PetColor by petColor

Slide 68

Slide 68 text

class PrintingPetAction(val food: String) : PetAction { override fun eat() { println(food) } } class Cat(petColor: PetColor = YellowColor) : PetAction by PrintingPetAction("eats a lot of fish"), PetColor by petColor

Slide 69

Slide 69 text

fun delegate() { val kittyCat = Cat() println("Pet has color ${kittyCat.color}") kittyCat.eat() } fun main(args: Array) { delegate() } // => Pet has color yellow // => eats a lot of fish

Slide 70

Slide 70 text

Data classes are a concise way to create classes that just hold data. Data classes Function Price Getters and Setters 0 Lei equals() & hashCode() 0 Lei toString() 0 Lei componentN() 0 Lei copy() 0 Lei TOTAL FREE!

Slide 71

Slide 71 text

data class Character(val name: String, val age: Int) fun main() { val mickeyMouse = Character("Mickey Mouse", 82) val mickeyMouseToday = mickeyMouse.copy(age = 83) // destructuring declarations val (name, age) = mickeyMouseToday println("$name, $age years of age") mickeyMouseToday.component1() // => name mickeyMouseToday.component2() // => age }

Slide 72

Slide 72 text

Companion object ● companion object: syntactically it's similar to the static methods in Java class Person { companion object { fun callMe() = "Call" } } // Person.callMe()

Slide 73

Slide 73 text

Agenda Introduction Kotlin Basics Functions Classes Kotlin Essentials

Slide 74

Slide 74 text

Collections

Slide 75

Slide 75 text

No content

Slide 76

Slide 76 text

// immutable list and mutable list val numbersList = listOf("one", "two", "three") val mutableNumbersList = mutableListOf("one", "two", "three") listOf(1, 5, 3).sum() // => 9 listOf("a", "b", "cc").sumBy { it.length } // => 4 List

Slide 77

Slide 77 text

// immutable set and mutable set val colors = setOf("red", "blue", "yellow") val mutableColors = mutableSetOf("red", "blue", "yellow") val longerThan3 = colors.filter { it.length > 3 } // => [blue, yellow] Set

Slide 78

Slide 78 text

// immutable map and mutable map val desserts = hashMapOf("whipped cream" to "cake", "chocolate" to "cookie") println(desserts["chocolate"]) val inventory = mutableMapOf("pancake" to 1) inventory.put("cake", 3) inventory.remove("pancake") Map

Slide 79

Slide 79 text

// Sequences represent lazily-evaluated collections. val fooSequence = generateSequence(1, { it + 1 }) val x = fooSequence.take(10).toList() println(x) // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] Sequence

Slide 80

Slide 80 text

Collection vs Sequence Source: Collections and sequences in Kotlin by Florina Muntenescu

Slide 81

Slide 81 text

Coroutines

Slide 82

Slide 82 text

Coroutines are lightweight threads

Slide 83

Slide 83 text

Coroutines = Co + Routines Cooperation Functions

Slide 84

Slide 84 text

Single threaded Thread 1 Task 1 Task 2 Task 3 Task 4

Slide 85

Slide 85 text

Multiple threaded Thread 1 Task 1 Task 3 Thread 2 Task 2 Task 4

Slide 86

Slide 86 text

Coroutine Thread 1 Task 1 Task 3 Thread 2 Task 2 Task 4 Result

Slide 87

Slide 87 text

Main advantages of Kotlin ● Readability ○ A code is clean if it is easy to understand ● Interoperability ○ Q: “Can I use my existing libraries?” ○ A: “Yes, absolutely!” ● Safety ○ Prevents some specific type of errors (NPE) ● Tooling ○ Kotlin is a compiled language (IntelliJ IDEA, Android Studio, NetBeans, Eclipse)

Slide 88

Slide 88 text

Best practices 1. Agree on conventions beforehand 2. Don’t treat it as Java with a different syntax 3. Use a linter (like ktlint) 4. Embrace the immutability 5. Reconsider if you need to use !! operator 6. Don’t hide too much info 7. Choose readable over short expressions

Slide 89

Slide 89 text

Kotlin is about developer happiness and productivity.

Slide 90

Slide 90 text

Learn more...

Slide 91

Slide 91 text

No content

Slide 92

Slide 92 text

No content

Slide 93

Slide 93 text

No content

Slide 94

Slide 94 text

No content

Slide 95

Slide 95 text

Thank you! Magda Miu @magdamiu Squad Lead Developer at Orange Android Google Developer Expert