Slide 1

Slide 1 text

Kotlin, What Is It? ! Cody Engel

Slide 2

Slide 2 text

Cody Engel NIU Computer Science Alum

Slide 3

Slide 3 text

Blogging, It’s A Helluva Drug (Also got into programming through editing Wordpress themes)

Slide 4

Slide 4 text

Android 2.2 Started Android Development when this was the dominant version.

Slide 5

Slide 5 text

Started Learning Kotlin End of 2016

Slide 6

Slide 6 text

Convinced Team to Use Kotlin in 2017

Slide 7

Slide 7 text

Joined a Kotlin-only Android Team 2018

Slide 8

Slide 8 text

All aboard the Kotlin hype-train. BreadLord

Slide 9

Slide 9 text

Kotlin, A Brief History

Slide 10

Slide 10 text

–Dmitry Jemerov, August 2, 2011 “We (JetBrains) want to become more productive by switching to a more expressive language.”

Slide 11

Slide 11 text

Kotlin Named after the Russian island, Kotlin.

Slide 12

Slide 12 text

Java Named after the Indonesian island of Java.

Slide 13

Slide 13 text

Kotlin v1.0 released on February 15, 2016.

Slide 14

Slide 14 text

Cody decides to start learning Kotlin in December 2016.

Slide 15

Slide 15 text

Google I/O 2017 Kotlin officially supported by Google for Android development.

Slide 16

Slide 16 text

Kotlin v1.2 released on November 28, 2017. Multiplatform Projects pick up steam.

Slide 17

Slide 17 text

Kotlin 1.3 Coroutines will graduate from experimental to stable.

Slide 18

Slide 18 text

Kotlin Basics (Less is More)

Slide 19

Slide 19 text

Functions

Slide 20

Slide 20 text

fun sum(a: Int, b: Int): Int { return a + b } Functions

Slide 21

Slide 21 text

fun sum(a: Int, b: Int) = a + b Functions

Slide 22

Slide 22 text

fun printSum(a: Int, b: Int): Unit { println("sum of $a and $b is ${a + b}") } Functions

Slide 23

Slide 23 text

fun printSum(a: Int, b: Int) { println("sum of $a and $b is ${a + b}") } Functions

Slide 24

Slide 24 text

Variables

Slide 25

Slide 25 text

val immutableNumber: Int = 1 Variables

Slide 26

Slide 26 text

val immutableNumber = 1 Variables

Slide 27

Slide 27 text

var mutableNumber = 5 mutableNumber = 54 Variables

Slide 28

Slide 28 text

String Templates

Slide 29

Slide 29 text

var a = 1 val s1 = "a is $a" // a is 1 String Templates

Slide 30

Slide 30 text

a = 2 val s2 = "${s1.replace("is", "was")}, but now is $a” // a was 1 but now is 2 String Templates

Slide 31

Slide 31 text

Conditional Expressions

Slide 32

Slide 32 text

fun maxOf(a: Int, b: Int): Int { if (a > b) { return a } else { return b } } Conditional Expressions

Slide 33

Slide 33 text

fun maxOf(a: Int, b: Int) = if (a > b) a else b Conditional Expressions

Slide 34

Slide 34 text

Handling Null

Slide 35

Slide 35 text

val maybeNull: String? = null val notNull: String = if (maybeNull != null) maybeNull else "" Handling Null

Slide 36

Slide 36 text

val maybeNull: String? = null val notNull: String = maybeNull ?: "" Handling Null

Slide 37

Slide 37 text

val maybeNull: String? = null val length: Int = maybeNull?.length ?: 0 Handling Null

Slide 38

Slide 38 text

