Kotlin
A pragmatic language for JVM and Android
What if I told you that
you already know Kotlin
But who am I?
@jigargosar
I am an
Agile Coach
And
Code Doctor
Conventions used in this talk
● Never == Almost Never
● Always == Almost always
● same goes for right, wrong, good, bad, 100%, 0%
What if I told you that
you already know Kotlin
Hello Kotlin
fun main(args: Array<String>) {
println("Hello Kotlin!")
}
What is Kotlin?
a pragmatic programming
language for JVM and Android
Combines OO and functional
features
Focused on
● interoperability
● safety
● clarity
● tooling support
Kotlin works
everywhere where
Java works
Kotlin works everywhere where Java works
● Server-side applications
● Mobile applications (Android)
● Desktop applications
● Works with all major tools and services such as
○ IntelliJ IDEA, Android Studio and Eclipse
○ Maven, Gradle and Ant
○ Spring Boot
○ GitHub, Slack and even Minecraft
Key focus is on
interoperability and
seamless support for
mixed Java+Kotlin
projects
Is it mature enough and ready for
production?
Is it ready for production?
● Yes. And for quite some time.
● JetBrains, have been using Kotlin in real-life projects on
a rather extensive scale over the last two years.
● Over 500K lines of Kotlin code in projects such as
IntelliJ IDEA and Rider.
● In addition, there are quite a few companies that have
been using Kotlin in production for some time now.
Who’s behind Kotlin?
First and foremost,
Kotlin is an Open
Source language
Open Source language
● Developed on GitHub
● Under Apache 2.0 Open-Source license
● Over 100 contributors to date
● Adoption: 2 million+ Kotlin LOC on GitHub
BUT JetBrains is
the main backer of
Kotlin
Why Kotlin?
Concise, Safe, Versatile, Interoperable, Tooling
Concise
Drastically reduce
the amount of
boilerplate code you
need to write.
Concise
Create a POJO with getters, setters, equals(), hashCode(), toString() and copy() in
a single line:
data class Customer(val name: String,
val email: String,
val company: String)
Concise
Or filter a list using a lambda expression:
val positiveNumbers = list.filter {it > 0}
Concise
Want a Singleton? Create an object:
object ThisIsASingleton {
val companyName: String = "JetBrains"
}
Safe
Avoid entire classes
of errors such as null
pointer exceptions.
SAFE
Get rid of those pesky NullPointerExceptions, you know, The Billion Dollar Mistake
var output : String
output = null // compilation error
And of course, Kotlin protects you from mistakenly operating on nullable types,
including those from Java
println(output.length()) // compilation error
SAFE
And if you check a type is right, the compiler will auto-cast it for you
fun calculateTotal(obj: Any) {
if (obj is Invoice) {
obj.calculateTotal()
}
}
Versatile
Build server-side
applications, Android
apps or frontend code
running in the browser.
Versatile
Multi-purpose language allowing you to build any type of application
● Android Development: No performance impact. Very small runtime.
● JavaScript: Write code in Kotlin and target JavaScript to run on Node.js or in
browser
● Web: Whether you want strongly typed HTML, CSS builders or just plain web
development.
● Application Server
○ The technology doesn't matter. 100% compatible with all JVM frameworks.
● Enterprise: Use Kotlin for any type of Enterprise Java EE development.
Interoperable
Leverage existing
frameworks and libraries
of the JVM with 100%
Java Interoperability.
Create and consume Java code at will
class NettyHandler: ChannelInboundMessageHandlerAdapter<Any>() {
override fun messageReceived(p0: ChannelHandlerContext?, p1: Any?) {
throw UnsupportedOperationException()
}
}
Or use any existing library on the JVM, as there’s 100% compatibility, including
SAM support.
Interoperable
Interoperable
Target either the JVM or JavaScript. Write code in Kotlin and decide where you
want to deploy to
import js.dom.html.*
fun onLoad() {
window.document.body.innerHTML += "<br/>Hello, Kotlin!"
}
Tooling
Command Line
Compiler or First
Class IDE Support.
Freedom to choose.
Basics
Let’s look at real code
Functions
fun sum(a: Int, b: Int): Int {
return a + b
}
fun sum(a: Int, b: Int) = a + b
fun printSum(a: Int, b: Int): Unit {
print(a + b)
}
Variables
val a: Int = 1
val b = 1 // `Int` type is inferred
val c: Int // Type required when no initializer
// is provided
c = 1 // definite assignment
var x = 5 // `Int` type is inferred
x += 1
String Interpolation & docstring
val i = 10
val s = "i = $i" // evaluates to "i = 10"
val s = "abc"
val str = "$s.length is ${s.length}" // evaluates to "abc.length is 3"
val price = """
${'$'}9.99
"""
Conditional Expression
fun max(a: Int, b: Int): Int {
if (a > b)
return a
else
return b
}
fun max(a: Int, b: Int) = if (a > b) a else b
When Expression
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
0, 1 -> print("x == 0 or x == 1")
parseInt(s) -> print("s encodes x")
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
is String -> x.startsWith("prefix")
x.isOdd() -> print("x is odd")
x.isEven() -> print("x is even")
else -> print("otherwise")
}
For Loop, while & do..while
for (item in collection)
print(item)
for (i in array.indices)
print(array[i])
for ((index, value) in array.withIndex()) {
println("the element at $index is $value")
}
Collections
val immutableList = listOf(1, 2, 3)
val mutable = arrayListOf(1, 2, 3)
val immutableMap = mapOf("foo" to 1, "bar" to 2)
val readWriteMap = hashMapOf("foo" to 1, "bar" to 2)
println(map["foo"])
Advanced
Let’s look at real code
null safety
Kotlin’s type system is aimed to eliminate
NullPointerException’s from our code. The only
possible causes of NPE’s may be:
● An explicit call to throw NullPointerException()
● External Java code has caused it
● There’s some data inconsistency with regard to initialization (an uninitialized
this available in a constructor is used somewhere)
null safety
var a: String = "abc"
a = null // compilation error
val l = a.length // safe
var b: String? = "abc"
b = null // ok
val l = if (b != null) b.length else -1
val l = b.length // error: variable 'b' can be null
null safety - Smart Cast
if (b != null && b.length > 0)
print("String of length ${b.length}")
else
print("Empty string")
Smart Type Checks and Casts
if (obj is String) {
print(obj.length) // obj is automatically cast to String
}
if (obj !is String) { // same as !(obj is String)
print("Not a String")
}
else {
print(obj.length)
}
Smart Type Checks and Casts
if (x !is String) return
print(x.length) // x is automatically cast to String
“Unsafe” cast operator
val x: String = y as String // y can’t be null else CCE
val x: String? = y as String? // y can’t be Int
val x: String? = y as? String // y can be anything
Extensions
Extension Functions
fun String.last(): Char {
return this[lastIndex]
}
fun String.last() = this[lastIndex]
val lastChar = "abc".last();
println("lastChar = ${lastChar}")
Nullable Receiver
fun Any?.toString(): String {
if (this == null) return "null"
return toString() // why does this compile?
}
More about Extension
● Extensions are resolved statically
● Extension Properties
● Companion Object Extensions
● Scope of Extensions
● Declaring Extensions as Members
https://kotlinlang.org/docs/reference/extensions.html
Motivation
behind
Extensions?
Classes and Inheritance
Classes and Inheritance
class Empty
class Person(firstName: String) {
init {
logger.info("Customer initialized with value ${name}")
}
}
class Person(val firstName: String, val lastName: String, var age: Int) {
// ...
}
Classes and Inheritance
open class A {
open fun f() { print("A") }
fun a() { print("a") }
}
interface B {
// interface members are 'open' by
default
fun f() { print("B") }
fun b() { print("b") }
}
class C() : A(), B {
// The compiler requires f() to be
overridden:
override fun f() {
super<A>.f() // call to A.f()
super<B>.f() // call to B.f()
}
}
More about Classes and Inheritance
https://kotlinlang.org/docs/reference/classes.html
Data Classes
Data Classes
data class User(val name: String, val age: Int)
data class User(val name: String = "", val age: Int = 0)
● equals()/hashCode() pair,
● toString() of the form "User(name=John, age=42)",
● componentN() functions corresponding to the properties in their order of declaration,
● copy() function (see below).
Data Classes: Copying
// generated by compiler for previous class
fun copy(name: String = this.name, age: Int = this.age) = User(name, age)
val jack = User(name = "Jack", age = 1)
val olderJack = jack.copy(age = 2)
Data Classes and Destructuring Declarations
val jane = User("Jane", 35)
val (name, age) = jane
println("$name, $age years of age")
// prints "Jane, 35 years of age"
Generics
Generics
class Box<T>(t: T) {
var value = t
}
val box: Box<Int> = Box<Int>(1)
val box = Box(1)
// 1 has type Int,
// so the compiler figures out that we are talking about Box<Int>
Generics
https://kotlinlang.org/docs/reference/generics.html
Extra
Functions Infix Notation
val a = 1 to 3
val b = "a".to("z")
val c: Pair<String, String> = "a" to "z"
Packages
package foo.bar
fun baz() {}
class Goo {}
------------------------------------------
import foo.Bar // Bar is now accessible without qualification
import bar.Bar as bBar // bBar stands for 'bar.Bar'
import foo.* // everything in 'foo' becomes accessible

