SlideShare a Scribd company logo
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

More Related Content

PDF
Effective Scala: Programming Patterns
PDF
JavaScript - From Birth To Closure
PDF
Burp Plugin Development for Java n00bs - 44CON 2012
KEY
OOP in JS
PPTX
Js: master prototypes
PDF
Javascript Best Practices
PDF
Metaprogramming with javascript
PDF
Prototype
Effective Scala: Programming Patterns
JavaScript - From Birth To Closure
Burp Plugin Development for Java n00bs - 44CON 2012
OOP in JS
Js: master prototypes
Javascript Best Practices
Metaprogramming with javascript
Prototype

What's hot (12)

PPT
Goodparts
PPTX
Building maintainable javascript applications
PDF
Kotlin Types for Java Developers
PPT
Java script unleashed
PDF
Writing SOLID code (in practice)
PDF
JavaScript Patterns
PPTX
Scala’s implicits
PPTX
AngularConf2015
PPT
Java Basics
PPTX
C++ Introduction brown bag
PDF
Oop in php_tutorial
PDF
[A4]de view2012 scala-michinisougu
Goodparts
Building maintainable javascript applications
Kotlin Types for Java Developers
Java script unleashed
Writing SOLID code (in practice)
JavaScript Patterns
Scala’s implicits
AngularConf2015
Java Basics
C++ Introduction brown bag
Oop in php_tutorial
[A4]de view2012 scala-michinisougu
Ad

Similar to Exploring Kotlin (20)

PDF
Privet Kotlin (Windy City DevFest)
PDF
Intro to Kotlin
PDF
Kotlin cheat sheet by ekito
PDF
Kotlin for Android devs
PDF
Kotlin, smarter development for the jvm
PDF
9054799 dzone-refcard267-kotlin
PDF
Kotlin: A pragmatic language by JetBrains
PDF
Kotlin what_you_need_to_know-converted event 4 with nigerians
PDF
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018
PDF
Little Helpers for Android Development with Kotlin
PDF
Introduction to Kotlin - Android KTX
PDF
2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf
PDF
Develop your next app with kotlin @ AndroidMakersFr 2017
PDF
A quick and fast intro to Kotlin
PDF
2 kotlin vs. java: what java has that kotlin does not
PDF
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
PDF
Kotlin intro
PDF
Coding for Android on steroids with Kotlin
PDF
Android 101 - Building a simple app with Kotlin in 90 minutes
PPTX
Introduction to Kotlin for Android developers
Privet Kotlin (Windy City DevFest)
Intro to Kotlin
Kotlin cheat sheet by ekito
Kotlin for Android devs
Kotlin, smarter development for the jvm
9054799 dzone-refcard267-kotlin
Kotlin: A pragmatic language by JetBrains
Kotlin what_you_need_to_know-converted event 4 with nigerians
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018
Little Helpers for Android Development with Kotlin
Introduction to Kotlin - Android KTX
2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf
Develop your next app with kotlin @ AndroidMakersFr 2017
A quick and fast intro to Kotlin
2 kotlin vs. java: what java has that kotlin does not
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin intro
Coding for Android on steroids with Kotlin
Android 101 - Building a simple app with Kotlin in 90 minutes
Introduction to Kotlin for Android developers
Ad

Recently uploaded (20)

PDF
System and Network Administraation Chapter 3
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PPTX
Reimagine Home Health with the Power of Agentic AI​
PDF
System and Network Administration Chapter 2
PDF
top salesforce developer skills in 2025.pdf
PPTX
Odoo POS Development Services by CandidRoot Solutions
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
AI in Product Development-omnex systems
PPTX
Introduction to Artificial Intelligence
PPTX
CHAPTER 2 - PM Management and IT Context
PPTX
ai tools demonstartion for schools and inter college
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
System and Network Administraation Chapter 3
2025 Textile ERP Trends: SAP, Odoo & Oracle
How to Choose the Right IT Partner for Your Business in Malaysia
Upgrade and Innovation Strategies for SAP ERP Customers
Reimagine Home Health with the Power of Agentic AI​
System and Network Administration Chapter 2
top salesforce developer skills in 2025.pdf
Odoo POS Development Services by CandidRoot Solutions
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Adobe Illustrator 28.6 Crack My Vision of Vector Design
AI in Product Development-omnex systems
Introduction to Artificial Intelligence
CHAPTER 2 - PM Management and IT Context
ai tools demonstartion for schools and inter college
Design an Analysis of Algorithms I-SECS-1021-03
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Which alternative to Crystal Reports is best for small or large businesses.pdf

Exploring Kotlin

  • 2. 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?
  • 3. Survey ! Already working with Kotlin? ! Familiar with Kotlin? ! Java Devs? ! Backend? ! Android? ! Java 8/9? ! Scala/Groovy/C#/Swift?
  • 4. 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
  • 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 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
  • 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 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
  • 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 // 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
  • 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(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
  • 27. 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
  • 28. 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:
  • 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(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:
  • 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
  • 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 interface Executor<T> { fun execute() : T } class SideEffectExecutor : Executor<Unit> { override fun execute() { // ... } } Unit:
  • 45. Any, Unit, Nothing fun doSomething() { Log.d("Hello", "World") } Unit: fun doSomething(): Unit { Log.d("Hello", "World") }
  • 46. 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
  • 47. 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() { // … }
  • 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 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:
  • 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 ! 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
  • 70. 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
  • 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: ! Virtually the 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! 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"
  • 78. 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:
  • 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/ 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) })
  • 82. 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:
  • 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
  • 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 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/
  • 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 Translated to +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 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)
  • 96. 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)
  • 97. 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))
  • 98. 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
  • 99. 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:
  • 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 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
  • 105. 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()
  • 106. 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
  • 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
  • 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 inline fun <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 inline fun <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.* 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
  • 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/
  • 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 application development 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/failure of 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 a lot 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 ! 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:
  • 137. 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
  • 138. 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
  • 140. 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?)
  • 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