Thanks to our sponsors!

Thank you.
Meet Me:
Dan Lindeman
Software Engineer @ Spantree
(Email: dan@spantree.net)
Master's Student @ GVSU
Meet Kotlin
package demo
fun main(args: Array<String>) {
println("Hello, World!")
}
The Promise

Brief History of Kotlin

Targets



JVM
JavaScript
Native

Who is otlin for?
- People who like
- Pragmatism
- Typing less
- Clean interoperability
- Never getting NullPointerExceptions
- People who have to
- Compile to Java 6



My journey to Kotlin



The call to action
Alternatives
-
Jython- (see jRuby)
-
Scala- Too far "out there"
-
Groovy-
"The world moved on"
-
-
Ceylon- "
Does anyone use this?"
- "








So?
- Spiked a new project
- No (coding) hiccups
- Ant + Kotlin
- When in doubt, write Java
- Unidiomatic

Fig 1. A real concern of mine
Most People
- testsAreAGoodStart.kt
- smallUtilConvertedTo.kt
- FP shallow end
- Low risk
- Fun!

Fig. 2 Ship of Theseus
(see also, your codebase)
Android
- Google IO
- No plans to drop JRE 6
- Android Studio
- Boilerplate reduction*
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// do whatever you want
}});
view.setOnClickListener {
// do whatever you want
}
*fun fact; There used to be
another column here, but I couldn't fit an Android verbosity example without moving it to another slide.

Unidiomatic Basics
// Constructor in the signature
class Person(age: Int, name: String) {
// members var for mutable, val for immutable
var age: Int = age
val name = name
fun sayHello() {
println("Hi, I am $name, and I am $age years old")
}
fun countEvensToTen() {
for (x in 1..10) {
if (x%2 == 0) {
println(x)
} else {
println("nope")
}
}
}
fun gimmeFive(): Int { // return type after colon
return 5
}
fun gimmeSomeMore(amount: Int, howMuchMore: Int): Int {
if (howMuchMore < 1) {
return amount + 1
} else {
return amount + howMuchMore
}
}
}
Idiomatic Basics
class Person(var age: Int, val name: String) {
fun sayHello() {
println("Hi, I am $name, and I am $age years old")
}
fun countEvensToTen() {
(1..10).forEach {
when {
(it % 2 == 0) -> println(it)
else -> println("nope")
}
}
}
fun gimmeFive() = 5
fun gimmeSomeMore(amount: Int, howMuchMore: Int = 1): Int {
return amount + howMuchMore
}
}
fun hello() {
}
Cool Features!
REPL
Null Safety
Elvis Operator
Extension Functions
Data Classes
Lambdas
Object Classes
Companion Objects
Sealed Classes
Coroutines


