25. Traits and Objects
trait Expr
class Constant(val value: Double) : Expr
class Sum(val op1: Expr, val op2: Expr)
: Expr
object NotANumber : Expr
26. Traits and Objects
trait Expr
class Constant(val value: Double) : Expr
class Sum(val op1: Expr, val op2: Expr)
: Expr
object NotANumber : Expr
27. Traits and Objects
trait Expr
class Constant(val value: Double) : Expr
class Sum(val op1: Expr, val op2: Expr)
: Expr
object NotANumber : Expr
28. Smart Casts
fun eval(e: Expr): Double = when(e) {
is Constant -> e.value
is Sum -> eval(e.op1) + eval(e.op2)
NotANumber -> Double.NaN
else ->
throw IllegalArgumentException()
}
29. Smart Casts
fun eval(e: Expr): Double = when(e) {
is Constant -> e.value
is Sum -> eval(e.op1) + eval(e.op2)
NotANumber -> Double.NaN
else ->
throw IllegalArgumentException()
}
30. Smart Casts
fun eval(e: Expr): Double = when(e) {
is Constant -> e.value
is Sum -> eval(e.op1) + eval(e.op2)
NotANumber -> Double.NaN
else ->
throw IllegalArgumentException()
}
31. Smart Casts
fun eval(e: Expr): Double = when(e) {
is Constant -> e.value
is Sum -> eval(e.op1) + eval(e.op2)
NotANumber -> Double.NaN
else ->
throw IllegalArgumentException()
}
32. Smart Casts
fun eval(e: Expr): Double = when(e) {
is Constant -> e.value
is Sum -> eval(e.op1) + eval(e.op2)
NotANumber -> Double.NaN
else ->
throw IllegalArgumentException()
}
33. Extension Functions
fun Expr.eval(): Double = when(this) {
is Constant -> value
is Sum -> op1.eval() + op2.eval()
NotANumber -> Double.NaN
else ->
throw IllegalArgumentException()
}
34. Extension Functions
fun Expr.eval(): Double = when(this) {
is Constant -> value
is Sum -> op1.eval() + op2.eval()
NotANumber -> Double.NaN
else ->
throw IllegalArgumentException()
}
35. Extension Functions
fun Expr.eval(): Double = when(this) {
is Constant -> value
is Sum -> op1.eval() + op2.eval()
NotANumber -> Double.NaN
else ->
throw IllegalArgumentException()
}
36. Operator Overloading
fun Expr.plus(rhs: Expr)
= Sum(this, rhs)
val Double.toExpr: Expr
get() = Constant(this)
fun exprTest() {
val expr = 1.0.toExpr + 2.0.toExpr
println(eval(expr))
}
37. Operator Overloading
fun Expr.plus(rhs: Expr)
= Sum(this, rhs)
val Double.toExpr: Expr
get() = Constant(this)
fun exprTest() {
val expr = 1.0.toExpr + 2.0.toExpr
println(eval(expr))
}
38. Operator Overloading
fun Expr.plus(rhs: Expr)
= Sum(this, rhs)
val Double.toExpr: Expr
get() = Constant(this)
fun exprTest() {
val expr = 1.0.toExpr + 2.0.toExpr
println(eval(expr))
}
39. Operator Overloading
fun Expr.plus(rhs: Expr)
= Sum(this, rhs)
val Double.toExpr: Expr
get() = Constant(this)
fun exprTest() {
val expr = 1.0.toExpr + 2.0.toExpr
println(eval(expr))
}
40. Operator Overloading
fun Expr.plus(rhs: Expr)
= Sum(this, rhs)
val Double.toExpr: Expr
get() = Constant(this)
fun exprTest() {
val expr = 1.0.toExpr + 2.0.toExpr
println(eval(expr))
}
41. Nullability
open class TreeNode(val parent: TreeNode?,
val left: TreeNode?,
val right: TreeNode?) {
fun depth(): Int {
val parentDepth = if (parent != null)
parent.depth()
else
0
return parentDepth + 1
}
}
42. Nullability
open class TreeNode(val parent: TreeNode?,
val left: TreeNode?,
val right: TreeNode?) {
fun depth(): Int {
val parentDepth = if (parent != null)
parent.depth()
else
0
return parentDepth + 1
}
}
46. Default Parameter Values
fun List<String>.join(sep: String = ", ")
: String {
val sb = StringBuilder()
for (i in 0..size()-1) {
if (i > 0) sb.append(sep)
sb.append(this[i])
}
return sb.toString()
}
47. Default Parameter Values
fun List<String>.join(sep: String = ", ")
: String {
val sb = StringBuilder()
for (i in 0..size()-1) {
if (i > 0) sb.append(sep)
sb.append(this[i])
}
return sb.toString()
}
48. Default Parameter Values
fun List<String>.join(sep: String = ", ")
: String {
val sb = StringBuilder()
for (i in 0..size()-1) {
if (i > 0) sb.append(sep)
sb.append(this[i])
}
return sb.toString()
}
49. Maps
val developers = mapOf(
"Kotlin" to "Andrey",
"Python" to "Guido")
fun report() {
for((language, author) in developers) {
println("$author made $language")
}
println("${developers["Kotlin"]} rocks")
}
50. Maps
val developers = mapOf(
"Kotlin" to "Andrey",
"Python" to "Guido")
fun report() {
for((language, author) in developers) {
println("$author made $language")
}
println("${developers["Kotlin"]} rocks")
}
51. Maps
val developers = mapOf(
"Kotlin" to "Andrey",
"Python" to "Guido")
fun report() {
for((language, author) in developers) {
println("$author made $language")
}
println("${developers["Kotlin"]} rocks")
}
52. Maps
val developers = mapOf(
"Kotlin" to "Andrey",
"Python" to "Guido")
fun report() {
for((language, author) in developers) {
println("$author made $language")
}
println("${developers["Kotlin"]} rocks")
}
57. Inline Functions
public inline fun <T>
Iterable<T>.filter(
predicate: (T) -> Boolean): List<T>
{
val destination = ArrayList<T>()
for (element in this) {
if (predicate(element))
destination.add(element)
}
return destination
}
58. Inline Functions
public inline fun <T>
Iterable<T>.filter(
predicate: (T) -> Boolean): List<T>
{
val destination = ArrayList<T>()
for (element in this) {
if (predicate(element))
destination.add(element)
}
return destination
}
59. Inline Functions
public inline fun <T>
Iterable<T>.filter(
predicate: (T) -> Boolean): List<T>
{
val destination = ArrayList<T>()
for (element in this) {
if (predicate(element))
destination.add(element)
}
return destination
}
60. Function References
fun nobles(persons: List<Person>)
= persons.filter(::isNoble)
fun isNoble(person: Person)
= person.lastName.startsWith("von ") ||
person.lastName.startsWith("zu ")
61. Member Extensions
class Person(val firstName: String,
val lastName: String) {
fun isNoble() = lastName.hasNoblePrefix()
fun String.hasNoblePrefix()
= startsWith("von ") ||
startsWith("zu ")
}
62. Reified Type Parameters
inline fun <reified T>
TreeNode.findParentOfType(): T? {
var p = parent
while (p != null && p !is T) {
p = p?.parent
}
return p as T
}
fun findDirectory(node: TreeNode)
= node.findParentOfType<DirectoryNode>()
63. Reified Type Parameters
inline fun <reified T>
TreeNode.findParentOfType(): T? {
var p = parent
while (p != null && p !is T) {
p = p?.parent
}
return p as T
}
fun findDirectory(node: TreeNode)
= node.findParentOfType<DirectoryNode>()
64. Reified Type Parameters
inline fun <reified T>
TreeNode.findParentOfType(): T? {
var p = parent
while (p != null && p !is T) {
p = p?.parent
}
return p as T
}
fun findDirectory(node: TreeNode)
= node.findParentOfType<DirectoryNode>()
65. Reified Type Parameters
inline fun <reified T>
TreeNode.findParentOfType(): T? {
var p = parent
while (p != null && p !is T) {
p = p?.parent
}
return p as T
}
fun findDirectory(node: TreeNode)
= node.findParentOfType<DirectoryNode>()
66. HTML Builders
h1 {
+"No Users"
}
p {
+"No users found. Please make sure "
a {
href = TeamRoute("invitations", team)
+"invitation codes"
}
+" are available to eligible users."
}
67. HTML Builders
h1 {
+"No Users"
}
p {
+"No users found. Please make sure "
a {
href = TeamRoute("invitations", team)
+"invitation codes"
}
+" are available to eligible users."
}
68. HTML Builders
h1 {
+"No Users"
}
p {
+"No users found. Please make sure "
a {
href = TeamRoute("invitations", team)
+"invitation codes"
}
+" are available to eligible users."
}
78. Status of Kotlin
• Compiler and IntelliJ IDEA plugin stable and
production-ready
79. Status of Kotlin
• Compiler and IntelliJ IDEA plugin stable and
production-ready
• Finalizing design of language and standard library
80. Status of Kotlin
• Compiler and IntelliJ IDEA plugin stable and
production-ready
• Finalizing design of language and standard library
• Expecting 1.0 release later this year
83. Summary
• Kotlin is safe, concise and expressive
• Kotlin can be gradually introduced in any existing
Java project
84. Summary
• Kotlin is safe, concise and expressive
• Kotlin can be gradually introduced in any existing
Java project
• Kotlin is stable and ready for production use