Johan Haleby Exploring Kotlin make val not var
Agenda ! Survey ! Who the f*** are you? ! Intro (What/Why is Kotlin?) ! Code/Feature Walkthrough ! Libraries/Frameworks ! Why might one adopt it? ! Why might one NOT adopt it?
Survey ! Already working with Kotlin? ! Familiar with Kotlin? ! Java Devs? ! Backend? ! Android? ! Java 8/9? ! Scala/Groovy/C#/Swift?
Who ! Backend Developer at Parkster ! Primarily Java/JVM ! REST Assured, Awaitility, PowerMock, Stub HTTP, kubetail… ! Kotlin 😱 ! Evaluating Kotlin for server-side use at Parkster ! Already in use in the Android APP @johanhaleby
fi we’re HIRING
What is Kotlin? ! Statically typed ! Object-oriented with Functional Constructs ! Pragmatic ! Open source ! Interoperable with Java and Android ! Complies to JavaScript (and Native!) ! Concise and Expressive ! Easy to Learn ! Tool-friendly ! Safe https://www.programiz.com/kotlin-programming
Why was Kotlin Created? ! Created by JetBrains ! https://blog.jetbrains.com/kotlin/2011/08/why- jetbrains-needs-kotlin/ ! Increase productivity ! Drive sales ! Drive company's business by keeping trust https://www.programiz.com/kotlin-programming
Where it’s at? https://www.programiz.com/kotlin-programming
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Functions // Function with block body fun sum(a: Int, b: Int): Int { return a + b } http://www.baeldung.com/kotlin // Function with expression body fun sum(a: Int, b: Int) = a + b
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Defining Variables // Immutable reference val a: Int = 1 val b = 1 val c: Int c = 1 // Mutable var x = 5 x += 1 http://www.baeldung.com/kotlin
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Nullable Types val email: String? Nullable fields: val email: String? = null Nullable fields with value: val email: String = "value" Value cannot be null: http://www.baeldung.com/kotlin
Null Safety var a: String = "abc" a = null // compilation error Compilation error: val l = b.length // error: variable 'b' can be null Compilation error: https://kotlinlang.org/docs/reference/null-safety.html var b: String? = "abc" b = null // ok OK: val l = a.length Guaranteed not to cause NPE:
Null Safety if (b != null) { b.length } Safe calls: https://kotlinlang.org/docs/reference/null-safety.html b?.length bob?.department?.head?.name Chaining:
Null Safety val l: Int = if (b != null) b.length else -1 Elvis Operator: https://kotlinlang.org/docs/reference/null-safety.html val l = b!!.length !! Operator: val aInt: Int? = a as? Int Safe Casts: val l = b?.length ?: -1
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Packages package foo.bar fun baz() {} class Goo {} val email: String = "value" Packages can have classes, functions and properties: https://kotlinlang.org/docs/reference/packages.html import foo.Bar // Bar is now accessible without qualification import foo.* // everything in 'foo' becomes accessible import foo.Bar // Bar is accessible import bar.Bar as bBar // bBar stands for 'bar.Bar' Import like this:
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Strings val firstName = "Tom" val secondName = "Mary" val concatOfNames = "$firstName + $secondName" val sum = "four: ${2 + 2}" String templates: val itemManager = … val result = "function result: ${itemManager.isFromSpecificCategory("1")}" Expression inside the ${} block: http://www.baeldung.com/kotlin
Multiline Strings fun demoMultiLineTemplate() { val first = "john" val second = "doe" println(""" First name: $first Second name: $second """) } http://richardlog.com/post/20714599434/exploring-kotlin
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Classes class ItemManager(val categoryId: String, val dbConnection: String) { var email = "" // ... } ItemManager("cat_id", "db://connection") Instantiate: ItemManager(categoryId = "catId", dbConnection = "db://Connection") Named arguments: ItemManager("catId", dbConnection = "db://Connection") Partially named arguments: http://www.baeldung.com/kotlin
Secondary Constructor class ItemManager(val categoryId: String, val dbConnection: String) { var email = "" constructor(categoryId: String, dbConnection: String, email: String) : this(categoryId, dbConnection) { this.email = email } // .. } ItemManager("cat_id", "db://connection", "foo@bar.com") Instantiate: http://www.baeldung.com/kotlin
Inheritance open class Item(val id: String, val name: String = "unknown_name") { open fun getIdOfItem(): String { return id } } class ItemWithCategory(id: String, name: String, val categoryId: String) : Item(id, name) { override fun getIdOfItem(): String { return id + name } } http://www.baeldung.com/kotlin
Data Classes data class User(val name: String, val age: Int) data class User(val name: String = "", val age: Int = 0) Example 2: val jack = User(name = "Jack", age = 1) val olderJack = jack.copy(age = 2) Copy: val jane = User("Jane", 35) val (name, age) = jane println("$name, $age years of age") // prints "Jane, 35 years of age" Destructuring: https://kotlinlang.org/docs/reference/data-classes.html Example 1:
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Properties var <propertyName>[: <PropertyType>] [= <property_initializer>] [<getter>] [<setter>] var initialized = 1 // has type Int, default getter and setter val inferredType = 1 // has type Int and a default getter Examples: https://kotlinlang.org/docs/reference/properties.html The full syntax for declaring a property is: val isEmpty: Boolean get() = this.size == 0 Custom getter: // Type is inferred (since Kotlin 1.1) val isEmpty get() = this.size == 0
Properties var stringRepresentation: String get() = this.toString() set(value) { // parses the string and assigns values to other properties setDataFromString(value) } var setterVisibility: String = "abc" private set // the setter is private and has the default implementation Reduce visibility: https://kotlinlang.org/docs/reference/properties.html Custom setter: var setterWithAnnotation: Any? = null @Inject set // annotate the setter with Inject Annotations:
Properties public class MyTest { lateinit var subject: TestSubject @SetUp fun setup() { subject = TestSubject() } @Test fun test() { subject.method() // dereference directly } } https://kotlinlang.org/docs/reference/properties.html Late-init:
Properties open class Foo { open val x: Int get() { ... } } class Bar1 : Foo() { override val x: Int = ... } https://kotlinlang.org/docs/reference/properties.html Overrides:
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Object Expressions window.addMouseListener(object : MouseAdapter() { override fun mouseClicked(e: MouseEvent) { // ... } override fun mouseEntered(e: MouseEvent) { // ... } }) https://kotlinlang.org/docs/reference/object-declarations.html Anonymous inner class equivalent:
Object Declarations object DataProviderManager { fun registerDataProvider(provider: DataProvider) { // ... } val allDataProviders: Collection<DataProvider> get() = // ... } https://kotlinlang.org/docs/reference/object-declarations.html Singleton: DataProviderManager.registerDataProvider(...) Usage:
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Companion Objects class MyClass { companion object { fun create(): MyClass = MyClass() } } val instance = MyClass.create() val myCompanionObject = MyClass.Companion https://kotlinlang.org/docs/reference/object-declarations.html Kotlin doesn’t have static methods/fields: class MyClass { companion object Factory { fun create(): MyClass = MyClass() } } val instance = MyClass.create() val myCompanionObject = MyClass.Factory Companion objects can be named:
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Preconditions data class RequestBody(val name: String?, val age: Int?) { init { checkNotNull(name) { "This can't be null" // Custom message for IllegalStateException } checkNotNull(age) // There is a default message too require(age ?: 0 < 18) { "Custom message for IllegalArgumentException" } } } https://medium.com/codeexplorers/a-quick-look-into-kotlin-preconditions-9a2d53c8c8ca Defining extension function:
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Kotlin Type Hierarchy https://www.slideshare.net/compscicenter/kotlin-2016-mixing-java-and-kotlin
Any, Unit, Nothing ! The root of the Kotlin class hierarchy. Every Kotlin class has Any as a superclass. class Example // Implicitly inherits from Any
Any, Unit, Nothing interface Executor<T> { fun execute() : T } class SideEffectExecutor : Executor<Unit> { override fun execute() { // ... } } Unit:
Any, Unit, Nothing fun doSomething() { Log.d("Hello", "World") } Unit: fun doSomething(): Unit { Log.d("Hello", "World") }
Any, Unit, Nothing fun fail() { throw RuntimeException("Something went wrong") } ! You can use Nothing to represent "a value that never exists" ! If a function has the return type of Nothing, it never returns (always throws an exception). fun fail(): Nothing { throw RuntimeException("Something went wrong") } https://proandroiddev.com/nothing-else-matters-in-kotlin-994a9ef106fc
Any, Unit, Nothing val data: String = intent.getStringExtra("key") ?: fail() textView.text = data https://proandroiddev.com/nothing-else-matters-in-kotlin-994a9ef106fc What happens? fun fail() { // … }
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
If Expression fun makeAnalysisOfCategory(catId: String) = if (catId == "100") "Yes" else "No" val number = 2 if (number < 10) { println("number less that 10") } else if (number > 10) { println("number is greater that 10") } http://www.baeldung.com/kotlin Expression example: Can be used like a statement:
When Expression when(view.visibility) { View.VISIBLE -> toast("visible") View.INVISIBLE -> toast("invisible") else -> toast("gone") } https://antonioleiva.com/when-expression-kotlin/ Like switch: when (view) { is TextView -> toast(view.text) is RecyclerView -> toast("Item count = ${view.adapter.itemCount}") is SearchView -> toast("Current query: ${view.query}") else -> toast("View type not supported") } Autocasting:
When Expression val res = when { x in 1..10 -> "cheap" s.contains("hello") -> "it's a welcome!" v is ViewGroup -> "child count: ${v.getChildCount()}" else -> "" } https://antonioleiva.com/when-expression-kotlin/ Without arguments:
When Expression sealed class Expr data class Const(val number: Double) : Expr() data class Sum(val e1: Expr, val e2: Expr) : Expr() object NotANumber : Expr() fun eval(expr: Expr): Double = when(expr) { is Const -> expr.number is Sum -> eval(expr.e1) + eval(expr.e2) NotANumber -> Double.NaN // the `else` clause is not required because we've covered all the cases } https://kotlinlang.org/docs/reference/sealed-classes.html With sealed classes:
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Collections val items = listOf(1, 2, 3, 4) val map1 = mapOf(1 to "x", 2 to "y", -1 to "zz") val map2 = emptyMap<String, Int>() https://kotlinlang.org/docs/reference/collections.html Read-only: val numbers = mutableListOf(1, 2, 3) val map = mutableMapOf(1 to "x", 2 to "y", -1 to "zz") Mutable:
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Lambdas val sayHello = { user: String -> println("Hello, $user!") } sayHello("johnny") https://marcin-chwedczuk.github.io/lambda-expressions-in-kotlin Parameter: val printSummary = { user: String, score: Int -> println("User '$user' get $score points.") } printSummary("johnny", 123) Multiple parameters:
Lambdas val names = arrayOf("joe", "ann", "molly", "dolly") names.sortedBy { name -> name.length } // equivalent to names.sortedBy { name: String -> name.length } https://marcin-chwedczuk.github.io/lambda-expressions-in-kotlin Type inference: val russianNames = arrayOf("Maksim", "Artem", "Sophia", "Maria", "Maksim") val selectedName = russianNames .filter { name -> name.startsWith("m", ignoreCase = true) } .sortedBy { name -> name.length } .firstOrNull() Implicit parameter: val russianNames = arrayOf("Maksim", "Artem", "Sophia", "Maria", "Maksim") val selectedName = russianNames .filter { it.startsWith("m", ignoreCase = true) } .sortedBy { it.length } .firstOrNull()
Lambdas val produceValue = { "foo" } println(produceValue()) // prints "foo" val max = { a: Int, b: Int -> if (a > b) a else b } println(max(10,4)) // prints "10" https://marcin-chwedczuk.github.io/lambda-expressions-in-kotlin Lambdas always return:
Lambdas (1..5) .map { _ -> rand.nextInt(100) } .forEach { println(it) } https://marcin-chwedczuk.github.io/lambda-expressions-in-kotlin Ignore argument with _: val fun1: (Int,Int)->Int = { a,b -> Math.max(a,b) } Multiple arguments: val fun3: (Int,(Int)->Int)->Int = { value, func -> func(value) } Higher order-functions:
Lambdas val sin: (angleInRadians: Double) -> Double = { x -> Math.sin(x) } https://marcin-chwedczuk.github.io/lambda-expressions-in-kotlin Argument names for clarity: val sin: (Double) -> Double = Math::sin Method references:
Lambdas fun main(args: Array<String>) { var sum = 0 // Declared outside lambda and not "final" (1..10).forEach { sum += it } println(sum) // Prints 55 } https://marcin-chwedczuk.github.io/lambda-expressions-in-kotlin True closures:
Lambdas fun doWithText(text : String, f : (String) -> String) : String { return f(text) } // Returns "Greeting Johan" doWithText("Johan", { name -> "Greeting $name" }) https://marcin-chwedczuk.github.io/lambda-expressions-in-kotlin Last argument in function can be specified as lambda: doWithText("Johan") { name -> "Greeting $name" }
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Sequences val fibonacci = generateSequence(1 to 1) { it.second to it.first+it.second }.map {it.first} // prints [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] println(fibonacci.take(10).toList()) https://agilewombat.com/2016/02/06/kotlin-sequences/ Example: Example Fibonacci: val numbers = listOf(1, 2, 3, 4, 5) val sum = numbers.asSequence() .map { it * 2 } // Lazy .filter { it % 2 == 0 } // Lazy .reduce(Int::plus) // Terminal (eager) println(sum) // 30
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Looping val numbers = arrayOf("first", "second", "third", "fourth") for (n in numbers) { println(n) } http://www.baeldung.com/kotlin Simple for loop: for (i in 2..9 step 2) { println(i) } Steps: 1.rangeTo(10).map { it * 2 } rangeTo: (1..10).map { it * 2 }
Looping val numbers = arrayOf("first", "second", "third", "fourth") for (i in numbers.indices) { print(numbers[i]) } https://kotlinlang.org/docs/reference/control-flow.html Loop with indices: for ((index, value) in array.withIndex()) { println("the element at $index is $value") } Value and index:
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Delegated Properties ! Not backed by a class field ! Delegates to another piece of code ! "by" keyword class DatabaseBackedUser(userId: String) { val name: String by lazy { queryForValue("SELECT name FROM users WHERE userId = :userId", mapOf("userId" to userId) } } Example 1 (lazy): http://www.baeldung.com/kotlin-delegated-properties
Delegated Properties import kotlin.properties.Delegates class User { var name: String by Delegates.observable("<no name>") { prop, old, new -> println("$old -> $new") } } fun main(args: Array<String>) { val user = User() user.name = "first" user.name = "second" } Example 2 (observable): https://kotlinlang.org/docs/reference/delegated-properties.html#observable This example prints: <no name> -> first first -> second
class DatabaseUser(userId: String) { var name: String by DatabaseDelegate( "SELECT name FROM users WHERE userId = :id", "UPDATE users SET name = :value WHERE userId = :id", userId) var email: String by DatabaseDelegate( "SELECT email FROM users WHERE userId = :id", "UPDATE users SET email = :value WHERE userId = :id", userId) } Delegated Properties class DatabaseDelegate<in R, T>(readQuery: String, writeQuery: String, id: Any) : ReadWriteDelegate<R, T> { fun getValue(thisRef: R, property: KProperty<*>): T { return queryForValue(readQuery, mapOf("id" to id)) } fun setValue(thisRef: R, property: KProperty<*>, value: T) { update(writeQuery, mapOf("id" to id, "value" to value)) } } Example 3 (custom): http://www.baeldung.com/kotlin-delegated-properties Usage:
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Exceptions throw Exception("msg") Throw: ! Virtually the same as Java ! but no checked exceptions! ! expression try { } catch (e: SomeException) { } finally { } Handling: http://www.baeldung.com/kotlin
Exceptions val a: Int? = try { parseInt(input) } catch (e: NumberFormatException){ null } Expression: http://www.baeldung.com/kotlin
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Extension Functions fun <T> MutableList<T>.swap(index1: Int, index2: Int) { val tmp = this[index1] // 'this' corresponds to the list this[index1] = this[index2] this[index2] = tmp } https://kotlinlang.org/docs/reference/extensions.html Defining extension function: val l = mutableListOf(1, 2, 3) l.swap(0, 2) // 'this' inside 'swap()' will hold the value of 'l' Usage:
Extension Functions Caution! open class C class D: C() fun C.foo() = "c" fun D.foo() = "d" fun printFoo(c: C) { println(c.foo()) } printFoo(C()) printFoo(D()) https://kotlinlang.org/docs/reference/extensions.html Extensions are resolved statically: // Will print "c" // Will print "c"
Extension Function Scope package foo.bar fun Baz.goo() { ... } https://kotlinlang.org/docs/reference/extensions.html Normally extensions are defined in package: package com.example.usage import foo.bar.goo // importing all extensions by name "goo" // or import foo.bar.* // importing everything from "foo.bar" fun usage(baz: Baz) { baz.goo() } Usage:
Extension Properties val <T> List<T>.lastIndex: Int get() = size - 1 https://kotlinlang.org/docs/reference/extensions.html Properties can also have extensions: // Define extension to Int infix fun Int.shl(x: Int): Int { ... } // call extension function using infix notation 1 shl 2 // is the same as 1.shl(2) Infix:
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Function with Receiver https://blog.simon-wirtz.de/function-literals-with-receiver-quick-introduction/ Without receiver: fun myHigherOrderFun(functionArg: (Int)->String) = functionArg(5) println ( myHigherOrderFun { "The Number is $it" }) // The Number is 5" With receiver: fun myHigherOrderFun(functionArg: Int.()->String) = functionArg(5) println ( myHigherOrderFun { "Number is $this" }) // Number is 5" println ( myHigherOrderFun { "Number times 2 is " + times(2) })
Function Literals with Receiver val greet: String.() -> Unit = { println("Hello $this") } Function literal with receiver: Receiver Type Parameter Types (none) Return Type val greet: String.() -> Unit = { println("Hello $this") } greet("Johan") // Prints "Hello Johan" "Johan".greet() // Also prints "Hello Johan" Function literal with receiver:
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Type-Safe Builders fun result(args: Array<String>) = html { head { title {+"XML encoding with Kotlin"} } body { h1 {+"XML encoding with Kotlin"} // content generated by args p { for (arg in args) +arg } p {+"this format can be used as an alternative markup to XML"} // an element with attributes and text content a(href = "http://kotlinlang.org") {+"Kotlin"} // mixed content p { +"Check" b {+"this"} a(href = "http://kotlinlang.org") {+"Kotlin"} } } https://kotlinlang.org/docs/reference/type-safe-builders.html
Type-Safe Builders https://kotlinlang.org/docs/reference/type-safe-builders.html class HTML { fun head(…) : Head { … } fun body(…) : Body { … } }
Type-Safe Builders https://kotlinlang.org/docs/reference/type-safe-builders.html fun html(init: HTML.() -> Unit): HTML { val html = HTML() // Create an instance of HTML html.init() // Call the function we passed in the arg with this instance! return html } How it works: html { this.head { /* ... */ } this.body { /* ... */ } } The receiver is accessed using "this": html { head { /* ... */ } // "this" can be omitted! body { /* ... */ } }
Type-Safe Builders https://kotlinlang.org/docs/reference/type-safe-builders.html class HTML { fun head(init: Head.() -> Unit) : Head { val head = Head() head.init() children.add(head) return head } fun body(init: Body.() -> Unit) : Body { val body = Body() body.init() children.add(body) return body } }
Type-Safe Builders https://kotlinlang.org/docs/reference/type-safe-builders.html protected fun <T : Element> initTag(tag: T, init: T.() -> Unit): T { tag.init() children.add(tag) return tag } fun head(init: Head.() -> Unit) = initTag(Head(), init) fun body(init: Body.() -> Unit) = initTag(Body(), init) Head and body can be abstracted out:
! https://kotlinlang.org/docs/reference/type-safe- builders.html#full-definition-of-the- comexamplehtml-package ! https://kotlinlang.org/docs/reference/ lambdas.html#function-literals-with-receiver ! More features (DSLMarker): Type-Safe Builders https://kotlinlang.org/docs/reference/type-safe-builders.html html { head { head {} // should be forbidden } // ... }
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Coroutines https://kotlinlang.org/docs/reference/coroutines.html ! Way to avoid blocking a thread ! Simplify asynchronous programming ! Implemented as a library ! async/await, channels, generators/yield ! Different implementation libraries ! rx, jdk8 (CompletableFuture), nio, javafx, … ! Experimental in Kotlin 1.1 ! https://blog.simon-wirtz.de/kotlin-coroutines- guide/
Coroutines https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md fun main(args: Array<String>) = runBlocking<Unit> { val time = measureTimeMillis { val one = async(CommonPool) { doSomethingUsefulOne() } val two = async(CommonPool) { doSomethingUsefulTwo() } println("The answer is ${one.await() + two.await()}") } println("Completed in $time ms") } async/await: suspend function: suspend fun doSomethingUsefulOne(): Unit { //... }
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Operator overloading https://kotlinlang.org/docs/reference/operator-overloading.html Expression Translated to +a a.unaryPlus() -a a.unaryMinus() !a a.not() a++ a.inc() a-- a.dec() Unary operations
Operator overloading https://kotlinlang.org/docs/reference/operator-overloading.html Binary operations Expression Translated to a + b a.plus(b) a - b a.minus(b) a * b a.times(b) a / b a.div(b) a % b a.rem(b), a.mod(b) (deprecated) a..b a.rangeTo(b)
Operator overloading https://kotlinlang.org/docs/reference/operator-overloading.html Array type operators Expression Translated to a[i] a.get(i) a[i, j] a.get(i, j) a[i_1, ..., i_n] a.get(i_1, ..., i_n) a[i] = b a.set(i, b) a[i, j] = b a.set(i, j, b) a[i_1, ..., i_n] = b a.set(i_1, ..., i_n, b)
Operator overloading https://kotlinlang.org/docs/reference/operator-overloading.html Equality and inequality operators Expression Translated to a == b a?.equals(b) ?: (b === null) a != b !(a?.equals(b) ?: (b === null))
Operator overloading https://kotlinlang.org/docs/reference/operator-overloading.html Comparison operators Expression Translated to a > b a.compareTo(b) > 0 a < b a.compareTo(b) < 0 a >= b a.compareTo(b) >= 0 a <= b a.compareTo(b) <= 0
Operator overloading https://antonioleiva.com/operator-overload-kotlin/ class Employee(val id: Long, val name: String) class Company(private val employees: List) { operator fun get(pos: Int) = employees[pos] } Example: val company = Company(listOf(Employee(1235, "John"), Employee(2584, "Mike"))) val mike = company[1] // Operator "get" kicks in Usage:
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Type Alias https://kotlinlang.org/docs/reference/type-aliases.html typealias Predicate<T> = (T) -> Boolean fun foo(p: Predicate<Int>) = p(42) fun main(args: Array<String>) { val f: (Int) -> Boolean = { it > 0 } println(foo(f)) // prints "true" val p: Predicate<Int> = { it > 0 } println(listOf(1, -2).filter(p)) // prints "[1]" } Example 1: typealias NodeSet = Set<Network.Node> typealias FileTable<K> = MutableMap<K, MutableList<File>> Example 2:
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Also, Apply, Run, Let, With https://medium.com/@nohitme/subtle-differences-between-kotlins-with-apply-let-also-and-run-ebdab57b78e1 StringBuilder builder = new StringBuilder(); builder.append("content: "); builder.append(builder.getClass().getCanonicalName()); System.out.println(builder.toString()); // content: java.lang.StringBuilder Example in Java: fun Any.print() = println(this) Given extension function:
1. their return value is always this, which is the (receiver) instance with type T. 2. the block returns Unit in both functions. Also, Apply, Run, Let, With https://medium.com/@nohitme/subtle-differences-between-kotlins-with-apply-let-also-and-run-ebdab57b78e1 StringBuilder builder = new StringBuilder(); builder.append("content: "); builder.append(builder.getClass().getCanonicalName()); System.out.println(builder.toString()); // content: java.lang.StringBuilder Example in Java: also() vs apply() StringBuilder().also { it.append("content: ") it.append(it.javaClass.canonicalName) }.print() // content: java.lang.StringBuilder StringBuilder().apply { append("content:") append(javaClass.canonicalName) }.print() // content: java.lang.StringBuilder
1. A block is defined as (T) -> R in let(), but it is defined as T.() -> R in run() 2. their return value is R from block function. Also, Apply, Run, Let, With https://medium.com/@nohitme/subtle-differences-between-kotlins-with-apply-let-also-and-run-ebdab57b78e1 StringBuilder builder = new StringBuilder(); builder.append("content: "); builder.append(builder.getClass().getCanonicalName()); System.out.println(builder.toString()); // content: java.lang.StringBuilder Example in Java: run() vs let() StringBuilder().run { append("content: ") append(javaClass.canonicalName) }.print() StringBuilder().let { it.append("content: ") it.append(it.javaClass.canonicalName) }.print()
1. A block is defined as (T) -> R in let(), but it is defined as T.() -> R in run() 2. their return value is R from block function. Also, Apply, Run, Let, With https://medium.com/@nohitme/subtle-differences-between-kotlins-with-apply-let-also-and-run-ebdab57b78e1 StringBuilder builder = new StringBuilder(); builder.append("content: "); builder.append(builder.getClass().getCanonicalName()); System.out.println(builder.toString()); // content: java.lang.StringBuilder Example in Java: run() vs let() StringBuilder().run { append("run (length):") append(" ") append(javaClass.canonicalName) length }.print() // 37 StringBuilder().run { append("run (append):") append(" ") append(javaClass.canonicalName) }.print() // run (append): java.lang.StringBuilder
block is defined as T.() -> R so you don't have to use it, and you can change the return value in block body Also, Apply, Run, Let, With https://medium.com/@nohitme/subtle-differences-between-kotlins-with-apply-let-also-and-run-ebdab57b78e1 StringBuilder builder = new StringBuilder(); builder.append("content: "); builder.append(builder.getClass().getCanonicalName()); System.out.println(builder.toString()); // content: java.lang.StringBuilder Example in Java: with(): with(StringBuilder()) { append("content: ") append(javaClass.canonicalName) }.print()
Also, Apply, Run, Let, With https://forcelain.github.io/2017/08/04/you-don-t-need-a-variable-for-this.html @Test fun title() { val modelWithTitle = fromJson(jsonWithTitle) assertEquals(modelWithTitle.title, "test-title") assertEquals(modelWithTitle.subTitle, "test-sub-title") val modelEmptyTitle = fromJson(jsonEmptyTitle) assertNull(modelEmptyTitle.title) assertNull(modelEmptyTitle.subTitle) val modelEmpty = fromJson("{}") assertNull(modelEmpty.title) assertNull(modelEmpty.subTitle) } Example:
https://forcelain.github.io/2017/08/04/you-don-t-need-a-variable-for-this.html @Test fun title() { fromJson(jsonWithTitle).apply { assertEquals(title, "test-title") assertEquals(subTitle, "test-sub-title") } fromJson(jsonEmptyTitle).apply { assertNull(title) assertNull(subTitle) } fromJson("{}").apply { assertNull(title) assertNull(subTitle) } } Example (rewritten): Also, Apply, Run, Let, With
https://medium.com/@nohitme/subtle-differences-between-kotlins-with-apply-let-also-and-run-ebdab57b78e1 Also, Apply, Run, Let, With
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Inline Functions https://kotlinlang.org/docs/reference/inline-functions.html lock(l) { foo() } Example: l.lock() try { foo() } finally { l.unlock() } Could be inlined to: inline fun lock<T>(lock: Lock, body: () -> T): T { // ... } By doing:
Reified Type Parameters https://kotlinlang.org/docs/reference/inline-functions.html fun <T> TreeNode.findParentOfType(clazz: Class<T>): T? { // .. } Example: treeNode.findParentOfType(MyTreeNode::class.java) Usage:
Reified Type Parameters https://kotlinlang.org/docs/reference/inline-functions.html inline fun <reified T> TreeNode.findParentOfType(): T? { // .. } Inline functions can have reified types: treeNode.findParentOfType<MyTreeNode>() Usage:
Reified Type Parameters https://kotlinlang.org/docs/reference/inline-functions.html inline fun <reified T : Any> loggerFor(): Logger = LoggerFactory.getLogger(T::class.java) Logging example: private val log = loggerFor<MyClass>(); Usage:
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Java Interop http://www.baeldung.com/kotlin class StringUtils { public static String toUpperCase(String name) { return name.toUpperCase(); } } Java: val name = "tom" val res = StringUtils.toUpperCase(name) assertEquals(res, "TOM") From Kotlin:
Java Interop http://www.baeldung.com/kotlin class MathematicsOperations { fun addTwoNumbers(a: Int, b: Int): Int { return a + b } } Kotlin: int res = new MathematicsOperations().addTwoNumbers(2, 4); assertEquals(6, res); From Java:
Code Walkthrough ! Functions ! Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
Function Composition https://try.kotlinlang.org/#/Examples/Callable%20references/Composition%20of%20functions/Composition%20of%20functions.kt fun main(args: Array<String>) { val oddLength = compose(::isOdd, ::length) val strings = listOf("a", "ab", "abc") println(strings.filter(oddLength)) } fun isOdd(x: Int) = x % 2 != 0 fun length(s: String) = s.length fun <A, B, C> compose(f: (B) -> C, g: (A) -> B): (A) -> C { return { x -> f(g(x)) } }
Frameworks and Libraries ! Spring Boot ! Ktor ! Spek ! Exposed ! Anko
 ! Result ! Funktionale ! Kotlin-Monads
Spring Boot ! Easy ! Opinionated ! Convention over configuration ! First class support for Kotlin with Spring 5 https://projects.spring.io/spring-boot/
Spring Boot beans { bean<Foo>() bean { Bar(ref()) } } DSL: router { ("/blog" and accept(TEXT_HTML)).nest { GET("/", fooHandler::findAllView) GET("/{slug}", fooHandler::findOneView) } ("/api/blog" and accept(APPLICATION_JSON)).nest { GET("/", barHandler::findAll) GET("/{id}", barHandler::findOne) } } WebFlux DSL: https://projects.spring.io/spring-boot/
Ktor import org.jetbrains.ktor.application.* import org.jetbrains.ktor.host.* import org.jetbrains.ktor.http.* import org.jetbrains.ktor.netty.* import org.jetbrains.ktor.response.* import org.jetbrains.ktor.routing.* fun main(args: Array<String>) { val server = embeddedServer(Netty, 8080) { routing { get("/") { call.respondText("Hello, world!", ContentType.Text.Html) } } } server.start(wait = true) } http://ktor.io
Spek @Test public void testCalculateTaxRate() { TaxRateCalculator calculator = new TaxRateCalculator(); Int value = calculator.calculateRate(200, 10); assertEquals(300,value); } Typical Kotlin test: http://spekframework.org/
Spek class SimpleTest : Spek({ describe("a calculator") { val calculator = SampleCalculator() it("returns the result of adding the first number to 2nd number") { val sum = calculator.sum(2, 4) assertEquals(6, sum) } it("returns result of subtracting the 2nd number from 1st number") { val subtract = calculator.subtract(4, 2) assertEquals(2, subtract) } } }) With Spek: http://spekframework.org/
Exposed https://github.com/JetBrains/Exposed ! Lightweight SQL library ! JetBrains team project
https://github.com/JetBrains/Exposed object Users : Table() { val id = varchar("id", 10).primaryKey() // Column<String> val name = varchar("name", length = 50) // Column<String> val cityId = (integer("city_id") references Cities.id).nullable() // Column<Int?> } object Cities : Table() { val id = integer("id").autoIncrement().primaryKey() // Column<Int> val name = varchar("name", 50) // Column<String> } fun main(args: Array<String>) { Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") transaction { create (Cities, Users) val saintPetersburgId = Cities.insert { it[name] = "St. Petersburg" } get Cities.id // .. Users.update({Users.id eq "alex"}) { it[name] = "Alexey" } (Users innerJoin Cities).slice(Users.name, Cities.name). select {(Users.id.eq("andrey") or Users.name.eq("Sergey")) and Users.id.eq("sergey") and Users.cityId.eq(Cities.id)}.forEach { println("${it[Users.name]} lives in ${it[Cities.name]}") } }
Anko https://github.com/Kotlin/anko ! Android application development faster and easier ! Cleaner code clean and easier to read ! Takes care of rough edges ! JetBrains official project
Anko verticalLayout { val name = editText() button("Say Hello") { onClick { toast("Hello, ${name.text}!") } } } Dynamic Android layouts: https://github.com/Kotlin/anko fun getUsers(db: ManagedSQLiteOpenHelper): List<User> = db.use { db.select("Users") .whereSimple("family_name = ?", "John") .doExec() .parseList(UserParser) } SQL Light:
Result ! Modelling success/failure of operations ! Result<V, E : Exception> ! Provides higher abstraction ! Composable ! Railway Oriented Programming https://github.com/kittinunf/Result
Result fun process(): String { try { val foo = File("/path/to/file/foo.txt").readText() val isSuccessful = normalizedData(foo) if (!isSuccessful) { return "Data cannot be processable" } val request = createRequestFromData(foo) try { val result = database.updateFromRequest(request) if (!result) { return "Record in DB is not found" } } catch (dbEx: DBException) { return "DB error, cannot update" } } catch (e: Exception) { //do something if error Logger.log(ERROR, e.message()) } } Without "Result": https://github.com/kittinunf/Result
Result fun process(): String { val (value, error) = Result.of{File("/path/to/file/foo.txt").readText()} .flatMap { normalizedData(it) } .map { createRequestFromData(it) } .flatMap { database.updateFromRequest(it) } if (error != null) { // Handle error } return value } With "Result": https://github.com/kittinunf/Result
Funktionale ! Provides a lot of functional constructs ! currying ! composition ! memoization ! partial functions ! try ! validation https://github.com/MarioAriasC/funKTionale
Funktionale import org.funktionale.currying.* val sum2ints = {(x: Int, y: Int)-> x + y } val curried:(Int) -> (Int) -> Int = sum2ints.curried() assertEquals(curried(2)(4), 6) val add5 = curried(5) assertEquals(add5(7), 12) Currying example: import org.funktionale.composition.* private val add5 = {(i: Int)-> i + 5 } private val multiplyBy2 = {(i: Int)-> i * 2 } @Test fun testCompose() { val multiplyBy2andAdd5 = add5 compose multiplyBy2 assertEquals(multiplyBy2andAdd5(2), 9) // (2 * 2) + 5 } Compose example: https://github.com/MarioAriasC/funKTionale
Kotlin Monads ! Monads in Kotlin inspired by Haskell ! Limited to Kotlin type system just(3) bind { returns(it * it) } Example: https://github.com/h0tk3y/kotlin-monads val m = doReturning(MonadListReturn) { val x = bind(monadListOf(1, 2, 3)) val y = bind(monadListOf(x, x + 1)) monadListOf(y, x * y) } assertEquals(monadListOf(1, 1, 2, 2, 2, 4, 3, 6, 3, 9, 4, 12), m) Do Notation:
Why might one adopt it? ! Less code ! More functional ! Nicer to work with ! JVM ! Uses standard build tools ! Excellent IDE support ! First-class Spring support ! Similar to Swift ! Easy to learn
Why might one NOT adopt it? ! Java to Kotlin interop quirks ! Might be slower and larger ! Build time ! New language that everyone needs to know ! Too hipster? ! Not functional enough? ! Boring? ! The Case Against Kotlin ! Drawbacks of migrating to Kotlin ! https://medium.com/@xzan/the-drawbacks-of-migrating-to- kotlin-51f49a96107a
Case Against Kotlin https://medium.com/@Pinterest_Engineering/the-case-against-kotlin-2c574cb87953
Future ! Java 9 support in Kotlin 1.2 ! Could target iOS with Kotlin Native ! Collection literals ! val l: List = [ 1, 2, 3 ] ! SAM conversions for Kotlin interfaces ! Truly immutable data (persistent collections?)
Tips ! https://try.kotlinlang.org ! https://kotlinlang.org/docs/reference/ ! https://kotlinlang.org/docs/resources.html ! https://github.com/KotlinBy/awesome-kotlin ! Kotlin REPL ! Talking Kotlin Podcast ! http://talkingkotlin.com/ ! Kotlin in Action book ! https://www.manning.com/books/kotlin-in-action
Learning https://kotlinlang.org/docs/tutorials/koans.html
Questions

Exploring Kotlin

  • 1.
  • 2.
    Agenda ! Survey ! Whothe f*** are you? ! Intro (What/Why is Kotlin?) ! Code/Feature Walkthrough ! Libraries/Frameworks ! Why might one adopt it? ! Why might one NOT adopt it?
  • 3.
    Survey ! Already workingwith Kotlin? ! Familiar with Kotlin? ! Java Devs? ! Backend? ! Android? ! Java 8/9? ! Scala/Groovy/C#/Swift?
  • 4.
    Who ! Backend Developerat Parkster ! Primarily Java/JVM ! REST Assured, Awaitility, PowerMock, Stub HTTP, kubetail… ! Kotlin 😱 ! Evaluating Kotlin for server-side use at Parkster ! Already in use in the Android APP @johanhaleby
  • 5.
  • 6.
    What is Kotlin? !Statically typed ! Object-oriented with Functional Constructs ! Pragmatic ! Open source ! Interoperable with Java and Android ! Complies to JavaScript (and Native!) ! Concise and Expressive ! Easy to Learn ! Tool-friendly ! Safe https://www.programiz.com/kotlin-programming
  • 7.
    Why was KotlinCreated? ! Created by JetBrains ! https://blog.jetbrains.com/kotlin/2011/08/why- jetbrains-needs-kotlin/ ! Increase productivity ! Drive sales ! Drive company's business by keeping trust https://www.programiz.com/kotlin-programming
  • 8.
  • 9.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 10.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 11.
    Functions // Function withblock body fun sum(a: Int, b: Int): Int { return a + b } http://www.baeldung.com/kotlin // Function with expression body fun sum(a: Int, b: Int) = a + b
  • 12.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 13.
    Defining Variables // Immutablereference val a: Int = 1 val b = 1 val c: Int c = 1 // Mutable var x = 5 x += 1 http://www.baeldung.com/kotlin
  • 14.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 15.
    Nullable Types val email:String? Nullable fields: val email: String? = null Nullable fields with value: val email: String = "value" Value cannot be null: http://www.baeldung.com/kotlin
  • 16.
    Null Safety var a:String = "abc" a = null // compilation error Compilation error: val l = b.length // error: variable 'b' can be null Compilation error: https://kotlinlang.org/docs/reference/null-safety.html var b: String? = "abc" b = null // ok OK: val l = a.length Guaranteed not to cause NPE:
  • 17.
    Null Safety if (b!= null) { b.length } Safe calls: https://kotlinlang.org/docs/reference/null-safety.html b?.length bob?.department?.head?.name Chaining:
  • 18.
    Null Safety val l:Int = if (b != null) b.length else -1 Elvis Operator: https://kotlinlang.org/docs/reference/null-safety.html val l = b!!.length !! Operator: val aInt: Int? = a as? Int Safe Casts: val l = b?.length ?: -1
  • 19.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 20.
    Packages package foo.bar fun baz(){} class Goo {} val email: String = "value" Packages can have classes, functions and properties: https://kotlinlang.org/docs/reference/packages.html import foo.Bar // Bar is now accessible without qualification import foo.* // everything in 'foo' becomes accessible import foo.Bar // Bar is accessible import bar.Bar as bBar // bBar stands for 'bar.Bar' Import like this:
  • 21.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 22.
    Strings val firstName ="Tom" val secondName = "Mary" val concatOfNames = "$firstName + $secondName" val sum = "four: ${2 + 2}" String templates: val itemManager = … val result = "function result: ${itemManager.isFromSpecificCategory("1")}" Expression inside the ${} block: http://www.baeldung.com/kotlin
  • 23.
    Multiline Strings fun demoMultiLineTemplate(){ val first = "john" val second = "doe" println(""" First name: $first Second name: $second """) } http://richardlog.com/post/20714599434/exploring-kotlin
  • 24.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 25.
    Classes class ItemManager(val categoryId:String, val dbConnection: String) { var email = "" // ... } ItemManager("cat_id", "db://connection") Instantiate: ItemManager(categoryId = "catId", dbConnection = "db://Connection") Named arguments: ItemManager("catId", dbConnection = "db://Connection") Partially named arguments: http://www.baeldung.com/kotlin
  • 26.
    Secondary Constructor class ItemManager(valcategoryId: String, val dbConnection: String) { var email = "" constructor(categoryId: String, dbConnection: String, email: String) : this(categoryId, dbConnection) { this.email = email } // .. } ItemManager("cat_id", "db://connection", "foo@bar.com") Instantiate: http://www.baeldung.com/kotlin
  • 27.
    Inheritance open class Item(valid: String, val name: String = "unknown_name") { open fun getIdOfItem(): String { return id } } class ItemWithCategory(id: String, name: String, val categoryId: String) : Item(id, name) { override fun getIdOfItem(): String { return id + name } } http://www.baeldung.com/kotlin
  • 28.
    Data Classes data classUser(val name: String, val age: Int) data class User(val name: String = "", val age: Int = 0) Example 2: val jack = User(name = "Jack", age = 1) val olderJack = jack.copy(age = 2) Copy: val jane = User("Jane", 35) val (name, age) = jane println("$name, $age years of age") // prints "Jane, 35 years of age" Destructuring: https://kotlinlang.org/docs/reference/data-classes.html Example 1:
  • 29.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 30.
    Properties var <propertyName>[: <PropertyType>][= <property_initializer>] [<getter>] [<setter>] var initialized = 1 // has type Int, default getter and setter val inferredType = 1 // has type Int and a default getter Examples: https://kotlinlang.org/docs/reference/properties.html The full syntax for declaring a property is: val isEmpty: Boolean get() = this.size == 0 Custom getter: // Type is inferred (since Kotlin 1.1) val isEmpty get() = this.size == 0
  • 31.
    Properties var stringRepresentation: String get()= this.toString() set(value) { // parses the string and assigns values to other properties setDataFromString(value) } var setterVisibility: String = "abc" private set // the setter is private and has the default implementation Reduce visibility: https://kotlinlang.org/docs/reference/properties.html Custom setter: var setterWithAnnotation: Any? = null @Inject set // annotate the setter with Inject Annotations:
  • 32.
    Properties public class MyTest{ lateinit var subject: TestSubject @SetUp fun setup() { subject = TestSubject() } @Test fun test() { subject.method() // dereference directly } } https://kotlinlang.org/docs/reference/properties.html Late-init:
  • 33.
    Properties open class Foo{ open val x: Int get() { ... } } class Bar1 : Foo() { override val x: Int = ... } https://kotlinlang.org/docs/reference/properties.html Overrides:
  • 34.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 35.
    Object Expressions window.addMouseListener(object :MouseAdapter() { override fun mouseClicked(e: MouseEvent) { // ... } override fun mouseEntered(e: MouseEvent) { // ... } }) https://kotlinlang.org/docs/reference/object-declarations.html Anonymous inner class equivalent:
  • 36.
    Object Declarations object DataProviderManager{ fun registerDataProvider(provider: DataProvider) { // ... } val allDataProviders: Collection<DataProvider> get() = // ... } https://kotlinlang.org/docs/reference/object-declarations.html Singleton: DataProviderManager.registerDataProvider(...) Usage:
  • 37.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 38.
    Companion Objects class MyClass{ companion object { fun create(): MyClass = MyClass() } } val instance = MyClass.create() val myCompanionObject = MyClass.Companion https://kotlinlang.org/docs/reference/object-declarations.html Kotlin doesn’t have static methods/fields: class MyClass { companion object Factory { fun create(): MyClass = MyClass() } } val instance = MyClass.create() val myCompanionObject = MyClass.Factory Companion objects can be named:
  • 39.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 40.
    Preconditions data class RequestBody(valname: String?, val age: Int?) { init { checkNotNull(name) { "This can't be null" // Custom message for IllegalStateException } checkNotNull(age) // There is a default message too require(age ?: 0 < 18) { "Custom message for IllegalArgumentException" } } } https://medium.com/codeexplorers/a-quick-look-into-kotlin-preconditions-9a2d53c8c8ca Defining extension function:
  • 41.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 42.
  • 43.
    Any, Unit, Nothing !The root of the Kotlin class hierarchy. Every Kotlin class has Any as a superclass. class Example // Implicitly inherits from Any
  • 44.
    Any, Unit, Nothing interfaceExecutor<T> { fun execute() : T } class SideEffectExecutor : Executor<Unit> { override fun execute() { // ... } } Unit:
  • 45.
    Any, Unit, Nothing fundoSomething() { Log.d("Hello", "World") } Unit: fun doSomething(): Unit { Log.d("Hello", "World") }
  • 46.
    Any, Unit, Nothing funfail() { throw RuntimeException("Something went wrong") } ! You can use Nothing to represent "a value that never exists" ! If a function has the return type of Nothing, it never returns (always throws an exception). fun fail(): Nothing { throw RuntimeException("Something went wrong") } https://proandroiddev.com/nothing-else-matters-in-kotlin-994a9ef106fc
  • 47.
    Any, Unit, Nothing valdata: String = intent.getStringExtra("key") ?: fail() textView.text = data https://proandroiddev.com/nothing-else-matters-in-kotlin-994a9ef106fc What happens? fun fail() { // … }
  • 48.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 49.
    If Expression fun makeAnalysisOfCategory(catId:String) = if (catId == "100") "Yes" else "No" val number = 2 if (number < 10) { println("number less that 10") } else if (number > 10) { println("number is greater that 10") } http://www.baeldung.com/kotlin Expression example: Can be used like a statement:
  • 50.
    When Expression when(view.visibility) { View.VISIBLE-> toast("visible") View.INVISIBLE -> toast("invisible") else -> toast("gone") } https://antonioleiva.com/when-expression-kotlin/ Like switch: when (view) { is TextView -> toast(view.text) is RecyclerView -> toast("Item count = ${view.adapter.itemCount}") is SearchView -> toast("Current query: ${view.query}") else -> toast("View type not supported") } Autocasting:
  • 51.
    When Expression val res= when { x in 1..10 -> "cheap" s.contains("hello") -> "it's a welcome!" v is ViewGroup -> "child count: ${v.getChildCount()}" else -> "" } https://antonioleiva.com/when-expression-kotlin/ Without arguments:
  • 52.
    When Expression sealed classExpr data class Const(val number: Double) : Expr() data class Sum(val e1: Expr, val e2: Expr) : Expr() object NotANumber : Expr() fun eval(expr: Expr): Double = when(expr) { is Const -> expr.number is Sum -> eval(expr.e1) + eval(expr.e2) NotANumber -> Double.NaN // the `else` clause is not required because we've covered all the cases } https://kotlinlang.org/docs/reference/sealed-classes.html With sealed classes:
  • 53.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 54.
    Collections val items =listOf(1, 2, 3, 4) val map1 = mapOf(1 to "x", 2 to "y", -1 to "zz") val map2 = emptyMap<String, Int>() https://kotlinlang.org/docs/reference/collections.html Read-only: val numbers = mutableListOf(1, 2, 3) val map = mutableMapOf(1 to "x", 2 to "y", -1 to "zz") Mutable:
  • 55.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 56.
    Lambdas val sayHello ={ user: String -> println("Hello, $user!") } sayHello("johnny") https://marcin-chwedczuk.github.io/lambda-expressions-in-kotlin Parameter: val printSummary = { user: String, score: Int -> println("User '$user' get $score points.") } printSummary("johnny", 123) Multiple parameters:
  • 57.
    Lambdas val names =arrayOf("joe", "ann", "molly", "dolly") names.sortedBy { name -> name.length } // equivalent to names.sortedBy { name: String -> name.length } https://marcin-chwedczuk.github.io/lambda-expressions-in-kotlin Type inference: val russianNames = arrayOf("Maksim", "Artem", "Sophia", "Maria", "Maksim") val selectedName = russianNames .filter { name -> name.startsWith("m", ignoreCase = true) } .sortedBy { name -> name.length } .firstOrNull() Implicit parameter: val russianNames = arrayOf("Maksim", "Artem", "Sophia", "Maria", "Maksim") val selectedName = russianNames .filter { it.startsWith("m", ignoreCase = true) } .sortedBy { it.length } .firstOrNull()
  • 58.
    Lambdas val produceValue ={ "foo" } println(produceValue()) // prints "foo" val max = { a: Int, b: Int -> if (a > b) a else b } println(max(10,4)) // prints "10" https://marcin-chwedczuk.github.io/lambda-expressions-in-kotlin Lambdas always return:
  • 59.
    Lambdas (1..5) .map { _-> rand.nextInt(100) } .forEach { println(it) } https://marcin-chwedczuk.github.io/lambda-expressions-in-kotlin Ignore argument with _: val fun1: (Int,Int)->Int = { a,b -> Math.max(a,b) } Multiple arguments: val fun3: (Int,(Int)->Int)->Int = { value, func -> func(value) } Higher order-functions:
  • 60.
    Lambdas val sin: (angleInRadians:Double) -> Double = { x -> Math.sin(x) } https://marcin-chwedczuk.github.io/lambda-expressions-in-kotlin Argument names for clarity: val sin: (Double) -> Double = Math::sin Method references:
  • 61.
    Lambdas fun main(args: Array<String>){ var sum = 0 // Declared outside lambda and not "final" (1..10).forEach { sum += it } println(sum) // Prints 55 } https://marcin-chwedczuk.github.io/lambda-expressions-in-kotlin True closures:
  • 62.
    Lambdas fun doWithText(text :String, f : (String) -> String) : String { return f(text) } // Returns "Greeting Johan" doWithText("Johan", { name -> "Greeting $name" }) https://marcin-chwedczuk.github.io/lambda-expressions-in-kotlin Last argument in function can be specified as lambda: doWithText("Johan") { name -> "Greeting $name" }
  • 63.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 64.
    Sequences val fibonacci =generateSequence(1 to 1) { it.second to it.first+it.second }.map {it.first} // prints [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] println(fibonacci.take(10).toList()) https://agilewombat.com/2016/02/06/kotlin-sequences/ Example: Example Fibonacci: val numbers = listOf(1, 2, 3, 4, 5) val sum = numbers.asSequence() .map { it * 2 } // Lazy .filter { it % 2 == 0 } // Lazy .reduce(Int::plus) // Terminal (eager) println(sum) // 30
  • 65.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 66.
    Looping val numbers =arrayOf("first", "second", "third", "fourth") for (n in numbers) { println(n) } http://www.baeldung.com/kotlin Simple for loop: for (i in 2..9 step 2) { println(i) } Steps: 1.rangeTo(10).map { it * 2 } rangeTo: (1..10).map { it * 2 }
  • 67.
    Looping val numbers =arrayOf("first", "second", "third", "fourth") for (i in numbers.indices) { print(numbers[i]) } https://kotlinlang.org/docs/reference/control-flow.html Loop with indices: for ((index, value) in array.withIndex()) { println("the element at $index is $value") } Value and index:
  • 68.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 69.
    Delegated Properties ! Notbacked by a class field ! Delegates to another piece of code ! "by" keyword class DatabaseBackedUser(userId: String) { val name: String by lazy { queryForValue("SELECT name FROM users WHERE userId = :userId", mapOf("userId" to userId) } } Example 1 (lazy): http://www.baeldung.com/kotlin-delegated-properties
  • 70.
    Delegated Properties import kotlin.properties.Delegates classUser { var name: String by Delegates.observable("<no name>") { prop, old, new -> println("$old -> $new") } } fun main(args: Array<String>) { val user = User() user.name = "first" user.name = "second" } Example 2 (observable): https://kotlinlang.org/docs/reference/delegated-properties.html#observable This example prints: <no name> -> first first -> second
  • 71.
    class DatabaseUser(userId: String){ var name: String by DatabaseDelegate( "SELECT name FROM users WHERE userId = :id", "UPDATE users SET name = :value WHERE userId = :id", userId) var email: String by DatabaseDelegate( "SELECT email FROM users WHERE userId = :id", "UPDATE users SET email = :value WHERE userId = :id", userId) } Delegated Properties class DatabaseDelegate<in R, T>(readQuery: String, writeQuery: String, id: Any) : ReadWriteDelegate<R, T> { fun getValue(thisRef: R, property: KProperty<*>): T { return queryForValue(readQuery, mapOf("id" to id)) } fun setValue(thisRef: R, property: KProperty<*>, value: T) { update(writeQuery, mapOf("id" to id, "value" to value)) } } Example 3 (custom): http://www.baeldung.com/kotlin-delegated-properties Usage:
  • 72.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 73.
    Exceptions throw Exception("msg") Throw: ! Virtuallythe same as Java ! but no checked exceptions! ! expression try { } catch (e: SomeException) { } finally { } Handling: http://www.baeldung.com/kotlin
  • 74.
    Exceptions val a: Int?= try { parseInt(input) } catch (e: NumberFormatException){ null } Expression: http://www.baeldung.com/kotlin
  • 75.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 76.
    Extension Functions fun <T>MutableList<T>.swap(index1: Int, index2: Int) { val tmp = this[index1] // 'this' corresponds to the list this[index1] = this[index2] this[index2] = tmp } https://kotlinlang.org/docs/reference/extensions.html Defining extension function: val l = mutableListOf(1, 2, 3) l.swap(0, 2) // 'this' inside 'swap()' will hold the value of 'l' Usage:
  • 77.
    Extension Functions Caution! openclass C class D: C() fun C.foo() = "c" fun D.foo() = "d" fun printFoo(c: C) { println(c.foo()) } printFoo(C()) printFoo(D()) https://kotlinlang.org/docs/reference/extensions.html Extensions are resolved statically: // Will print "c" // Will print "c"
  • 78.
    Extension Function Scope packagefoo.bar fun Baz.goo() { ... } https://kotlinlang.org/docs/reference/extensions.html Normally extensions are defined in package: package com.example.usage import foo.bar.goo // importing all extensions by name "goo" // or import foo.bar.* // importing everything from "foo.bar" fun usage(baz: Baz) { baz.goo() } Usage:
  • 79.
    Extension Properties val <T>List<T>.lastIndex: Int get() = size - 1 https://kotlinlang.org/docs/reference/extensions.html Properties can also have extensions: // Define extension to Int infix fun Int.shl(x: Int): Int { ... } // call extension function using infix notation 1 shl 2 // is the same as 1.shl(2) Infix:
  • 80.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 81.
    Function with Receiver https://blog.simon-wirtz.de/function-literals-with-receiver-quick-introduction/ Withoutreceiver: fun myHigherOrderFun(functionArg: (Int)->String) = functionArg(5) println ( myHigherOrderFun { "The Number is $it" }) // The Number is 5" With receiver: fun myHigherOrderFun(functionArg: Int.()->String) = functionArg(5) println ( myHigherOrderFun { "Number is $this" }) // Number is 5" println ( myHigherOrderFun { "Number times 2 is " + times(2) })
  • 82.
    Function Literals withReceiver val greet: String.() -> Unit = { println("Hello $this") } Function literal with receiver: Receiver Type Parameter Types (none) Return Type val greet: String.() -> Unit = { println("Hello $this") } greet("Johan") // Prints "Hello Johan" "Johan".greet() // Also prints "Hello Johan" Function literal with receiver:
  • 83.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 84.
    Type-Safe Builders fun result(args:Array<String>) = html { head { title {+"XML encoding with Kotlin"} } body { h1 {+"XML encoding with Kotlin"} // content generated by args p { for (arg in args) +arg } p {+"this format can be used as an alternative markup to XML"} // an element with attributes and text content a(href = "http://kotlinlang.org") {+"Kotlin"} // mixed content p { +"Check" b {+"this"} a(href = "http://kotlinlang.org") {+"Kotlin"} } } https://kotlinlang.org/docs/reference/type-safe-builders.html
  • 85.
    Type-Safe Builders https://kotlinlang.org/docs/reference/type-safe-builders.html class HTML{ fun head(…) : Head { … } fun body(…) : Body { … } }
  • 86.
    Type-Safe Builders https://kotlinlang.org/docs/reference/type-safe-builders.html fun html(init:HTML.() -> Unit): HTML { val html = HTML() // Create an instance of HTML html.init() // Call the function we passed in the arg with this instance! return html } How it works: html { this.head { /* ... */ } this.body { /* ... */ } } The receiver is accessed using "this": html { head { /* ... */ } // "this" can be omitted! body { /* ... */ } }
  • 87.
    Type-Safe Builders https://kotlinlang.org/docs/reference/type-safe-builders.html class HTML{ fun head(init: Head.() -> Unit) : Head { val head = Head() head.init() children.add(head) return head } fun body(init: Body.() -> Unit) : Body { val body = Body() body.init() children.add(body) return body } }
  • 88.
    Type-Safe Builders https://kotlinlang.org/docs/reference/type-safe-builders.html protected fun<T : Element> initTag(tag: T, init: T.() -> Unit): T { tag.init() children.add(tag) return tag } fun head(init: Head.() -> Unit) = initTag(Head(), init) fun body(init: Body.() -> Unit) = initTag(Body(), init) Head and body can be abstracted out:
  • 89.
    ! https://kotlinlang.org/docs/reference/type-safe- builders.html#full-definition-of-the- comexamplehtml-package ! https://kotlinlang.org/docs/reference/ lambdas.html#function-literals-with-receiver !More features (DSLMarker): Type-Safe Builders https://kotlinlang.org/docs/reference/type-safe-builders.html html { head { head {} // should be forbidden } // ... }
  • 90.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 91.
    Coroutines https://kotlinlang.org/docs/reference/coroutines.html ! Way toavoid blocking a thread ! Simplify asynchronous programming ! Implemented as a library ! async/await, channels, generators/yield ! Different implementation libraries ! rx, jdk8 (CompletableFuture), nio, javafx, … ! Experimental in Kotlin 1.1 ! https://blog.simon-wirtz.de/kotlin-coroutines- guide/
  • 92.
    Coroutines https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md fun main(args: Array<String>)= runBlocking<Unit> { val time = measureTimeMillis { val one = async(CommonPool) { doSomethingUsefulOne() } val two = async(CommonPool) { doSomethingUsefulTwo() } println("The answer is ${one.await() + two.await()}") } println("Completed in $time ms") } async/await: suspend function: suspend fun doSomethingUsefulOne(): Unit { //... }
  • 93.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 94.
    Operator overloading https://kotlinlang.org/docs/reference/operator-overloading.html Expression Translatedto +a a.unaryPlus() -a a.unaryMinus() !a a.not() a++ a.inc() a-- a.dec() Unary operations
  • 95.
    Operator overloading https://kotlinlang.org/docs/reference/operator-overloading.html Binary operations ExpressionTranslated to a + b a.plus(b) a - b a.minus(b) a * b a.times(b) a / b a.div(b) a % b a.rem(b), a.mod(b) (deprecated) a..b a.rangeTo(b)
  • 96.
    Operator overloading https://kotlinlang.org/docs/reference/operator-overloading.html Array typeoperators Expression Translated to a[i] a.get(i) a[i, j] a.get(i, j) a[i_1, ..., i_n] a.get(i_1, ..., i_n) a[i] = b a.set(i, b) a[i, j] = b a.set(i, j, b) a[i_1, ..., i_n] = b a.set(i_1, ..., i_n, b)
  • 97.
    Operator overloading https://kotlinlang.org/docs/reference/operator-overloading.html Equality andinequality operators Expression Translated to a == b a?.equals(b) ?: (b === null) a != b !(a?.equals(b) ?: (b === null))
  • 98.
    Operator overloading https://kotlinlang.org/docs/reference/operator-overloading.html Comparison operators ExpressionTranslated to a > b a.compareTo(b) > 0 a < b a.compareTo(b) < 0 a >= b a.compareTo(b) >= 0 a <= b a.compareTo(b) <= 0
  • 99.
    Operator overloading https://antonioleiva.com/operator-overload-kotlin/ class Employee(valid: Long, val name: String) class Company(private val employees: List) { operator fun get(pos: Int) = employees[pos] } Example: val company = Company(listOf(Employee(1235, "John"), Employee(2584, "Mike"))) val mike = company[1] // Operator "get" kicks in Usage:
  • 100.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 101.
    Type Alias https://kotlinlang.org/docs/reference/type-aliases.html typealias Predicate<T>= (T) -> Boolean fun foo(p: Predicate<Int>) = p(42) fun main(args: Array<String>) { val f: (Int) -> Boolean = { it > 0 } println(foo(f)) // prints "true" val p: Predicate<Int> = { it > 0 } println(listOf(1, -2).filter(p)) // prints "[1]" } Example 1: typealias NodeSet = Set<Network.Node> typealias FileTable<K> = MutableMap<K, MutableList<File>> Example 2:
  • 102.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 103.
    Also, Apply, Run,Let, With https://medium.com/@nohitme/subtle-differences-between-kotlins-with-apply-let-also-and-run-ebdab57b78e1 StringBuilder builder = new StringBuilder(); builder.append("content: "); builder.append(builder.getClass().getCanonicalName()); System.out.println(builder.toString()); // content: java.lang.StringBuilder Example in Java: fun Any.print() = println(this) Given extension function:
  • 104.
    1. their returnvalue is always this, which is the (receiver) instance with type T. 2. the block returns Unit in both functions. Also, Apply, Run, Let, With https://medium.com/@nohitme/subtle-differences-between-kotlins-with-apply-let-also-and-run-ebdab57b78e1 StringBuilder builder = new StringBuilder(); builder.append("content: "); builder.append(builder.getClass().getCanonicalName()); System.out.println(builder.toString()); // content: java.lang.StringBuilder Example in Java: also() vs apply() StringBuilder().also { it.append("content: ") it.append(it.javaClass.canonicalName) }.print() // content: java.lang.StringBuilder StringBuilder().apply { append("content:") append(javaClass.canonicalName) }.print() // content: java.lang.StringBuilder
  • 105.
    1. A blockis defined as (T) -> R in let(), but it is defined as T.() -> R in run() 2. their return value is R from block function. Also, Apply, Run, Let, With https://medium.com/@nohitme/subtle-differences-between-kotlins-with-apply-let-also-and-run-ebdab57b78e1 StringBuilder builder = new StringBuilder(); builder.append("content: "); builder.append(builder.getClass().getCanonicalName()); System.out.println(builder.toString()); // content: java.lang.StringBuilder Example in Java: run() vs let() StringBuilder().run { append("content: ") append(javaClass.canonicalName) }.print() StringBuilder().let { it.append("content: ") it.append(it.javaClass.canonicalName) }.print()
  • 106.
    1. A blockis defined as (T) -> R in let(), but it is defined as T.() -> R in run() 2. their return value is R from block function. Also, Apply, Run, Let, With https://medium.com/@nohitme/subtle-differences-between-kotlins-with-apply-let-also-and-run-ebdab57b78e1 StringBuilder builder = new StringBuilder(); builder.append("content: "); builder.append(builder.getClass().getCanonicalName()); System.out.println(builder.toString()); // content: java.lang.StringBuilder Example in Java: run() vs let() StringBuilder().run { append("run (length):") append(" ") append(javaClass.canonicalName) length }.print() // 37 StringBuilder().run { append("run (append):") append(" ") append(javaClass.canonicalName) }.print() // run (append): java.lang.StringBuilder
  • 107.
    block is defined as T.()-> R so you don't have to use it, and you can change the return value in block body Also, Apply, Run, Let, With https://medium.com/@nohitme/subtle-differences-between-kotlins-with-apply-let-also-and-run-ebdab57b78e1 StringBuilder builder = new StringBuilder(); builder.append("content: "); builder.append(builder.getClass().getCanonicalName()); System.out.println(builder.toString()); // content: java.lang.StringBuilder Example in Java: with(): with(StringBuilder()) { append("content: ") append(javaClass.canonicalName) }.print()
  • 108.
    Also, Apply, Run,Let, With https://forcelain.github.io/2017/08/04/you-don-t-need-a-variable-for-this.html @Test fun title() { val modelWithTitle = fromJson(jsonWithTitle) assertEquals(modelWithTitle.title, "test-title") assertEquals(modelWithTitle.subTitle, "test-sub-title") val modelEmptyTitle = fromJson(jsonEmptyTitle) assertNull(modelEmptyTitle.title) assertNull(modelEmptyTitle.subTitle) val modelEmpty = fromJson("{}") assertNull(modelEmpty.title) assertNull(modelEmpty.subTitle) } Example:
  • 109.
    https://forcelain.github.io/2017/08/04/you-don-t-need-a-variable-for-this.html @Test fun title() { fromJson(jsonWithTitle).apply{ assertEquals(title, "test-title") assertEquals(subTitle, "test-sub-title") } fromJson(jsonEmptyTitle).apply { assertNull(title) assertNull(subTitle) } fromJson("{}").apply { assertNull(title) assertNull(subTitle) } } Example (rewritten): Also, Apply, Run, Let, With
  • 110.
  • 111.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 112.
    Inline Functions https://kotlinlang.org/docs/reference/inline-functions.html lock(l) {foo() } Example: l.lock() try { foo() } finally { l.unlock() } Could be inlined to: inline fun lock<T>(lock: Lock, body: () -> T): T { // ... } By doing:
  • 113.
    Reified Type Parameters https://kotlinlang.org/docs/reference/inline-functions.html fun<T> TreeNode.findParentOfType(clazz: Class<T>): T? { // .. } Example: treeNode.findParentOfType(MyTreeNode::class.java) Usage:
  • 114.
    Reified Type Parameters https://kotlinlang.org/docs/reference/inline-functions.html inlinefun <reified T> TreeNode.findParentOfType(): T? { // .. } Inline functions can have reified types: treeNode.findParentOfType<MyTreeNode>() Usage:
  • 115.
    Reified Type Parameters https://kotlinlang.org/docs/reference/inline-functions.html inlinefun <reified T : Any> loggerFor(): Logger = LoggerFactory.getLogger(T::class.java) Logging example: private val log = loggerFor<MyClass>(); Usage:
  • 116.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 117.
    Java Interop http://www.baeldung.com/kotlin class StringUtils{ public static String toUpperCase(String name) { return name.toUpperCase(); } } Java: val name = "tom" val res = StringUtils.toUpperCase(name) assertEquals(res, "TOM") From Kotlin:
  • 118.
    Java Interop http://www.baeldung.com/kotlin class MathematicsOperations{ fun addTwoNumbers(a: Int, b: Int): Int { return a + b } } Kotlin: int res = new MathematicsOperations().addTwoNumbers(2, 4); assertEquals(6, res); From Java:
  • 119.
    Code Walkthrough ! Functions !Variables ! Nullable Types/Safety ! Packages ! Strings ! Classes ! Properties ! Object Expressions ! Companion Objects ! Preconditions ! Type Hierarchy ! If/When expressions ! Collections ! Lambdas ! Sequences ! Looping ! Delegated Properties ! Exceptions ! Extension Functions ! Functions with Receiver ! Type-safe Builders ! Coroutines ! Operator overloading ! Type Alias ! Also, apply, run, let, with.. ! Inline/reified functions ! Java Interop ! Function Composition
  • 120.
    Function Composition https://try.kotlinlang.org/#/Examples/Callable%20references/Composition%20of%20functions/Composition%20of%20functions.kt fun main(args:Array<String>) { val oddLength = compose(::isOdd, ::length) val strings = listOf("a", "ab", "abc") println(strings.filter(oddLength)) } fun isOdd(x: Int) = x % 2 != 0 fun length(s: String) = s.length fun <A, B, C> compose(f: (B) -> C, g: (A) -> B): (A) -> C { return { x -> f(g(x)) } }
  • 121.
    Frameworks and Libraries !Spring Boot ! Ktor ! Spek ! Exposed ! Anko
 ! Result ! Funktionale ! Kotlin-Monads
  • 122.
    Spring Boot ! Easy !Opinionated ! Convention over configuration ! First class support for Kotlin with Spring 5 https://projects.spring.io/spring-boot/
  • 123.
    Spring Boot beans { bean<Foo>() bean{ Bar(ref()) } } DSL: router { ("/blog" and accept(TEXT_HTML)).nest { GET("/", fooHandler::findAllView) GET("/{slug}", fooHandler::findOneView) } ("/api/blog" and accept(APPLICATION_JSON)).nest { GET("/", barHandler::findAll) GET("/{id}", barHandler::findOne) } } WebFlux DSL: https://projects.spring.io/spring-boot/
  • 124.
    Ktor import org.jetbrains.ktor.application.* import org.jetbrains.ktor.host.* importorg.jetbrains.ktor.http.* import org.jetbrains.ktor.netty.* import org.jetbrains.ktor.response.* import org.jetbrains.ktor.routing.* fun main(args: Array<String>) { val server = embeddedServer(Netty, 8080) { routing { get("/") { call.respondText("Hello, world!", ContentType.Text.Html) } } } server.start(wait = true) } http://ktor.io
  • 125.
    Spek @Test public void testCalculateTaxRate(){ TaxRateCalculator calculator = new TaxRateCalculator(); Int value = calculator.calculateRate(200, 10); assertEquals(300,value); } Typical Kotlin test: http://spekframework.org/
  • 126.
    Spek class SimpleTest :Spek({ describe("a calculator") { val calculator = SampleCalculator() it("returns the result of adding the first number to 2nd number") { val sum = calculator.sum(2, 4) assertEquals(6, sum) } it("returns result of subtracting the 2nd number from 1st number") { val subtract = calculator.subtract(4, 2) assertEquals(2, subtract) } } }) With Spek: http://spekframework.org/
  • 127.
  • 128.
    https://github.com/JetBrains/Exposed object Users :Table() { val id = varchar("id", 10).primaryKey() // Column<String> val name = varchar("name", length = 50) // Column<String> val cityId = (integer("city_id") references Cities.id).nullable() // Column<Int?> } object Cities : Table() { val id = integer("id").autoIncrement().primaryKey() // Column<Int> val name = varchar("name", 50) // Column<String> } fun main(args: Array<String>) { Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") transaction { create (Cities, Users) val saintPetersburgId = Cities.insert { it[name] = "St. Petersburg" } get Cities.id // .. Users.update({Users.id eq "alex"}) { it[name] = "Alexey" } (Users innerJoin Cities).slice(Users.name, Cities.name). select {(Users.id.eq("andrey") or Users.name.eq("Sergey")) and Users.id.eq("sergey") and Users.cityId.eq(Cities.id)}.forEach { println("${it[Users.name]} lives in ${it[Cities.name]}") } }
  • 129.
    Anko https://github.com/Kotlin/anko ! Android applicationdevelopment faster and easier ! Cleaner code clean and easier to read ! Takes care of rough edges ! JetBrains official project
  • 130.
    Anko verticalLayout { val name= editText() button("Say Hello") { onClick { toast("Hello, ${name.text}!") } } } Dynamic Android layouts: https://github.com/Kotlin/anko fun getUsers(db: ManagedSQLiteOpenHelper): List<User> = db.use { db.select("Users") .whereSimple("family_name = ?", "John") .doExec() .parseList(UserParser) } SQL Light:
  • 131.
    Result ! Modelling success/failureof operations ! Result<V, E : Exception> ! Provides higher abstraction ! Composable ! Railway Oriented Programming https://github.com/kittinunf/Result
  • 132.
    Result fun process(): String{ try { val foo = File("/path/to/file/foo.txt").readText() val isSuccessful = normalizedData(foo) if (!isSuccessful) { return "Data cannot be processable" } val request = createRequestFromData(foo) try { val result = database.updateFromRequest(request) if (!result) { return "Record in DB is not found" } } catch (dbEx: DBException) { return "DB error, cannot update" } } catch (e: Exception) { //do something if error Logger.log(ERROR, e.message()) } } Without "Result": https://github.com/kittinunf/Result
  • 133.
    Result fun process(): String{ val (value, error) = Result.of{File("/path/to/file/foo.txt").readText()} .flatMap { normalizedData(it) } .map { createRequestFromData(it) } .flatMap { database.updateFromRequest(it) } if (error != null) { // Handle error } return value } With "Result": https://github.com/kittinunf/Result
  • 134.
    Funktionale ! Provides alot of functional constructs ! currying ! composition ! memoization ! partial functions ! try ! validation https://github.com/MarioAriasC/funKTionale
  • 135.
    Funktionale import org.funktionale.currying.* val sum2ints= {(x: Int, y: Int)-> x + y } val curried:(Int) -> (Int) -> Int = sum2ints.curried() assertEquals(curried(2)(4), 6) val add5 = curried(5) assertEquals(add5(7), 12) Currying example: import org.funktionale.composition.* private val add5 = {(i: Int)-> i + 5 } private val multiplyBy2 = {(i: Int)-> i * 2 } @Test fun testCompose() { val multiplyBy2andAdd5 = add5 compose multiplyBy2 assertEquals(multiplyBy2andAdd5(2), 9) // (2 * 2) + 5 } Compose example: https://github.com/MarioAriasC/funKTionale
  • 136.
    Kotlin Monads ! Monadsin Kotlin inspired by Haskell ! Limited to Kotlin type system just(3) bind { returns(it * it) } Example: https://github.com/h0tk3y/kotlin-monads val m = doReturning(MonadListReturn) { val x = bind(monadListOf(1, 2, 3)) val y = bind(monadListOf(x, x + 1)) monadListOf(y, x * y) } assertEquals(monadListOf(1, 1, 2, 2, 2, 4, 3, 6, 3, 9, 4, 12), m) Do Notation:
  • 137.
    Why might oneadopt it? ! Less code ! More functional ! Nicer to work with ! JVM ! Uses standard build tools ! Excellent IDE support ! First-class Spring support ! Similar to Swift ! Easy to learn
  • 138.
    Why might oneNOT adopt it? ! Java to Kotlin interop quirks ! Might be slower and larger ! Build time ! New language that everyone needs to know ! Too hipster? ! Not functional enough? ! Boring? ! The Case Against Kotlin ! Drawbacks of migrating to Kotlin ! https://medium.com/@xzan/the-drawbacks-of-migrating-to- kotlin-51f49a96107a
  • 139.
  • 140.
    Future ! Java 9support in Kotlin 1.2 ! Could target iOS with Kotlin Native ! Collection literals ! val l: List = [ 1, 2, 3 ] ! SAM conversions for Kotlin interfaces ! Truly immutable data (persistent collections?)
  • 141.
    Tips ! https://try.kotlinlang.org ! https://kotlinlang.org/docs/reference/ !https://kotlinlang.org/docs/resources.html ! https://github.com/KotlinBy/awesome-kotlin ! Kotlin REPL ! Talking Kotlin Podcast ! http://talkingkotlin.com/ ! Kotlin in Action book ! https://www.manning.com/books/kotlin-in-action
  • 142.
  • 143.