72
THE KOTLIN PROGRAMMING LANGUAGE Sergey Lukjanov, 2012 [email protected] 1 Thursday, February 16, 12

Kotlin techtalk

Embed Size (px)

Citation preview

Page 1: Kotlin techtalk

THE KOTLIN PROGRAMMING LANGUAGE

Sergey Lukjanov, [email protected]

1

Thursday, February 16, 12

Page 2: Kotlin techtalk

WHAT IS KOTLIN?

2

•JVM-targeted

•Statically typed

•Object-oriented

•General purpose

•Programming language

•Docs available today

•Open source from Feb 14

Thursday, February 16, 12

Page 3: Kotlin techtalk

OUTLINE

3

•Motivation

•Design goals

•Feature overview

•Basic syntax

•Classes, types, inheritance

•High-order functions

•Generics

•Tuples

•Pattern matching

•Class objects

Thursday, February 16, 12

Page 4: Kotlin techtalk

MOTIVATION

4

Thursday, February 16, 12

Page 5: Kotlin techtalk

MOTIVATION

4

•IDEA codebase ≥ 200MB Java-code, ≥ 50k classes

Thursday, February 16, 12

Page 6: Kotlin techtalk

MOTIVATION

4

•IDEA codebase ≥ 200MB Java-code, ≥ 50k classes

•Java libraries and community

Thursday, February 16, 12

Page 7: Kotlin techtalk

MOTIVATION

4

•IDEA codebase ≥ 200MB Java-code, ≥ 50k classes

•Java libraries and community

•There are many languages, why not try?

Thursday, February 16, 12

Page 8: Kotlin techtalk

DESIGN GOALS

5

Thursday, February 16, 12

Page 9: Kotlin techtalk

DESIGN GOALS

5

•Full Java interoperability

Thursday, February 16, 12

Page 10: Kotlin techtalk

DESIGN GOALS

5

•Full Java interoperability

•Compiles as fast as Java

Thursday, February 16, 12

Page 11: Kotlin techtalk

DESIGN GOALS

5

•Full Java interoperability

•Compiles as fast as Java

•Safer than Java

Thursday, February 16, 12

Page 12: Kotlin techtalk

DESIGN GOALS

5

•Full Java interoperability

•Compiles as fast as Java

•Safer than Java

•More concise than Java

Thursday, February 16, 12

Page 13: Kotlin techtalk

DESIGN GOALS

5

•Full Java interoperability

•Compiles as fast as Java

•Safer than Java

•More concise than Java

•Way simpler than Scala

Thursday, February 16, 12

Page 14: Kotlin techtalk

FEATURE OVERVIEW 1/2

6

•Static null-safety guarantees

•Traits

•First-class delegation

•Properties (instead of fields)

•Reified generics

•Declaration-site variance & “Type projections”

•High-order functions (“closures”)

•Extension properties and functions

•Inline-functions (zero-overhead closures)

Thursday, February 16, 12

Page 15: Kotlin techtalk

FEATURE OVERVIEW 2/2

7

•Tuples

•Modules and build infrastructure

•Pattern matching

•Range expressions

•String templates

•Singletons

•Operator overloading

•Full-featured IDE by JetBrains

•Java to Kotlin converting

Thursday, February 16, 12

Page 16: Kotlin techtalk

CODE EXAMPLES

8

Thursday, February 16, 12

Page 17: Kotlin techtalk

HELLO, WORLD!

9

fun main(args : Array<String>) : Unit { println("Hello, World!"); }

fun println(any : Any?) /* : Unit */ { System.out?.println(any); }

Thursday, February 16, 12

Page 18: Kotlin techtalk

HELLO, <NAMES>!

10