val listWithNulls: List = listOf("Kotlin", null) for (item in listWithNulls) { item?.let { println(it) } //prints Kotlin and ignores null } Handling Null

Slide 39

Slide 39 text

Type Casting

Slide 40

Slide 40 text

if (x instanceof Integer) { System.out.print((Integer) x + 1); } else if (x instanceof String) { System.out.print(((String) x).length() + 1); } else if (x instanceof List) { Integer total = 0; for (Integer i : (List) x) { total += i; } System.out.print(total); } Type Casting

Slide 41

Slide 41 text

if (x is Int) { print(x + 1) } else if (x is String) { print(x.length + 1) } else if (x is IntArray) { print(x.sum()) } Type Casting

Slide 42

Slide 42 text

when (x) { is Int -> print(x + 1) is String -> print(x.length + 1) is IntArray -> print(x.sum()) } Type Casting

Slide 43

Slide 43 text

Classes in Kotlin (Easier to Represent Data)

Slide 44

Slide 44 text

–KotlinLang.org - Data Classes Documentation “We frequently create classes whose main purpose is to hold data. In such a class some standard functionality and utility functions are often mechanically derivable from the data. In Kotlin, this is called a data class.”

Slide 45

Slide 45 text

public class Person { private final String name; private final int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } } Data Classes

Slide 46

Slide 46 text

public class Person { private final String name; private final int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } // but wait… there’s more! @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); } @Override public int hashCode() { return Objects.hash(name, age); } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } } Data Classes

Slide 47

Slide 47 text

data class Person(val name: String, val age: Int) Data Classes

Slide 48

Slide 48 text

val person = Person("Cody", "56") person.age person.name person.equals(anotherPerson) person.hashCode() person.toString() person.copy(name = "Bob") (name, age) = person Data Classes

Slide 49

Slide 49 text

–KotlinLang.org - Sealed Classes Documentation “Sealed classes are used for representing restricted class hierarchies, when a value can have one of the types from a limited set, but cannot have any other type. They are, in a sense, an extension of enum classes: the set of values for an enum type is also restricted, but each enum constant exists only as a single instance, whereas a subclass of a sealed class can have multiple instances which can contain state.”

Slide 50

Slide 50 text

–Cody Engel - Kotlin Lunch & Learn “Sealed classes are used for representing restricted class hierarchies. They are similar to enums, except they can have multiple instances of the same type.”

Slide 51

Slide 51 text

sealed class Expr data class Const(val number: Double) : Expr() data class Sum(val firstNum: Expr, val secondNum: Expr) : Expr() object NotANumber : Expr() Sealed Classes

Slide 52

Slide 52 text