Kotlin: A pragmatic language by JetBrains

  • 1.
    Kotlin A pragmatic languagefor JVM and Android
  • 2.
    What if Itold you that you already know Kotlin
  • 3.
    But who amI? @jigargosar
  • 11.
    I am an AgileCoach And Code Doctor
  • 12.
    Conventions used inthis talk ● Never == Almost Never ● Always == Almost always ● same goes for right, wrong, good, bad, 100%, 0%
  • 13.
    What if Itold you that you already know Kotlin
  • 14.
    Hello Kotlin fun main(args:Array<String>) { println("Hello Kotlin!") }
  • 15.
    What is Kotlin? apragmatic programming language for JVM and Android Combines OO and functional features Focused on ● interoperability ● safety ● clarity ● tooling support
  • 16.
  • 17.
    Kotlin works everywherewhere Java works ● Server-side applications ● Mobile applications (Android) ● Desktop applications ● Works with all major tools and services such as ○ IntelliJ IDEA, Android Studio and Eclipse ○ Maven, Gradle and Ant ○ Spring Boot ○ GitHub, Slack and even Minecraft
  • 18.
    Key focus ison interoperability and seamless support for mixed Java+Kotlin projects
  • 19.
    Is it matureenough and ready for production?
  • 20.
    Is it readyfor production? ● Yes. And for quite some time. ● JetBrains, have been using Kotlin in real-life projects on a rather extensive scale over the last two years. ● Over 500K lines of Kotlin code in projects such as IntelliJ IDEA and Rider. ● In addition, there are quite a few companies that have been using Kotlin in production for some time now.
  • 21.
  • 22.
    First and foremost, Kotlinis an Open Source language
  • 23.
    Open Source language ●Developed on GitHub ● Under Apache 2.0 Open-Source license ● Over 100 contributors to date ● Adoption: 2 million+ Kotlin LOC on GitHub
  • 24.
    BUT JetBrains is themain backer of Kotlin
  • 26.
    Why Kotlin? Concise, Safe,Versatile, Interoperable, Tooling
  • 27.
    Concise Drastically reduce the amountof boilerplate code you need to write.
  • 28.
    Concise Create a POJOwith getters, setters, equals(), hashCode(), toString() and copy() in a single line: data class Customer(val name: String, val email: String, val company: String)
  • 29.
    Concise Or filter alist using a lambda expression: val positiveNumbers = list.filter {it > 0}
  • 30.
    Concise Want a Singleton?Create an object: object ThisIsASingleton { val companyName: String = "JetBrains" }
  • 31.
    Safe Avoid entire classes oferrors such as null pointer exceptions.
  • 32.
    SAFE Get rid ofthose pesky NullPointerExceptions, you know, The Billion Dollar Mistake var output : String output = null // compilation error And of course, Kotlin protects you from mistakenly operating on nullable types, including those from Java println(output.length()) // compilation error
  • 33.
    SAFE And if youcheck a type is right, the compiler will auto-cast it for you fun calculateTotal(obj: Any) { if (obj is Invoice) { obj.calculateTotal() } }
  • 34.
    Versatile Build server-side applications, Android appsor frontend code running in the browser.
  • 35.
    Versatile Multi-purpose language allowingyou to build any type of application ● Android Development: No performance impact. Very small runtime. ● JavaScript: Write code in Kotlin and target JavaScript to run on Node.js or in browser ● Web: Whether you want strongly typed HTML, CSS builders or just plain web development. ● Application Server ○ The technology doesn't matter. 100% compatible with all JVM frameworks. ● Enterprise: Use Kotlin for any type of Enterprise Java EE development.
  • 36.
    Interoperable Leverage existing frameworks andlibraries of the JVM with 100% Java Interoperability.
  • 37.
    Create and consumeJava code at will class NettyHandler: ChannelInboundMessageHandlerAdapter<Any>() { override fun messageReceived(p0: ChannelHandlerContext?, p1: Any?) { throw UnsupportedOperationException() } } Or use any existing library on the JVM, as there’s 100% compatibility, including SAM support. Interoperable
  • 38.
    Interoperable Target either theJVM or JavaScript. Write code in Kotlin and decide where you want to deploy to import js.dom.html.* fun onLoad() { window.document.body.innerHTML += "<br/>Hello, Kotlin!" }
  • 39.
    Tooling Command Line Compiler orFirst Class IDE Support. Freedom to choose.
  • 40.
  • 41.
    Functions fun sum(a: Int,b: Int): Int { return a + b } fun sum(a: Int, b: Int) = a + b fun printSum(a: Int, b: Int): Unit { print(a + b) }
  • 42.
    Variables val a: Int= 1 val b = 1 // `Int` type is inferred val c: Int // Type required when no initializer // is provided c = 1 // definite assignment var x = 5 // `Int` type is inferred x += 1
  • 43.
    String Interpolation &docstring val i = 10 val s = "i = $i" // evaluates to "i = 10" val s = "abc" val str = "$s.length is ${s.length}" // evaluates to "abc.length is 3" val price = """ ${'$'}9.99 """
  • 44.
    Conditional Expression fun max(a:Int, b: Int): Int { if (a > b) return a else return b } fun max(a: Int, b: Int) = if (a > b) a else b
  • 45.
    When Expression when (x){ 1 -> print("x == 1") 2 -> print("x == 2") 0, 1 -> print("x == 0 or x == 1") parseInt(s) -> print("s encodes x") in 1..10 -> print("x is in the range") in validNumbers -> print("x is valid") !in 10..20 -> print("x is outside the range") is String -> x.startsWith("prefix") x.isOdd() -> print("x is odd") x.isEven() -> print("x is even") else -> print("otherwise") }
  • 46.
    For Loop, while& do..while for (item in collection) print(item) for (i in array.indices) print(array[i]) for ((index, value) in array.withIndex()) { println("the element at $index is $value") }
  • 47.
    Collections val immutableList =listOf(1, 2, 3) val mutable = arrayListOf(1, 2, 3) val immutableMap = mapOf("foo" to 1, "bar" to 2) val readWriteMap = hashMapOf("foo" to 1, "bar" to 2) println(map["foo"])
  • 48.
  • 49.
  • 50.
    Kotlin’s type systemis aimed to eliminate NullPointerException’s from our code. The only possible causes of NPE’s may be: ● An explicit call to throw NullPointerException() ● External Java code has caused it ● There’s some data inconsistency with regard to initialization (an uninitialized this available in a constructor is used somewhere)
  • 51.
    null safety var a:String = "abc" a = null // compilation error val l = a.length // safe var b: String? = "abc" b = null // ok val l = if (b != null) b.length else -1 val l = b.length // error: variable 'b' can be null
  • 52.
    null safety -Smart Cast if (b != null && b.length > 0) print("String of length ${b.length}") else print("Empty string")
  • 53.
    Smart Type Checksand Casts if (obj is String) { print(obj.length) // obj is automatically cast to String } if (obj !is String) { // same as !(obj is String) print("Not a String") } else { print(obj.length) }
  • 54.
    Smart Type Checksand Casts if (x !is String) return print(x.length) // x is automatically cast to String
  • 55.
    “Unsafe” cast operator valx: String = y as String // y can’t be null else CCE val x: String? = y as String? // y can’t be Int val x: String? = y as? String // y can be anything
  • 56.
  • 57.
    Extension Functions fun String.last():Char { return this[lastIndex] } fun String.last() = this[lastIndex] val lastChar = "abc".last(); println("lastChar = ${lastChar}")
  • 58.
    Nullable Receiver fun Any?.toString():String { if (this == null) return "null" return toString() // why does this compile? }
  • 59.
    More about Extension ●Extensions are resolved statically ● Extension Properties ● Companion Object Extensions ● Scope of Extensions ● Declaring Extensions as Members https://kotlinlang.org/docs/reference/extensions.html
  • 60.
  • 61.
  • 62.
    Classes and Inheritance classEmpty class Person(firstName: String) { init { logger.info("Customer initialized with value ${name}") } } class Person(val firstName: String, val lastName: String, var age: Int) { // ... }
  • 63.
    Classes and Inheritance openclass A { open fun f() { print("A") } fun a() { print("a") } } interface B { // interface members are 'open' by default fun f() { print("B") } fun b() { print("b") } } class C() : A(), B { // The compiler requires f() to be overridden: override fun f() { super<A>.f() // call to A.f() super<B>.f() // call to B.f() } }
  • 64.
    More about Classesand Inheritance https://kotlinlang.org/docs/reference/classes.html
  • 65.
  • 66.
    Data Classes data classUser(val name: String, val age: Int) data class User(val name: String = "", val age: Int = 0) ● equals()/hashCode() pair, ● toString() of the form "User(name=John, age=42)", ● componentN() functions corresponding to the properties in their order of declaration, ● copy() function (see below).
  • 67.
    Data Classes: Copying //generated by compiler for previous class fun copy(name: String = this.name, age: Int = this.age) = User(name, age) val jack = User(name = "Jack", age = 1) val olderJack = jack.copy(age = 2)
  • 68.
    Data Classes andDestructuring Declarations val jane = User("Jane", 35) val (name, age) = jane println("$name, $age years of age") // prints "Jane, 35 years of age"
  • 69.
  • 70.
    Generics class Box<T>(t: T){ var value = t } val box: Box<Int> = Box<Int>(1) val box = Box(1) // 1 has type Int, // so the compiler figures out that we are talking about Box<Int>
  • 71.
  • 72.
  • 73.
    Functions Infix Notation vala = 1 to 3 val b = "a".to("z") val c: Pair<String, String> = "a" to "z"
  • 74.
    Packages package foo.bar fun baz(){} class Goo {} ------------------------------------------ import foo.Bar // Bar is now accessible without qualification import bar.Bar as bBar // bBar stands for 'bar.Bar' import foo.* // everything in 'foo' becomes accessible