Kotlin: A pragmatic language by JetBrains

Preview:

Citation preview

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 anAgile 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

ConciseDrastically 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"

}

SafeAvoid entire classes of errors such as null pointer exceptions.

SAFE

Get rid of those pesky NullPointerExceptions, you know, The Billion Dollar Mistake

var output : Stringoutput = 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() }}

VersatileBuild 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.

InteroperableLeverage 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!"}

ToolingCommand 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 Expressionwhen (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 Inheritanceclass 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"

Packagespackage 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

Recommended