Cody Engel
September 21, 2018
47

# Kotlin Lunch and Learn

This was a lunch and learn I gave about Kotlin at ActiveCampaign.

## Cody Engel

September 21, 2018

## Transcript

3. ### Blogging, It’s A Helluva Drug (Also got into programming through

editing Wordpress themes)

version.

10. ### –Dmitry Jemerov, August 2, 2011 “We (JetBrains) want to become

more productive by switching to a more expressive language.”

development.

up steam.

20. ### fun sum(a: Int, b: Int): Int { return a +

b } Functions

22. ### fun printSum(a: Int, b: Int): Unit { println("sum of \$a

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

\$b is \${a + b}") } Functions

29. ### var a = 1 val s1 = "a is \$a"

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

is \$a” // a was 1 but now is 2 String Templates

32. ### fun maxOf(a: Int, b: Int): Int { if (a >

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

a else b Conditional Expressions

35. ### val maybeNull: String? = null val notNull: String = if

(maybeNull != null) maybeNull else "" Handling Null
36. ### val maybeNull: String? = null val notNull: String = maybeNull

?: "" Handling Null
37. ### val maybeNull: String? = null val length: Int = maybeNull?.length

?: 0 Handling Null
38. ### val listWithNulls: List<String?> = listOf("Kotlin", null) for (item in listWithNulls)

{ item?.let { println(it) } //prints Kotlin and ignores null } Handling Null

40. ### 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>) { Integer total = 0; for (Integer i : (List<Integer>) x) { total += i; } System.out.print(total); } Type Casting
41. ### 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
42. ### when (x) { is Int -> print(x + 1) is

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

44. ### –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.”
45. ### 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
46. ### 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

48. ### 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
49. ### –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.”
50. ### –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.”
51. ### 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
52. ### 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

54. ### class ImageCache( val timeRetrieved: Long, val wasSuccessful: Boolean, val cacheExpirationMs:

Long = 300000 ) Default Values
55. ### 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

57. ### 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" }

62. ### fun <T> MutableList<T>.swap(index1: Int, index2: Int) { val tmp =

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

65. ### private ExpensiveObjectToCreate _expensiveObject = null; ExpensiveObjectToCreate getExpensiveObject() { if (_expensiveObject

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

67. ### private class SynchronizedLazyImpl<out T>(initializer: () -> T, lock: Any? =

null) : Lazy<T>, 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
68. ### Cody’s Animal App …Or the best example he could think

of for class delegation.
69. ### 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<String>) { val catCommunicator = CatCommunicator() val dogCommunicator = DogCommunicator() Animal(catCommunicator).communicate() // Meow Animal(dogCommunicator).communicate() // Woof } Class Delegation
70. ### 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<String>) { val catCommunicator = CatCommunicator() val dogCommunicator = DogCommunicator() Animal(catCommunicator).communicate() // Meow Animal(dogCommunicator).communicate() // Woof } Class Delegation
71. ### 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<String>) { val catCommunicator = CatCommunicator() val dogCommunicator = DogCommunicator() Animal(catCommunicator).communicate() // Meow Animal(dogCommunicator).communicate() // Woof } Class Delegation
72. ### 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<String>) { val catCommunicator = CatCommunicator() val dogCommunicator = DogCommunicator() Animal(catCommunicator).communicate() // Meow Animal(dogCommunicator).communicate() // Woof } Class Delegation
73. ### 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<String>) { val catCommunicator = CatCommunicator() val dogCommunicator = DogCommunicator() Animal(catCommunicator).communicate() // Meow Animal(dogCommunicator).communicate() // Woof } Class Delegation
74. ### 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<String>) { val catCommunicator = CatCommunicator() val dogCommunicator = DogCommunicator() Animal(catCommunicator).communicate() // Meow Animal(dogCommunicator).communicate() // Woof } Class Delegation

76. ### –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.”

79. ### val start = System.currentTimeMillis() BreadLord.whatShouldMobileWorkOnThisWeek() val executionTime = System.currentTimeMillis() -

start Sandwich Code

81. ### public fun measureTimeMillis(block: () -> Unit) : Long { val

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

val start = System.currentTimeMillis() block() return System.currentTimeMillis() - start } Sandwich Code

84. ### fun printNumbers(oneMillionNumbers: List<Int>) { oneMillionNumbers.forEach { number -> println(number) }

} Delayed Execution

86. ### fun oneMillionNumbers(): () -> List<Int> = { (0..1000000).toList() } printNumbers(oneMillionNumbers())

Delayed Execution

89. ### (0..1000000) .filter { it % 2 == 0 } .map

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

{ it.toString() } .map { Pair(it, it.length) } // 3 Lists, Expensive! Collections

92. ### (0..1000000) .asSequence() .filter { it % 2 == 0 }

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

.map { it.toString() } .map { Pair(it, it.length) } .toList() // 1 List, Sorta Cheap ¯\_(ツ)_/¯ Sequence
94. ### 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

100. ### Kotlin Core Library Expanding The core library will continue to

add features like Coroutines and Contracts.
101. ### Resources • Oﬃcial 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