fun eval(expr: Expr): Double = when(expr) { is Const -> expr.number is Sum -> eval(expr.firstNum) + eval(expr.secondNum) NotANumber -> Double.NaN // an `else` clause is not required because we've covered all the cases } Sealed Classes

Slide 53

Slide 53 text

Default Values

Slide 54

Slide 54 text

class ImageCache( val timeRetrieved: Long, val wasSuccessful: Boolean, val cacheExpirationMs: Long = 300000 ) Default Values

Slide 55

Slide 55 text

class ImageCache( val timeRetrieved: Long, val wasSuccessful: Boolean, val cacheExpirationMs: Long = 300000 ) val imageCache = ImageCache( timeRetrieved = 40, wasSuccessful = false ) val imageCache = ImageCache( timeRetrieved = 40, wasSuccessful = false, cacheExpirationMs = 5000 ) Default Values

Slide 56

Slide 56 text

Extensions (Less Utils and Better Null Safety)

Slide 57

Slide 57 text

Totally Fictitious API Response { "p_admin": "1", "pg_list_add": "1", "pg_list_edit": “0", "pg_list_delete": "1", "pg_list_headers": "0", "pg_list_emailaccount": "1", "pg_list_bounce": "1", "pg_message_add": "1", "pg_message_edit": null, "pg_message_delete": "0" }

Slide 58

Slide 58 text

Extension Property

Slide 59

Slide 59 text

val String.asBoolean: Boolean get() = this != “0" //… val pAdmin: String = "1" pAdmin.asBoolean Extension Property

Slide 60

Slide 60 text

val String?.asBoolean: Boolean get() = this != null && this != "0" //… val pAdmin: String? = null pAdmin.asBoolean Extension Property

Slide 61

Slide 61 text

Extension Function

Slide 62

Slide 62 text

fun MutableList.swap(index1: Int, index2: Int) { val tmp = this[index1] this[index1] = this[index2] this[index2] = tmp } //… val myList = mutableListOf(55, 32, 45) myList.swap(0, 2) Extension Function

Slide 63

Slide 63 text

Delegation (Composition Over Inheritance)

Slide 64

Slide 64 text

Property Delegation

Slide 65

Slide 65 text

private ExpensiveObjectToCreate _expensiveObject = null; ExpensiveObjectToCreate getExpensiveObject() { if (_expensiveObject == null) { _expensiveObject = new ExpensiveObjectToCreate(); } return _expensiveObject; } Property Delegation

Slide 66

Slide 66 text

val expensiveObject by lazy { ExpensiveObjectToCreate() } Property Delegation

Slide 67

Slide 67 text

private class SynchronizedLazyImpl(initializer: () -> T, lock: Any? = null) : Lazy, Serializable { private var initializer: (() -> T)? = initializer @Volatile private var _value: Any? = UNINITIALIZED_VALUE // final field is required to enable safe publication of constructed instance private val lock = lock ?: this override val value: T get() { val _v1 = _value if (_v1 !== UNINITIALIZED_VALUE) { @Suppress("UNCHECKED_CAST") return _v1 as T } return synchronized(lock) { val _v2 = _value if (_v2 !== UNINITIALIZED_VALUE) { @Suppress("UNCHECKED_CAST") (_v2 as T) } else { val typedValue = initializer!!() _value = typedValue initializer = null typedValue } } } override fun isInitialized(): Boolean = _value !== UNINITIALIZED_VALUE override fun toString(): String = if (isInitialized()) value.toString() else "Lazy value not initialized yet." private fun writeReplace(): Any = InitializedLazyImpl(value) } Property Delegation

Slide 68

Slide 68 text

Cody’s Animal App …Or the best example he could think of for class delegation.

Slide 69

Slide 69 text

interface Communicate { fun communicate() } class CatCommunicator() : Communicate { override fun communicate() { println("Meow") } } class DogCommunicator() : Communicate { override fun communicate() { println("Woof") } } class Animal(communicate: Communicate) : Communicate by communicate fun main(args: Array) { val catCommunicator = CatCommunicator() val dogCommunicator = DogCommunicator() Animal(catCommunicator).communicate() // Meow Animal(dogCommunicator).communicate() // Woof } Class Delegation

Slide 70

Slide 70 text

interface Communicate { fun communicate() } class CatCommunicator() : Communicate { override fun communicate() { println("Meow") } } class DogCommunicator() : Communicate { override fun communicate() { println("Woof") } } class Animal(communicate: Communicate) : Communicate by communicate fun main(args: Array) { val catCommunicator = CatCommunicator() val dogCommunicator = DogCommunicator() Animal(catCommunicator).communicate() // Meow Animal(dogCommunicator).communicate() // Woof } Class Delegation

Slide 71

Slide 71 text

interface Communicate { fun communicate() } class CatCommunicator() : Communicate { override fun communicate() { println("Meow") } } class DogCommunicator() : Communicate { override fun communicate() { println("Woof") } } class Animal(communicate: Communicate) : Communicate by communicate fun main(args: Array) { val catCommunicator = CatCommunicator() val dogCommunicator = DogCommunicator() Animal(catCommunicator).communicate() // Meow Animal(dogCommunicator).communicate() // Woof } Class Delegation

Slide 72

Slide 72 text

interface Communicate { fun communicate() } class CatCommunicator() : Communicate { override fun communicate() { println("Meow") } } class DogCommunicator() : Communicate { override fun communicate() { println("Woof") } } class Animal(communicate: Communicate) : Communicate by communicate fun main(args: Array) { val catCommunicator = CatCommunicator() val dogCommunicator = DogCommunicator() Animal(catCommunicator).communicate() // Meow Animal(dogCommunicator).communicate() // Woof } Class Delegation

Slide 73

Slide 73 text

interface Communicate { fun communicate() } class CatCommunicator() : Communicate { override fun communicate() { println("Meow") } } class DogCommunicator() : Communicate { override fun communicate() { println("Woof") } } class Animal(communicate: Communicate) : Communicate by communicate fun main(args: Array) { val catCommunicator = CatCommunicator() val dogCommunicator = DogCommunicator() Animal(catCommunicator).communicate() // Meow Animal(dogCommunicator).communicate() // Woof } Class Delegation

Slide 74

Slide 74 text

interface Communicate { fun communicate() } class CatCommunicator() : Communicate { override fun communicate() { println("Meow") } } class DogCommunicator() : Communicate { override fun communicate() { println("Woof") } } class Animal(communicate: Communicate) : Communicate by communicate fun main(args: Array) { val catCommunicator = CatCommunicator() val dogCommunicator = DogCommunicator() Animal(catCommunicator).communicate() // Meow Animal(dogCommunicator).communicate() // Woof } Class Delegation

Slide 75

Slide 75 text

Higher Order Functions (Because Functional is Quite Functional)

Slide 76

Slide 76 text

–Wikipedia “In mathematics and computer science, a higher-order function (also functional, functional form or functor) is a function that does at least one of the following: takes one or more functions as arguments (i.e. procedural parameters), returns a function as its result.”

Slide 77

Slide 77 text

Sandwich Code

Slide 78

Slide 78 text

Sandwich Code

Slide 79

Slide 79 text

val start = System.currentTimeMillis() BreadLord.whatShouldMobileWorkOnThisWeek() val executionTime = System.currentTimeMillis() - start Sandwich Code

Slide 80

Slide 80 text

val executionTime = measureTimeMillis { BreadLord.whatShouldMobileWorkOnThisWeek() } Sandwich Code

Slide 81

Slide 81 text

public fun measureTimeMillis(block: () -> Unit) : Long { val start = System.currentTimeMillis() block() return System.currentTimeMillis() - start } Sandwich Code

Slide 82

Slide 82 text

public inline fun measureTimeMillis(block: () -> Unit) : Long { val start = System.currentTimeMillis() block() return System.currentTimeMillis() - start } Sandwich Code

Slide 83

Slide 83 text

Delayed Execution

Slide 84

Slide 84 text

fun printNumbers(oneMillionNumbers: List) { oneMillionNumbers.forEach { number -> println(number) } } Delayed Execution

Slide 85

Slide 85 text

val oneMillionNumbers = (0..1000000).toList() printNumbers(oneMillionNumbers) Delayed Execution

Slide 86

Slide 86 text

fun oneMillionNumbers(): () -> List = { (0..1000000).toList() } printNumbers(oneMillionNumbers()) Delayed Execution

Slide 87

Slide 87 text

Kotlin Core Libraries (Because Free is Usually Better)

Slide 88

Slide 88 text

Collections

Slide 89

Slide 89 text

(0..1000000) .filter { it % 2 == 0 } .map { it.toString() } .map { Pair(it, it.length) } Collections

Slide 90

Slide 90 text

(0..1000000) .filter { it % 2 == 0 } .map { it.toString() } .map { Pair(it, it.length) } // 3 Lists, Expensive! Collections

Slide 91

Slide 91 text

Sequence

Slide 92

Slide 92 text

(0..1000000) .asSequence() .filter { it % 2 == 0 } .map { it.toString() } .map { Pair(it, it.length) } .toList() Sequence

Slide 93

Slide 93 text

(0..1000000) .asSequence() .filter { it % 2 == 0 } .map { it.toString() } .map { Pair(it, it.length) } .toList() // 1 List, Sorta Cheap ¯\_(ツ)_/¯ Sequence

Slide 94

Slide 94 text

Kotlin Core Libraries kotlin Core functions and types, available on all supported platforms. kotlin.annotation Library support for the Kotlin annotation facility. kotlin.browser - JS Access to top-level properties (document, window etc.) in the browser environment. kotlin.collections Collection types, such as Iterable, Collection, List, Set, Map and related top-level and extension functions. kotlin.comparisons Helper functions for creating Comparator instances. kotlin.concurrent - JVM Utility functions for concurrent programming. kotlin.coroutines.experimental Library support for coroutines, including support for lazy sequences. kotlin.coroutines.experimental.intrinsics Low-level building blocks for libraries that provide coroutine-based APIs. kotlin.dom - JS Utility functions for working with the browser DOM. kotlin.experimental Experimental APIs, subject to change in future versions of Kotlin. kotlin.io IO API for working with files and streams. kotlin.js - JS Functions and other APIs specific to the JavaScript platform. kotlin.jvm - JVM Functions and annotations specific to the Java platform. kotlin.math Mathematical functions and constants. kotlin.properties Standard implementations of delegates for delegated properties and helper functions for implementing custom delegates. kotlin.ranges Ranges, Progressions and related top-level and extension functions. kotlin.reflect Runtime API for Kotlin reflection kotlin.reflect.full - JVM Extensions for Kotlin reflection provided by kotlin-reflect library. kotlin.reflect.jvm - JVM Runtime API for interoperability between Kotlin reflection and Java reflection provided by kotlin-reflect library. kotlin.sequences Sequence type that represents lazily evaluated collections. Top-level functions for instantiating sequences and extension functions for sequences. kotlin.streams - JVM Utility functions for working with Java 8 streams. kotlin.system - JVM System-related utility functions. kotlin.text Functions for working with text and regular expressions. org.khronos.webgl - JS Kotlin JavaScript wrappers for the WebGL API. org.w3c.dom - JS Kotlin JavaScript wrappers for the DOM API. org.w3c.dom.css - JS Kotlin JavaScript wrappers for the DOM CSS API. org.w3c.dom.events - JS Kotlin JavaScript wrappers for the DOM events API. org.w3c.dom.parsing - JS Kotlin JavaScript wrappers for the DOM parsing API. org.w3c.dom.svg - JS Kotlin JavaScript wrappers for the DOM SVG API. org.w3c.dom.url - JS Kotlin JavaScript wrappers for the DOM URL API. org.w3c.fetch - JS Kotlin JavaScript wrappers for the W3C fetch API. org.w3c.files - JS Kotlin JavaScript wrappers for the W3C file API. org.w3c.notifications - JS Kotlin JavaScript wrappers for the Web Notifications API. org.w3c.performance - JS Kotlin JavaScript wrappers for the Navigation Timing API. org.w3c.workers - JS Kotlin JavaScript wrappers for the Web Workers API. org.w3c.xhr - JS Kotlin JavaScript wrappers for the XMLHttpRequest API. https://kotlinlang.org/api/latest/jvm/stdlib/index.html

Slide 95

Slide 95 text

Why Kotlin?

Slide 96

Slide 96 text

Less is More The language was designed to be concise.

Slide 97

Slide 97 text

Kotlin & Java The interoperability is

Slide 98

Slide 98 text

IDE Support JetBrains provides added functionality for Kotlin in IntelliJ.

Slide 99

Slide 99 text

Kotlin/Native is Coming Write once, run anywhere.

Slide 100

Slide 100 text

Kotlin Core Library Expanding The core library will continue to add features like Coroutines and Contracts.

Slide 101

Slide 101 text

Resources • Official Documentation - https://kotlinlang.org/ • Try Online - https://try.kotlinlang.org/ • Why JetBrains needs Kotlin - https://blog.jetbrains.com/kotlin/2011/08/ why-jetbrains-needs-kotlin/ • What #android-dev is doing - https://github.com/ActiveCampaign/ android-crm