Null Safety!
var a: String = "abc"
a = null // compilation error
// To allow nulls, we can declare a variable as nullable string,
// written String?
var b: String? = "abc"
b = null // ok
// Now, if you call a method or access a property on a,
// it’s guaranteed not to cause an NPE, so you can safely say
val l = a.length
// But if you want to access the same property on b,
// that would not be safe, and the compiler reports an error:
val l = b.length // error: variable 'b' can be null
Null Safety (cont'd)
// Safe Calls:
val b: String? = "something"
b?.length
// 9
x = "path/to/file"
var y: List<String> = listOf()
if (x != null) {
y = x.split("/") // notice the lack of a check here!
}
bob?.department?.head?.name
// Useful for chaining
// Returns null if any of the properties in it is null
// Heads up you CAN ignore null safety..
// I'm not going to show you how...
val l = b?.length ?: -1
// If the expression to the left of ?: is not null,
// the elvis operator returns it,
// otherwise it returns the expression to the right.
// Note that the right-hand side expression
// is evaluated only if the left-hand side is null.
// This can be very handy, for example, for checking function arguments:
fun foo(node: Node): String? {
val parent = node.getParent() ?: return null
val name = node.getName() ?: throw IllegalArgumentException("name expected")
// ...
}
// Note
fun foo() throws Exception {
// Not actually possible!!!
}
Elvis Operator
?:
?:

Clean Interop?

.java from .kt
public class Customer {
private String name;
public Customer(String s){
name = s;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
val customer = Customer("Phase")
println(customer.name)
.kt from .java
package demo;
public class plainOldJavaPerson {
...
public void doStuffFromKotlinFunctions() {
FunctionalStuffKt.activities();
}
public void doStuffFromKotlinClass() {
Cool c = new Cool(3, "red");
}
...
}
package demo
fun activities() {
// things
}
package demo
class Cool(val id: Int, val color: String){
fun reportInfo(): String {
return "$id, $color"
}
}
Interop


Side-by-Side!*
*Gradle likes them separate
More Interop

Note: This may kill the git history
REPL

On POJOs
public class User {
public String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
} // Line 22
Data Classes
data class User(val name: String, var age: Int)
// Kotlin also provides toString(), equals(), hashCode(), and copy()
// val comes with getter (immutable)
// var comes with getter and setter (mutable)
// Copy
// not a deep copy
val jack = User(name = "Jack", age = 1)
val olderJack = jack.copy(age = 2)
// Extracting fields from the class
val jane = User("Jane", 35)
val (name, age) = jane
println("${jane.name}, ${jane.age} years of age") // prints "Jane, 35 years of age"
// Accessing attributes (also done language-wide)
>>> jane.name
Jane
>>> jane.age = 36
>>> jane
User(name=Jane, age=36)
>>> jane.name = "Jenny"
java.lang.IllegalAccessError: tried to access field Line3$User.name from class Line7
// As of 1.1 can now extend Sealed Classes. Neat!
Sealed Classes


Extension Functions!
// To declare an extension function, we need to prefix its name
// with a receiver type, i.e. the type being extended.
// The following adds a swap function to MutableList<T>:
fun <T> MutableList<T>.swap(index1: Int, index2: Int) {
val tmp = this[index1] // 'this' corresponds to the list
this[index1] = this[index2 + 1]
this[index2] = tmp
}
>>> val l = mutableListOf(1, 2, 3)
>>> l
[1, 2, 3]
>>> l.swap(0, 2)
>>> l
[3, 2, 1]
>>> val r = mutableListOf("a", "b", "c")
>>> r.swap(1,2)
>>> r
[a, c, b]
// Extension functions are resolved statically.
// Extensions do not actually modify classes they extend.
// By defining an extension, you do not insert new members into a class,
// but merely make new functions callable
// with the dot-notation on instances of this class.

Lambdas
// The full syntactic form of lambda expressions, i.e. literals of function types
val sum = { x: Int, y: Int -> x + y }
// A lambda expression is always surrounded by curly braces.
// Parameter declarations in the full syntactic form go inside parentheses
// and have optional type annotations,
// the body goes after an -> sign.
// If we leave all the optional annotations out, what’s left looks like this:
val sum: (Int, Int) -> Int = { x, y -> x + y }
// It’s very common that a lambda expression has only one parameter.
// If Kotlin can figure the signature out itself,
// it allows us not to declare the only parameter,
// and will implicitly declare it for us under the name it:
ints.filter { it > 0 }


Functional Features
val names = listOf( "Cedric", "Marija", "Jonathan",
"Kevin", "Liz", "Richard", "Roberto",
"Sebastian", "Justin", "Andy", "Dan")
val loudNames = names.map { it.toUpperCase() }
// [CEDRIC, MARIJA, JONATHAN, KEVIN,
// LIZ, RICHARD, ROBERTO, SEBASTIAN, JUSTIN, ANDY, DAN]
val shortNames = names.filter { it.length < 5 }
// [Liz, Andy, Dan]
val groupedNames = names.groupBy { it.first() }
// {C=[Cedric], M=[Marija], J=[Jonathan, Justin],
// K=[Kevin], L=[Liz], R=[Richard, Roberto],
// S=[Sebastian], A=[Andy], D=[Dan]}
val letterCount = names.map { it.length }.reduce { a, b -> a + b}
// 64

Other neat things
- Coroutines
- Higher Order Functions
- Kotlin Uncovered
- https://academy.realm.io/posts/360-andev-2017-victoria-gonda-kotlin-uncovered/?
- Exception Handling
- https://spantree.net/blog/2017/09/15/kotlin-exception-handling-with-kategory.html
(worthy of their own talk)
Tooling
- Gradle/Maven/Ant
- IDEs
- IntelliJ / Android Studio
- Eclipse Luna
- Syntax highlighting for 'most editors'
- Static Analysis




Nice Libraries
- Fuel
- TornadoFX (think JavaFX)
- Spek (think rspec)
- Kategory (think cats)
- requery
- Spring
- Any Java library you like


Community
- Kotlin Slack (very active)
- Many library maintainers use it
- Fuel, Kategory
- Andrey Breslav
- Many library maintainers use it
- Talking Kotlin podcast
- KotlinConf (Nov 2-3)
- Kotlin Weekly is great!
- Kotlin User Group support is great!
- Kotlin Subreddit isn't great...
- IntelliJ blog frequently updated
- Kotlin in Action
- Buy it! It's amazing.

Warts
- Youth of community
- Reflection can be wonky
- JavaScript Story

Future
- Roadmap for 1.2
- Improvements/Tooling
- KEEP Kotlin Evolution and Enhancement Process
- Similar to Python's PEP

Electric Sheep

Questions?
Sources:
- https://realm.io/news/droidcon-michael-pardo-kotlin/
- https://kotlinlang.org/docs/
- https://blog.jetbrains.com/kotlin/category/releases/
- https://techbeacon.com/why-you-should-use-kotlin-android-development
- https://kotlinlang.org/docs/reference/idioms.html
- Kevin Greene, Roberto Guerra, Victoria Gonda, Mike Langdon, Corbin Phelps, Nikko Stewart
"Not a deep copy"
>>> data class C (val l: MutableList<Int>)
>>> val c = C(mutableListOf(1,2))
>>> val cc = c.copy()
>>> cc.l.add(10)
true
>>> cc.l
[1, 2, 10]
>>> c.l
[1, 2, 10]
>>>
Meet Kotlin
By dlindema
Meet Kotlin
An introduction to the Kotlin Programming language. And some assorted thoughts on why you should consider the language.
- 1,075