fun main(args : Array<String>) { var names = ""; // names : String for(idx in args.indices) { names += args[idx] if(idx + 1 < args.size) { names += ", " } } println("Hello, $names!") // Groovy-style templates } val Array<*>.indices : Iterable<Int> get() = IntRange(0, size - 1)

Thursday, February 16, 12

Page 19: Kotlin techtalk

HELLO, <NAMES>! (FASTER)

11

fun main(args : Array<String>) { var names = StringBuilder(); // names : StringBuilder for(idx in args.indices) { names += args[idx] if(idx + 1 < args.size) { names += ", " } } println("Hello, $names!") // Groovy-style templates } fun StringBuilder.plusAssign(any : Any?) { this.append(any) }

Thursday, February 16, 12

Page 20: Kotlin techtalk

HELLO, <NAMES>! (REALISTIC)

12

fun main(args : Array<String>) { println("Hello, ${args.join(", ")}!") }

Thursday, February 16, 12

Page 21: Kotlin techtalk

HELLO, <NAMES>! (REALISTIC)

12

fun main(args : Array<String>) { println("Hello, ${args.join(", ")}!") }

fun <T> Iterable<T>.join(separator : String) : String { val names = StringBuilder() forit (this) { names += it.next() if (it.hasNext) names += separator } return names.toString() ?: "" } fun <T> forit(col : Iterable<T>, f : (Iterator<T>) -> Unit) { val it = col.iterator() while (it.hasNext) f(it) }

Thursday, February 16, 12

Page 22: Kotlin techtalk

NULL-SAFETY 1/2

13

fun parseInt(str : String) : Int? { try { return Integer.parseInt(str) } catch (e : NumberFormatException) { return null } }

Thursday, February 16, 12

Page 23: Kotlin techtalk

NULL-SAFETY 1/2

13

fun parseInt(str : String) : Int? { try { return Integer.parseInt(str) } catch (e : NumberFormatException) { return null } }

fun main(args : Array<String>) { val x = parseInt("1027") val y = parseInt("Hello, World!") // y == null println(x?.times(2)) // can’t write x * 2 println(x?.times(y)) // times argument can't be nullable println(x?.times(y.sure())) // throws NPE if y == null if (x != null) { println(x * 2) } }

Thursday, February 16, 12

Page 24: Kotlin techtalk

NULL-SAFETY 2/2

14

fun String?.isNullOrEmpty() : Boolean { return this == null || this.trim().length == 0 }

Thursday, February 16, 12

Page 25: Kotlin techtalk

NULL-SAFETY 2/2

14

fun main(args : Array<String>) { println("Hello".isNullOrEmpty()) // false println(" World ".isNullOrEmpty()) // false println(" ".isNullOrEmpty()) // true println(null.isNullOrEmpty()) // true }

fun String?.isNullOrEmpty() : Boolean { return this == null || this.trim().length == 0 }

Thursday, February 16, 12

Page 26: Kotlin techtalk

AUTOMATIC CASTS

15

fun foo(obj : Any?) { if (obj is String) { println(obj.get(0)); } }

Thursday, February 16, 12

Page 27: Kotlin techtalk

WHEN STATEMENT

16

fun foo(obj : Any?) { val x : Any? = when (obj) { is String -> obj.get(0) // autocast to String is Int -> obj + 1 // autocast to Int !is Boolean -> null else -> "unknown" } val i : Int = when (obj) { is String -> if(obj.startsWith("a")) 1 else 0 is Int -> obj else -> -1 } }

Thursday, February 16, 12

Page 28: Kotlin techtalk

TYPES 1/2

17

SyntaxSyntax

Class types List<Foo>

Nullable types Foo?

Function types (Int) -> String

Tuple types (Int, Int)

Self types This

Thursday, February 16, 12

Page 29: Kotlin techtalk

TYPES 2/2

18

Special typesSpecial types

Top Any?

Bottom Nothing

No meaningful return value Unit

Thursday, February 16, 12

Page 30: Kotlin techtalk

TYPES HIERARCHY

19

Any?

AnyInt?

Int

Complete lattice

Nothing

String?

Unit

...

Nothing?

Thursday, February 16, 12

Page 31: Kotlin techtalk

MAPPING TO JAVA TYPES

20

Kotlin Java Kotlin

Any Object Any?Unit void UnitInt int IntInt? Integer Int?

String String String?Array<Foo> Foo[] Array<Foo?>?Array<Int> int[] Array<Int>?List<Int> List<Integer> List<Int?>?Nothing - -

Foo Foo Foo?

GEN LOAD

Thursday, February 16, 12

Page 32: Kotlin techtalk

MAPPING TO JAVA TYPES

20

Kotlin Java Kotlin

Any Object Any?Unit void UnitInt int IntInt? Integer Int?

String String String?Array<Foo> Foo[] Array<Foo?>?Array<Int> int[] Array<Int>?List<Int> List<Integer> List<Int?>?Nothing - -

Foo Foo Foo?

GEN LOAD

Thursday, February 16, 12

Page 33: Kotlin techtalk

MAPPING TO JAVA TYPES

20

Kotlin Java Kotlin

Any Object Any?Unit void UnitInt int IntInt? Integer Int?

String String String?Array<Foo> Foo[] Array<Foo?>?Array<Int> int[] Array<Int>?List<Int> List<Integer> List<Int?>?Nothing - -

Foo Foo Foo?

GEN LOAD

Thursday, February 16, 12

Page 34: Kotlin techtalk

MAPPING TO JAVA TYPES

20

Kotlin Java Kotlin

Any Object Any?Unit void UnitInt int IntInt? Integer Int?

String String String?Array<Foo> Foo[] Array<Foo?>?Array<Int> int[] Array<Int>?List<Int> List<Integer> List<Int?>?Nothing - -

Foo Foo Foo?

GEN LOAD

Thursday, February 16, 12

Page 35: Kotlin techtalk

MAPPING TO JAVA TYPES

20

Kotlin Java Kotlin

Any Object Any?Unit void UnitInt int IntInt? Integer Int?

String String String?Array<Foo> Foo[] Array<Foo?>?Array<Int> int[] Array<Int>?List<Int> List<Integer> List<Int?>?Nothing - -

Foo Foo Foo?

GEN LOAD

Thursday, February 16, 12

Page 36: Kotlin techtalk

MAPPING TO JAVA TYPES

20

Kotlin Java Kotlin

Any Object Any?Unit void UnitInt int IntInt? Integer Int?

String String String?Array<Foo> Foo[] Array<Foo?>?Array<Int> int[] Array<Int>?List<Int> List<Integer> List<Int?>?Nothing - -

Foo Foo Foo?

GEN LOAD

Thursday, February 16, 12

Page 37: Kotlin techtalk

MAPPING TO JAVA TYPES

20

Kotlin Java Kotlin

Any Object Any?Unit void UnitInt int IntInt? Integer Int?

String String String?Array<Foo> Foo[] Array<Foo?>?Array<Int> int[] Array<Int>?List<Int> List<Integer> List<Int?>?Nothing - -

Foo Foo Foo?

GEN LOAD

Thursday, February 16, 12

Page 38: Kotlin techtalk

MAPPING TO JAVA TYPES

20

Kotlin Java Kotlin

Any Object Any?Unit void UnitInt int IntInt? Integer Int?

String String String?Array<Foo> Foo[] Array<Foo?>?Array<Int> int[] Array<Int>?List<Int> List<Integer> List<Int?>?Nothing - -

Foo Foo Foo?

GEN LOAD

Thursday, February 16, 12

Page 39: Kotlin techtalk

MAPPING TO JAVA TYPES

20

Kotlin Java Kotlin

Any Object Any?Unit void UnitInt int IntInt? Integer Int?

String String String?Array<Foo> Foo[] Array<Foo?>?Array<Int> int[] Array<Int>?List<Int> List<Integer> List<Int?>?Nothing - -

Foo Foo Foo?

GEN LOAD

Thursday, February 16, 12

Page 40: Kotlin techtalk

MAPPING TO JAVA TYPES

20

Kotlin Java Kotlin

Any Object Any?Unit void UnitInt int IntInt? Integer Int?

String String String?Array<Foo> Foo[] Array<Foo?>?Array<Int> int[] Array<Int>?List<Int> List<Integer> List<Int?>?Nothing - -

Foo Foo Foo?

GEN LOAD

Thursday, February 16, 12

Page 41: Kotlin techtalk

MAPPING TO JAVA TYPES

20

Kotlin Java Kotlin

Any Object Any?Unit void UnitInt int IntInt? Integer Int?

String String String?Array<Foo> Foo[] Array<Foo?>?Array<Int> int[] Array<Int>?List<Int> List<Integer> List<Int?>?Nothing - -

Foo Foo Foo?

GEN LOAD

Thursday, February 16, 12

Page 42: Kotlin techtalk

CLASSES

21

open class Parent(p : Bar) { open fun foo() { }

fun bar() { } } class Child(p : Bar) : Parent(p) { override fun foo() { } }

•Any is the default supertype•Constructors must initialize supertypes•Final by default, explicit override annotations

Thursday, February 16, 12

Page 43: Kotlin techtalk

TRAITS

22

trait T1 : Class1, OtherTrait { // no state } class Foo(p : Bar) : Class1(p), T1, T2 { // ... } class Decorator(p : T2) : Class2(), T2 by p { // ... }

Thursday, February 16, 12

Page 44: Kotlin techtalk

DISAMBIGUATION

23

trait A { fun foo() : Int = 1 // open by default } open class B() { open fun foo() : Int = 2 // not open by default } class C() : B(), A { override fun foo() = super<A>.foo() // returns 1 }

Thursday, February 16, 12

Page 45: Kotlin techtalk

FIRST-CLASS FUNCTIONS

24

fun foo(arg : String) : Boolean // function

(p : Int) -> Int // function type

(Int) -> Int // function type

(a : Int) -> a + 1 // function literal

c -> c.times(2) // function literal

(b) : Int -> b * 2 // function literal

Thursday, February 16, 12

Page 46: Kotlin techtalk

HIGH-ORDER FUNS

25

fun <T> filter( c : Iterable<T>, f: (T)->Boolean):Iterable<T> filter(list, { s -> s.length < 3 })

Thursday, February 16, 12

Page 47: Kotlin techtalk

HIGH-ORDER FUNS

25

fun <T> filter( c : Iterable<T>, f: (T)->Boolean):Iterable<T> filter(list, { s -> s.length < 3 }) filter(list) { s -> s.length < 3 }

Thursday, February 16, 12

Page 48: Kotlin techtalk

HIGH-ORDER FUNS

25

fun <T> filter( c : Iterable<T>, f: (T)->Boolean):Iterable<T> filter(list, { s -> s.length < 3 }) filter(list) { s -> s.length < 3 } // if only one arg:

Thursday, February 16, 12

Page 49: Kotlin techtalk

HIGH-ORDER FUNS

25

fun <T> filter( c : Iterable<T>, f: (T)->Boolean):Iterable<T> filter(list, { s -> s.length < 3 }) filter(list) { s -> s.length < 3 } // if only one arg: filter(list) { it.length < 3 }

Thursday, February 16, 12

Page 50: Kotlin techtalk

LOCAL FUNCTIONS

26

fun reachable(from : Vertex, to : Vertex) : Boolean { val visited = HashSet<Vertex>() fun dfs(current : Vertex) { // here we return from the outer function: if (current == to) return@reachable true // And here - from local function: if (!visited.add(current)) return for (v in current.neighbors) dfs(v) } dfs(from) return false // if dfs() did not return true already }

Thursday, February 16, 12

Page 51: Kotlin techtalk

INFIX FUNCTION CALLS

27

// regular call: a.contains("123") // infix call: a contains "123"

Thursday, February 16, 12

Page 52: Kotlin techtalk

INFIX FUNCTION CALLS

27

// regular call: a.contains("123") // infix call: a contains "123"

// “LINQ”users .filter { it hasPrivilege WRITE } .map { it -> it.fullName } .orderBy { it.lastName }

Thursday, February 16, 12

Page 53: Kotlin techtalk

LOCK EXAMPLE

28

myLock.lock() try { // do something } finally { myLock.unlock() }

Thursday, February 16, 12

Page 54: Kotlin techtalk

LOCK EXAMPLE

28

myLock.lock() try { // do something } finally { myLock.unlock() }

lock(myLock) { // do something }

Thursday, February 16, 12

Page 55: Kotlin techtalk

LOCK EXAMPLE

28

myLock.lock() try { // do something } finally { myLock.unlock() }

lock(myLock) { // do something }

inline fun <T> lock(l : Lock, body : () -> T) : T { l.lock() try { return body() } finally { l.unlock() } }

Thursday, February 16, 12

Page 56: Kotlin techtalk

GENERICS: INVARIANCE

29

class List<T> { fun add(t : T) fun get(idx : Int) : T } val intList = List<Int>() // We should not be able to do it:val anyList : List<Any> = intList anyList.add("1") // Cause of the problem val i : Int = intList.get(0) // !!!

Thursday, February 16, 12

Page 57: Kotlin techtalk

DECLARATION-SITE VARIANCE

30

val intList = List<Int>() val anyList : List<Any> = intList

class List<T> { fun add(t : T) fun get(idx : Int) : T }

Thursday, February 16, 12

Page 58: Kotlin techtalk

DECLARATION-SITE VARIANCE

30

val intList = List<Int>() val anyList : List<Any> = intList

class List<T> { fun add(t : T) fun get(idx : Int) : T }

class Producer<out T> { fun get() : T }

val intProd = Producer<Int>() val anyProd : Producer<Any> = intProd

Thursday, February 16, 12

Page 59: Kotlin techtalk

DECLARATION-SITE VARIANCE

30

val intList = List<Int>() val anyList : List<Any> = intList

class List<T> { fun add(t : T) fun get(idx : Int) : T }

class Producer<out T> { fun get() : T }

val intProd = Producer<Int>() val anyProd : Producer<Any> = intProd

class Consumer<in T> { fun add(t : T) }

val anyCons = Consumer<Any>() val intCons : Consumer<Int> = anyCons

Thursday, February 16, 12

Page 60: Kotlin techtalk

USE-SITE VARIANCE

31

val intList = List<Int>() val anyListOut : List<out Any> = intList anyListOut.add("1") // Not available val i : Int = intList.get(0) // No problem

val anyList = List<Any>() val intListIn : List<in Int> = anyList intListIn.add(123) val obj = intListIn.get(0) // : Any?

Thursday, February 16, 12

Page 61: Kotlin techtalk

REIFIED GENERICS

32

// Type information is retained in runtime foo is List<T> Array<T>(10) T.create() T.javaClass

Thursday, February 16, 12

Page 62: Kotlin techtalk

REIFIED GENERICS

32

// Type information is retained in runtime foo is List<T> Array<T>(10) T.create() T.javaClass

// Java types is still erased... foo is java.util.List<*>

Thursday, February 16, 12

Page 63: Kotlin techtalk

TUPLES

33

class Tuple2<out T1, out T2>( val _1 : T1, val _2 : T2 ) val pair : #(Int, String) = #(1, "") // same as 'Tuple2<Int, String>(1, "")' when (x) { is #(null, *) => throw NullPointerException() is #(val a, val b) => print(a, b) } print("left = ${pair._1}, right = ${pair._2}") val point : #(x : Int, y : Int) // labeled tuple print("x = ${point.x}, y = ${point.y}") val point : #(x : Int, y : Int) = #(y = 10, x = 5)

Thursday, February 16, 12

Page 64: Kotlin techtalk

PATTERN MATCHING 1/2

34

when (a) { is Tree#(*, null) -> print("no right child") is Tree#(val l is Tree, val r is Tree) -> print("$l and $r") is Tree -> print("just a tree") is #(*, val b in 1..100) -> print(b) else -> print("unknown") }

Thursday, February 16, 12

Page 65: Kotlin techtalk

PATTERN MATCHING 1/2

34

when (a) { is Tree#(*, null) -> print("no right child") is Tree#(val l is Tree, val r is Tree) -> print("$l and $r") is Tree -> print("just a tree") is #(*, val b in 1..100) -> print(b) else -> print("unknown") }

class Tree(val left : Tree?, val right : Tree?)

Thursday, February 16, 12

Page 66: Kotlin techtalk

PATTERN MATCHING 1/2

34

when (a) { is Tree#(*, null) -> print("no right child") is Tree#(val l is Tree, val r is Tree) -> print("$l and $r") is Tree -> print("just a tree") is #(*, val b in 1..100) -> print(b) else -> print("unknown") }

class Tree(val left : Tree?, val right : Tree?)

decomposer fun Any?.Tree() : #(Tree?, Tree?)? { return if (this is Tree) #(this.left, this.right) else null }

Thursday, February 16, 12

Page 67: Kotlin techtalk

PATTERN MATCHING 2/2

35

when (d) { is mmddyy#(02, 16, val a) -> print("Feb 16th of $a")) }

class Date(val timestamp : Long) { fun mmddyy() : #(Int, Int, Int)? = #(month, day, year) }

fun Date.mmddyy() : #(Int, Int, Int)? = #(month, day, year)

Thursday, February 16, 12

Page 68: Kotlin techtalk

CLASS OBJECTS 1/2

36

class Example() { class object { fun create() = Example() } } val e = Example.create()

Thursday, February 16, 12

Page 69: Kotlin techtalk

CLASS OBJECTS 2/2

37

trait Factory<T> { fun create() : T } class Example2() { class object : Factory<Example2> { override fun create() = Example2() } } val factory : Factory<Example2> = Example2 val e2 : Example2 = factory.create()

Thursday, February 16, 12

Page 70: Kotlin techtalk

RESOURCES

38

Documentation: http://jetbrains.com/kotlinBlog: http://blog.jetbrains.com/kotlin

Thursday, February 16, 12

Page 71: Kotlin techtalk

THANKS

X

This presentation based on slides and speeches of Andrey Breslav, author of Kotlin language.

Thursday, February 16, 12

Page 72: Kotlin techtalk

Q&A

39

Sergey Lukjanov, [email protected]

Thursday, February 16, 12