2. What do I know?
— JVM (Java1.4–8
, KotlinM14–1.1
, Groovy1.5
)
— Ruby1.9–2.4
& Rails3.0–5.0
— Perl5.5–5.12
— PHP5.2–5.3
— JavaScript1.5–ECMAScript 6/ES2016/ES6 Harmony/WTF
(when I have to)
— Android & iOS in a pinch
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 2
3. What is it?
— A language for the JVM
— As easy to integrate as Groovy
— Syntax like Java, but cleaner
— Written by JetBrains, who wrote your IDE1
1
If you use the correct IDE
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 3
13. Productivity
— Unit tests can cover functionality, not borders
— Easy refactoring, thanks to powerful tools
— Hard to break things accidentally
— Much less reading the source APIs you're using
— No tracking down parameters
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 13
20. Variables
— vals are immutable (read-only; like final in Java)
— vars are mutable
— Type inference
val foo = "Foo" // is a String
foo = "Bar" // nope, can't change a val
var num = 7
num = 3 // ok
// Java
// final String foo = "Foo";
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 20
21. Null safety
var neverNull: String = "foobar"
var maybeNull: String? = "baz"
neverNull = null // Compiler error
neverNull.length // Guaranteed OK
maybeNull.length // Compiler error
maybeNull?.length // Possible null instead of length
maybeNull!!.length // Possible NPE
var valueOrSadness = maybeNull ?: "it was null !"
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 21
22. Null safety
var neverNull: String = "foobar"
var maybeNull: String? = "baz"
neverNull = null // Compiler error
neverNull.length // Guaranteed OK
maybeNull.length // Compiler error
maybeNull?.length // Possible null instead of length
maybeNull!!.length // Possible NPE
var valueOrSadness = maybeNull ?: "it was null !"
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 22
23. Null safety
var neverNull: String = "foobar"
var maybeNull: String? = "baz"
neverNull = null // Compiler error
neverNull.length // Guaranteed OK
maybeNull.length // Compiler error
maybeNull?.length // Possible null instead of length
maybeNull!!.length // Possible NPE
var valueOrSadness = maybeNull ?: "it was null !"
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 23
24. Null safety
var neverNull: String = "foobar"
var maybeNull: String? = "baz"
neverNull = null // Compiler error
neverNull.length // Guaranteed OK
maybeNull.length // Compiler error
maybeNull?.length // Possible null instead of length
maybeNull!!.length // Possible NPE
var valueOrSadness = maybeNull ?: "it was null !"
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 24
25. Null safety
var neverNull: String = "foobar"
var maybeNull: String? = "baz"
neverNull = null // Compiler error
neverNull.length // Guaranteed OK
maybeNull.length // Compiler error
maybeNull?.length // Possible null instead of length
maybeNull!!.length // Possible NPE
var valueOrSadness = maybeNull ?: "it was null !"
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 25
26. Null safety
var neverNull: String = "foobar"
var maybeNull: String? = "baz"
neverNull = null // Compiler error
neverNull.length // Guaranteed OK
maybeNull.length // Compiler error
maybeNull?.length // Possible null instead of length
maybeNull!!.length // Possible NPE
var valueOrSadness = maybeNull ?: "it was null !"
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 26
27. Null safety
var neverNull: String = "foobar"
var maybeNull: String? = "baz"
neverNull = null // Compiler error
neverNull.length // Guaranteed OK
maybeNull.length // Compiler error
maybeNull?.length // Possible null instead of length
maybeNull!!.length // Possible NPE
var valueOrSadness = maybeNull ?: "it was null !"
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 27
28. Null tracking
if (maybeNull != null && maybeNull.length > 5) {
// maybeNull guaranteed to not be
print("It is ${maybeNull.length} characters")
} else {
print("The variable is null !")
}
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 28
29. Type inference
fun returnsAListOfStrings(): List<String> {
return listOf("foo", "bar")
}
// Java
// final List<String> listOfStrings = returnsAListOfStrings();
// final String firstString = listOfStrings[0];
val listOfStrings = returnsAListOfStrings()
val firstString = listOfStrings[0]
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 29
30. Type inference
fun returnsAListOfStrings(): List<String> {
return listOf("foo", "bar")
}
// Java
// final List<String> listOfStrings = returnsAListOfStrings();
// final String firstString = listOfStrings[0];
val listOfStrings = returnsAListOfStrings()
val firstString = listOfStrings[0]
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 30
31. Type inference
fun returnsAListOfStrings(): List<String> {
return listOf("foo", "bar")
}
// Java
// final List<String> listOfStrings = returnsAListOfStrings();
// final String firstString = listOfStrings[0];
val listOfStrings = returnsAListOfStrings()
val firstString = listOfStrings[0]
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 31
32. POJO
public class Pagechat {
private final int id;
private final String url;
private final boolean fresh;
public Pagechat(int id, String url, boolean fresh) {
this.id = id;
this.url = url;
this.fresh = fresh;
}
public int getId() { return id; }
public String getUrl() { return url; }
public boolean getFresh() { return fresh; }
public boolean equals(Object obj) { … }
public int hashCode() { … }
public String toString() { … }
}
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 32
33. Data class (POJO equivalent)
data class Pagechat(val id: Int,
val url: String,
val fresh: Boolean)
Free stuff:
- Accessors for fields; setters for vars
- equals()/hashCode()
- toString()
- copy()
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 33
34. Param checking in Kotlin
fun updateAddress(newAddress: UpdateAddress): Boolean {
// Guaranteed to be well-formed
...
}
data class UpdateAddress(val userId: Int, val address: Address )
data class Address(val number: Int, val street: String, val zip: Int)
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 34
35. Using the copy constructor
data class Pagechat(val id: Int, val url: String, val fresh: Boolean)
...
fun createPagechat(url: String, fresh: Boolean): Pagechat {
val pagechat = Pagechat(0, "http://foobar.com", true)
// { id: 0, url: "http://foobar.com", fresh: true }
val newId = dao.insert(pagechat)
return pagechat.copy(id = newId)
// { id: $newId, url: "http://foobar.com", fresh: true }
}
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 35
36. Be!er switch statement (when)
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")
}
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 36
37. Named arguments & defaults
data class User(name: String, email: String, admin: Boolean = false)
...
val drew = User("Drew", "drew@dinomite.net")
// drew.admin is false
val plague = User("The Plague", "babbage@ellingson.com", true)
// plague.admin is true
val named = User(email = "foo@bar.com", name = "Foo Bar")
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 37
38. Tail recursion4
tailrec fun findFixPoint(x: Double = 1.0): Double {
val cosine = Math.cos(x)
if (x == cosine) {
return x
} else {
return findFixPoint(cosine)
}
}
// Shorter
tailrec fun findFixPoint(x: Double = 1.0): Double
= if (x == Math.cos(x)) x else findFixPoint(Math.cos(x))
4
https://kotlinlang.org/docs/reference/functions.html#tail-recursive-functions
Drew Stephens • <drew@dinomite.net> • github.com/dinomite/talks 38