SlideShare una empresa de Scribd logo
1 de 119
Descargar para leer sin conexión
Kotlin - Boost Your
Productivity
By Nklmish
@nklmish
Jetbrains
• Develops tools dedicated for
software developers.

• Large code base written in
Java (IDE and server side
tools). 

• E.g. IntelliJ-Community
edition, 3M+ lines of Java
code.
@nklmish
Back in 2010, Jetbrains were
looking for a language…
Java Interoperability
Can use existing Java code base & eco system
Reduce boilerplate code
Concise
Expressive
Easy tooling
Should be easy to prepare tooling for the language
Pragmatic
Solve real world problem
@nklmish
Why not X language ?
• “Most languages did not have the features we were
looking for, with the exception of Scala” - Dmitry Jemerov

• So why not Scala?

• Slow compilation time

• Tooling
@nklmish
Kotlin
• Open source programming language.

• Targets : Server side, client side web, mobile and
native.

• First commit - 8 Nov 2010, First release - 15 Feb
2016

• Gaining momentum - 20K+ repos and millions of lines
of code

• Google officially support it for android development.
@nklmish
Why Kotlin ?
Java Interoperability
We can use existing Java code & libraries as well

As call Java code from Kotlin and vice-versa
Null safety baked into type system
Safe
Statically Typed Easy tooling Pragmatic
Reduce boilerplate code
Concise
Expressive Small Learning Curve
Java developers can leverage there existing knowledge
Support Both
Let’s Get Started!
@nklmish
Hello
fun main(args: Array<String>) {
println("Hello")
}
@nklmish
Hello - source code level
fun main(args: Array<String>) {
println("Hello")
}
kotlin.Array
@nklmish
Hello - source code level
fun main(args: Array<String>) {
println("Hello")
}
kotlin.String
@nklmish
Hello - source code level
fun main(args: Array<String>) {
println("Hello")
}
kotlin.io.println
@nklmish
Hello- bytecode level
public final class com/nklmish/presentation/demo/s/_00Kt {
// access flags 0x19
public final static main([Ljava/lang/String;)V
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
L0
ALOAD 0
LDC "args"
INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V
L1
LINENUMBER 7 L1
LDC "Hello"
ASTORE 1
L2
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
ALOAD 1
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V
L3
L4
LINENUMBER 8 L4
RETURN
L5
LOCALVARIABLE args [Ljava/lang/String; L0 L5 0
MAXSTACK = 2
MAXLOCALS = 2
@Lkotlin/Metadata;(mv={1, 1, 7}, bv={1, 0, 2}, k=2,
d1={"u0000u0014nu0000nu0002u0010u0002nu0000nu0002u0010u0011nu0002u0010u000enu0002u0008u0002u001au0019u0010u0000u0
01au00020u00012u000cu0010u0002u001au0008u0012u0004u0012u00020u00040u0003u00a2u0006u0002u0010u0005u00a8u0006u0006"},
d2={"main", "", "args", "", "", "([Ljava/lang/String;)V", "production sources for module kotlin-presentation_main"})
// compiled from: 00.kt
// debug info: SMAP
00.kt
Kotlin
*S Kotlin
*F
+ 1 00.kt
com/nklmish/presentation/demo/s/_00Kt
*L
1#1,8:1
*E}
@nklmish
But how?
Let’s understand build process
@nklmish
Variable
@nklmish
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3));
val list: List<Int> = listOf(1, 2, 3)
Java Kotlin
Variable
@nklmish
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3));
val list: List<Int> = listOf(1, 2, 3)
Java Kotlin
Why Opposite ?
Variable
@nklmish
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3));
val list = listOf(1, 2, 3)
Java Kotlin
Type inference
Variable
@nklmish
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3));
val list = listOf(1, 2, 3)
Java Kotlin
IntelliJ view!
Function
@nklmish
Function
fun calculateBonus(base : Int, factor : Double) : Double {
return base * factor
}
@nklmish
Function
fun calculateBonus(base : Int, factor : Double) : Double {
return base * factor
}
Single Expression ?
@nklmish
Function
fun calculateBonus(base : Int, factor : Double) : Double {
return base * factor
}
Single Expression ?
Can be omitted
@nklmish
Function
fun calculateBonus(base : Int, factor : Double) : Double = base * factor
@nklmish
Function
fun calculateBonus(base : Int, factor : Double) : Double = base * factor
Type Inference
@nklmish
Function
fun calculateBonus(base : Int, factor : Double) = base * factor
@nklmish
Useful ?
Function
fun calculateBonus(base : Int, factor : Double) = base * factor
@nklmish
Concise +
refactor
Infix function == function
prefixed with “infix”
Must be a member/

extension function
@nklmish
Must take only one parameter
class Stack {
infix fun push(num : Int) {
//
}
}
fun main(args: Array<String>) {
val stack = Stack()
stack push 1
}
class Stack {
fun push(num : Int) {
//
}
}
fun main(args: Array<String>) {
val stack = Stack()
stack.push(1)
}
Infix function - real life
@nklmish
"should assign a default state for a newly launched game" {
game.states.count() shouldBe 1
}
val map = mapOf("Bob" to "123 North Avenue")
kotlintest
Kotlin
Extension functions ==
replace utility classes
@nklmish
fun LocalDateTime.toDate(): Date = Date.from(this.toInstant(OffsetDateTime.now().offset))
Higher order function
@nklmish
fun calculateTotal(amount : Double, exchange: (Double) -> Double) : Double {
val convertedAmount = exchange(amount)
return convertedAmount + (convertedAmount * 0.23)
}
Higher order function
@nklmish
fun calculateTotal(amount : Double, exchange: (Double) -> Double) : Double {
val convertedAmount = exchange(amount)
return convertedAmount + (convertedAmount * 0.23)
}
calculateTotal(100.00) {
amount -> amount * 4.5
}
calculateTotal(100.00) {
amount -> amount * 3.7
}
Invocation
Higher order function
fun calculateTotal(amount : Double, exchange: (Double) -> Double) : Double {
val convertedAmount = exchange(amount)
return convertedAmount + (convertedAmount * 0.23)
}
calculateTotal(100.00) {
amount -> amount * 4.5
}
calculateTotal(100.00) {
amount -> amount * 3.7
}
Lambda, extra cost (Wrapper Function), worried about runtime overhead ?
@nklmish
Inline function == avoid
runtime overhead
@nklmish
inline fun calculateTotal(amount : Double, exchange: (Double) -> Double) : Double {
val convertedAmount = exchange(amount)
return convertedAmount + (convertedAmount * 0.23)
}
Inline function == avoid
runtime overhead
@nklmish
inline fun calculateTotal(amount : Double, exchange: (Double) -> Double) : Double {
val convertedAmount = exchange(amount)
return convertedAmount + (convertedAmount * 0.23)
}
Compiler will replace this call with inline
(copy and paste) code
Inline function lambda
bytecode
@nklmish
inline fun calculateTotal(amount : Double, exchange: (Double) -> Double) : Double {
val convertedAmount = exchange(amount)
return convertedAmount + (convertedAmount * 0.23)
}
calculateTotal(100.00) {
amount -> amount * 4.5
}
calculateTotal(100.00) {
amount -> amount * 3.7
}
Inline function - time
measurement
@nklmish
val elapsedTime = measureTimeMillis { //execute the given code & returns elapsed time in ms.
calculateTotal(100.00) {
amount -> amount * 4.5
}
}
val elapsedTime = measureNanoTime { //execute the given block & returns elapsed time in ns.
...
}
Inline functions
Inline + reified == access
generic type info
@nklmish
@Suppress("UNCHECKED_CAST")
fun <T> Node.parent(clazz: Class<T>): T? {
var tmp = parent
while (tmp != null && !clazz.isInstance(tmp)) tmp = tmp.parent
return tmp as T?
}
//invocation
node.parent(Node::class.java)
Without reified
inline fun <reified T> Node.parent(): T? {
var tmp = parent
while (p != null && p !is T) tmp = tmp.parent
return p as T?
}
//invocation
node.parent<Node>()
Reified
Function literal with
receiver == recipe for DSL
@nklmish
class Delivery {
fun person(function: Person.() -> Unit) : Person {
...
}
fun address(function: Address.() -> Unit) : Address {
...
}
}
fun delivery(function: Delivery.() -> Unit): Delivery {
...
}
Extension fun on Delivery
Function literal with
receiver == recipe for DSL
@nklmish
class Delivery {
fun person(function: Person.() -> Unit) : Person {
...
}
fun address(function: Address.() -> Unit) : Address {
...
}
}
fun delivery(function: Delivery.() -> Unit): Delivery {
...
}
Extension fun on Delivery => we can access
Function literal with
receiver == recipe for DSL
@nklmish
delivery({ })
Syntactic sugar (if lambda is last argument)
delivery() { }== delivery { }==
Calling function “delivery” passing lambda as argument
Function literal with
receiver == recipe for DSL
@nklmish
Function literal with
receiver == recipe for DSL
@nklmish
class Delivery {
fun person(function: Person.() -> Unit) : Person {
...
}
fun address(function: Address.() -> Unit) : Address {
...
}
}
fun delivery(function: Delivery.() -> Unit): Delivery {
...
}
fun onTransit(function: () -> Unit) : TransitInfo {
…
}
fun sendSMS(message: String) {
...
}
Extension fun on Delivery
Extension fun on Address
Extension fun on Person
Higher Order Function
Function literal with
receiver == recipe for DSL
@nklmish
delivery {
person {
name = "Bob"
surname = "Smith"
}
address {
city = “paris"
street = "abc street"
postalCode = "12345"
onTransit {
sendSMS("...")
}
}
}
Final Result
Real life DSL - Anko
verticalLayout {
val name = editText()
button("Say Hello") {
onClick { toast("Hello, ${name.text}!") }
}
}
https://github.com/Kotlin/anko @nklmish
Real life DSL - GradleKotlinDSL
https://github.com/gradle/kotlin-dsl @nklmish
Overloading - Java
@nklmish
Overloading - Java
Which argument is which ?
@nklmish
Overloading - Kotlin
fun print(firstName : String, middleName: String = "", lastName : String = "") = { println("$firstName $middleName $lastName”) }
fun main(args: Array<String>) {
print(firstName = "john")
print(firstName = "john", lastName = "smith")
print(firstName = "john", middleName = "mac", lastName = "smith")
}
Default value Default value
@nklmish
Overloading - Kotlin
fun print(firstName : String, middleName: String = "", lastName : String = "") = println("$firstName $middleName $lastName")
fun main(args: Array<String>) {
print(firstName = "john")
print(firstName = "john", lastName = "smith")
print(firstName = "john", middleName = "mac", lastName = "smith")
}
Named arguments can further improve readability
Classes
@nklmish
Class - Java
public class Schedule {
private final LocalDateTime start;
private final LocalDateTime end;
private String notes;
public Schedule(LocalDateTime start, LocalDateTime end) {
this.start = start;
this.end = end;
}
public LocalDateTime getStart() {
return start;
}
public LocalDateTime getEnd() {
return end;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
}
@nklmish
Class - Kotlin
class Schedule(val start: LocalDateTime, val end: LocalDateTime, var note : String)
@nklmish
Class - Kotlin
class Schedule(val start: LocalDateTime, val end: LocalDateTime, var note : String)
Default: public and final
@nklmish
Class - Kotlin
class Schedule(val start: LocalDateTime, val end: LocalDateTime, var note : String)
Properties
@nklmish
Class - Kotlin
class Schedule(val start: LocalDateTime, val end: LocalDateTime, var note : String)
Immutable Immutable
@nklmish
Class - Kotlin
class Schedule(val start: LocalDateTime, val end: LocalDateTime, var note : String)
Mutable
@nklmish
Data class == data holders
data class Schedule(val start : LocalDateTime, val end : LocalDateTime)
@nklmish
Data class
data class Schedule(val start : LocalDateTime, val end : LocalDateTime)
Autogenerate: meaningful toString(), copy(), equals(), hashcode()
@nklmish
Data class - copy()
val schedule = Schedule(LocalDateTime.now(), LocalDateTime.now().plusSeconds(1))
val copy = schedule.copy()
val copyWithModifiedEndDate = schedule.copy(end = schedule.end.plusSeconds(1)) // we
can change specific fields during copy, comes handy during unit testing
@nklmish
Data class - validation
data class Schedule(val start : LocalDateTime, val end : LocalDateTime) {
init {
if (end.isBefore(start)) throw IllegalArgumentException("end $end should be after start $start")
}
}
@nklmish
String interpolation
Note: String interpolation comes handy when dealing with JSON strings. e.g.
private val expectedServerContent = """
{"name":"$canonicalName","json":"{"id":"$expectedGameProviderId"}","data":{"@foo":".bar","number":"123"},"policy":"","password":""}
""".trimIndent()
Sealed class ~ extension of
enum classes
sealed class Bonus {
data class Yearly(val amount : BigDecimal) : Bonus()
data class Monthly(val amount : BigDecimal, val factor : BigDecimal) : Bonus()
}
@nklmish
Each enum constant exists only as 

a single instance
Enum
Subclass of a sealed class can have
multiple instances which can contain
state
Sealed class
Sealed class ~ extension of
enum classes
sealed class Bonus {
data class Yearly(val amount : BigDecimal) : Bonus()
data class Monthly(val amount : BigDecimal, val factor : BigDecimal) : Bonus()
}
fun evaluate(bonus: Bonus) = when(bonus) {
is Yearly -> bonus.amount
is Monthly -> bonus.amount.multiply(bonus.factor)
}
Abstract class
@nklmish
Delegation
@nklmish
Delegation
class NetworkChaosSimulator{
private ChaosSwitch chaosSwitch = new DefaultSwitch();
public void enableActivationChaos() {
chaosSwitch.enableActivationChaos();
}
public void disableActivationChaos() {
chaosSwitch.disableActivationChaos();
}
public void enableDeactivationChaos() {
chaosSwitch.enableDeactivationChaos();
}
public void disableDeactivationChaos() {
chaosSwitch.disableDeactivationChaos();
}
public boolean isActivationChaosEnabled() {
return chaosSwitch.isActivationChaosEnabled();
}
public boolean isDeactivationChaosEnabled() {
return chaosSwitch.isDeactivationChaosEnabled();
}
}
@nklmish
class NetworkChaosSimulator(switch: ChaosSwitch = DefaultSwitch())
: ChaosSwitch by switch
Java Kotlin
Delegated properties
• Wrap objects with custom behaviour.
@nklmish
Lazy
• Create a new instance only when an object get accessed
for the very first time.
@nklmish
Lazy
class GameRound(val player : String) {
val bets by lazy { fetchBets(this) }
private fun fetchBets(gameRound: GameRound): Int {
...
}
}
@nklmish
Lazy - thread safety ?
class GameRound(val player : String) {
val bets by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { fetchBets(this) }
private fun fetchBets(gameRound: GameRound): Int {
...
}
}
Only a single thread can initialise the Lazy instance.
@nklmish
Lazy - thread safety ?
class GameRound(val player : String) {
val bets by lazy(mode = LazyThreadSafetyMode.PUBLICATION) { fetchBets(this) }
private fun fetchBets(gameRound: GameRound): Int {
...
}
}
Concurrent access permissible but only first returned value will be used.
@nklmish
Lazy - thread safety ?
class GameRound(val player : String) {
val bets by lazy(mode = LazyThreadSafetyMode.NONE) { fetchBets(this) }
private fun fetchBets(gameRound: GameRound): Int {
...
}
}
multiple threads == undefined behaviour
@nklmish
There are more builtin delegated properties like notNull, observable, etc.
We can also create our own.
Lambda
@nklmish
players.filter({p -> p.score > 70})
@nklmish
players.filter({p -> p.score > 70})
players.filter() {p -> p.score > 70}
players.filter {p -> p.score > 70}
players.filter {it.score > 70}
syntactic sugar
Implicit name for a single parameter
@nklmish
• Allows to invoke methods of different object (w/o any
qualifiers) inside there body.
@nklmish@nklmish
with receiver
@nklmish
@nklmish@nklmish@nklmish
public String toCSVFormat(List<Integer> list) {
StringBuilder sb = new StringBuilder("[");
for (Integer integer : list) {
sb.append(integer).append(“;");
}
sb.deleteCharAt(sb.length() - 1);
sb.append("]");
return sb.toString();
}
Java
Kotlin : with (returns result of last call)
fun toCSVFormat(list: List<Int>) =
with(StringBuilder()) {
append("[")
for (i in list) {
append(i).append(";")
}
deleteCharAt(length - 1)
append("]")
toString()
}
with receiver - with
@nklmish@nklmish@nklmish
public String toCSVFormat(List<Integer> list) {
StringBuilder sb = new StringBuilder("[");
for (Integer integer : list) {
sb.append(integer).append(“;");
}
sb.deleteCharAt(sb.length() - 1);
sb.append("]");
return sb.toString();
}
Java Kotlin : apply (returns the receiver)
fun toCSVFormat(list: List<Int>) =
StringBuilder().apply {
append("[")
for (i in list) {
append(i).append(";")
}
deleteCharAt(length - 1)
append("]")
}.toString()
with receiver - apply
Safety
@nklmish
Null safety - baked into type
system
@nklmish
var message : String = "hello"
message = null // compile time error
var message : String? = "hello"
message = null // ok
println(message?.length) //safe operator, if not null then invoke length
Java
message?.let {
process(it)
}
Kotlin
if (message != null) {
process(message);
}
Null safety - using Java API
from Kotlin?
• Annotate Java code with nullability annotations.

• Kotlin can understand annotations from:

• Jetbrains (org.jetbrains.annotations)

• JSR-305 (javax.annotation)

• Android (android.support.annotation)
@nklmish
Misc
@nklmish
For loop - Java
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
@nklmish
For loop - Kotlin
Progressions - to rescue
for (i in 0..9) println(i)
@nklmish
Progressions - to rescue
for (i in 0..9) println(i)
Lots of useful methods : downTo(), stepTo(), until…
@nklmish
Collection
• No Kotlin specific collections.

• Kotlin Collection == Java collection classes + enrichment.
@nklmish
Collection
Immutable
Mutable
@nklmish
Typealias
• Synonyms for pre-existing types
Typealias - without
fun main(args: Array<String>) {
val map : Map<String,String> = mapOf("Bob" to "North Avenue")
}
@nklmish
Less semantics
Typealias - with
typealias FirstName = String
typealias Street = String
fun main(args: Array<String>) {
val map : Map<FirstName, Street> = mapOf("Bob" to "North Avenue")
}
@nklmish
Better Semantics
Casting - Java
Object obj = "Any"
if (obj instanceof String) {
String str = (String) obj;
str.toUpperCase();
}
@nklmish
Casting - Kotlin (smartcast)
val obj:Any = "Any"
if (obj is String) {
obj.toUpperCase() // compiler smartness, auto cast to String
// Works only, if obj is immutable or 

// haven’t changed after check
}
@nklmish
Deprecation
@Deprecated(level = DeprecationLevel.WARNING,
message = "we are going to replace with StringUtils",
replaceWith = @ReplaceWith(
expression = "StringUtils.isEmpty(input)",
imports = {"org.apache.commons.lang3.StringUtils"})
)
public static boolean isEmpty(String input) {
...
}
@nklmish
Deprecation
@Deprecated(level = DeprecationLevel.WARNING,
message = "we are going to replace with StringUtils",
replaceWith = @ReplaceWith(
expression = "StringUtils.isEmpty(input)",
imports = {"org.apache.commons.lang3.StringUtils"})
)
public static boolean isEmpty(String input) {
...
}
level: Warning, Error, Hidden
@nklmish
Deprecation
@Deprecated(level = DeprecationLevel.WARNING,
message = "we are going to replace with StringUtils",
replaceWith = @ReplaceWith(
expression = "StringUtils.isEmpty(input)",
imports = {"org.apache.commons.lang3.StringUtils"})
)
public static boolean isEmpty(String input) {
...
}
Method to replace with
@nklmish
Deprecation
@Deprecated(level = DeprecationLevel.WARNING,
message = "we are going to replace with StringUtils",
replaceWith = @ReplaceWith(
expression = "StringUtils.isEmpty(input)",
imports = {"org.apache.commons.lang3.StringUtils"})
)
public static boolean isEmpty(String input) {
...
}
Which class to import
@nklmish
Deprecation - final result
@nklmish
when == powerful switch
fun playerPrivileges(rank : Int) = when(rank) {
in 1..3 -> "VIP"
in 4..50 -> "Elevated"
in 51..1000 -> "Classic"
else -> "Regular"
}
@nklmish
when == powerful switch
fun playerPrivileges(rank : Int) = when(rank) {
in 1..3 -> "VIP"
in 4..50 -> "Elevated"
in 51..1000 -> "Classic"
else -> "Regular"
}
Can be any type, no limitations
@nklmish
when == powerful switch
fun playerPrivileges(rank : Int) = when(rank) {
in 1..3 -> "VIP"
in 4..50 -> "Elevated"
in 51..1000 -> "Classic"
else -> "Regular"
}
No need to type break
@nklmish
Operator overloading -
Java?public class Wallet {
public Wallet(Integer amount) {
this.amount = amount;
}
private final Integer amount;
public Wallet plus(Wallet w) {
return new Wallet(this.amount + w.amount);
}
public Wallet minus(Wallet w) {
return new Wallet(this.amount - w.amount);
}
public Wallet multiply(Wallet w) {
return new Wallet(this.amount * w.amount);
}
}
Wallet walletA = new Wallet(100);
Wallet walletB = new Wallet(200);
walletA.plus(walletB);
walletA.subtract(walletB);
walletA.multiply(walletB);
@nklmish
Operator overloading -
Kotlin
data class Wallet(val amount : Int) {
operator fun plus(w : Wallet) = Wallet(amount.plus(w.amount))
operator fun minus(w : Wallet) = Wallet(amount.minus(w.amount))
operator fun times(w : Wallet) = Wallet(amount.minus(w.amount))
}
val walletA = Wallet(100)
val walletB = Wallet(200)
walletA + walletB
walletA - walletB
walletA * walletB
@nklmish
Operator overloading -
Kotlin
Naming Convention Syntax
plus walletA + walletB
unaryPlus +walletA
minus walletA - walletB
unaryMinus -walletA
inc ++walletA
dec — walletA
times walletA * walletB
div walletA / walletB
mod walletA % walletB
not !walletA
@nklmish
Co-routines == asyn
programming made simple
@nklmish
val jobs = List(1_000_000) {
async(CommonPool) {
delay(10L)
1.0
}
}
runBlocking {
println(jobs.sumByDouble { it.await() })
}
Co-routines == asyn
programming made simple
@nklmish
val jobs = List(1_000_000) {
async(CommonPool) {
delay(10L)
1.0
}
}
runBlocking {
println(jobs.sumByDouble { it.await() })
}
Lightweight
TODO
@nklmish
Kotlin + Spring
@nklmish
Kotlin + Spring
@nklmish
Kotlin + Spring -
build.gradle
@nklmish
dependencies {
classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion")
}
Kotlin + Spring -
build.gradle
@nklmish
dependencies {
classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion")
}
Before plugin
After Plugin
@SpringBootApplication
open class PhoneBookApplication {
@Bean
open fun passwordEncoder(): PasswordEncoder {
return BCryptPasswordEncoder()
}
}
@SpringBootApplication
class PhoneBookApplication {
@Bean
fun passwordEncoder(): PasswordEncoder {
return BCryptPasswordEncoder()
}
}
Kotlin + Spring -
build.gradle
@nklmish
dependencies {
classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion")
}
@Document
data class Contact(@Id val id: String = UUID.randomUUID().toString(),
val firstName: String,
var lastName: String,
val phones: List<String> = emptyList()
)
Kotlin + Spring - controller
@nklmish
Kotlin + Spring - controller
@nklmish
Constructor injection(no @Autowired required)
Kotlin + Spring - controller
@nklmish
Type Inference
Kotlin + Spring - 

null safety?
@nklmish
@GetMapping("/schedule")
fun getSchedule(@RequestParam id: Long): Mono<ScheduleDto> =
scheduleService.findOne(id).map { it.get().dto() }
@GetMapping("/schedule")
fun getSchedule(@RequestParam id: Long?): Mono<ScheduleDto> =
scheduleService.findOne(id).map { it.get().dto() }
Kotlin + Spring - null safety
@nklmish
Kotlin + Spring
@nklmish
@GetMapping(path = arrayOf("/schedules"), produces = arrayOf(TEXT_EVENT_STREAM_VALUE))
fun getSchedules(): Flux<ScheduleDto> = scheduleService.findAll().map { it.dto() }
route(
path(“/schedules”).and(accept(TEXT_EVENT_STREAM_VALUE)),
)
Same thing expressed in Kotlin
Who uses Kotlin…
• Amazon

• Uber

• Netflix

• Foursquare

• Expedia

• HSBC

• Goldman Sachs

• Trello

• Casumo

• …
@nklmish
Useful links
• http://slack.kotlinlang.org/

• https://kotlin.link/
@nklmish
Questions?
https://tinyurl.com/y9lgkpc8
@nklmish
Review

Más contenido relacionado

La actualidad más candente

eMan Dev Meetup: Kotlin - A Language we should know it exists (part 02/03) 18...
eMan Dev Meetup: Kotlin - A Language we should know it exists (part 02/03) 18...eMan Dev Meetup: Kotlin - A Language we should know it exists (part 02/03) 18...
eMan Dev Meetup: Kotlin - A Language we should know it exists (part 02/03) 18...eMan s.r.o.
 
Anko - The Ultimate Ninja of Kotlin Libraries?
Anko - The Ultimate Ninja of Kotlin Libraries?Anko - The Ultimate Ninja of Kotlin Libraries?
Anko - The Ultimate Ninja of Kotlin Libraries?Kai Koenig
 
Building microservices with Kotlin
Building microservices with KotlinBuilding microservices with Kotlin
Building microservices with KotlinHaim Yadid
 
Kotlin a problem solver - gdd extended pune
Kotlin   a problem solver - gdd extended puneKotlin   a problem solver - gdd extended pune
Kotlin a problem solver - gdd extended puneHardik Trivedi
 
The Kotlin Programming Language
The Kotlin Programming LanguageThe Kotlin Programming Language
The Kotlin Programming Languageintelliyole
 
K is for Kotlin
K is for KotlinK is for Kotlin
K is for KotlinTechMagic
 
Intro to Kotlin
Intro to KotlinIntro to Kotlin
Intro to KotlinMagda Miu
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlinThijs Suijten
 
Develop your next app with kotlin @ AndroidMakersFr 2017
Develop your next app with kotlin @ AndroidMakersFr 2017Develop your next app with kotlin @ AndroidMakersFr 2017
Develop your next app with kotlin @ AndroidMakersFr 2017Arnaud Giuliani
 
Kotlin in action
Kotlin in actionKotlin in action
Kotlin in actionCiro Rizzo
 
Swift and Kotlin Presentation
Swift and Kotlin PresentationSwift and Kotlin Presentation
Swift and Kotlin PresentationAndrzej Sitek
 
Kotlin, smarter development for the jvm
Kotlin, smarter development for the jvmKotlin, smarter development for the jvm
Kotlin, smarter development for the jvmArnaud Giuliani
 
Kotlin hands on - MorningTech ekito 2017
Kotlin hands on - MorningTech ekito 2017Kotlin hands on - MorningTech ekito 2017
Kotlin hands on - MorningTech ekito 2017Arnaud Giuliani
 
Little Helpers for Android Development with Kotlin
Little Helpers for Android Development with KotlinLittle Helpers for Android Development with Kotlin
Little Helpers for Android Development with KotlinKai Koenig
 
Kotlin: Challenges in JVM language design
Kotlin: Challenges in JVM language designKotlin: Challenges in JVM language design
Kotlin: Challenges in JVM language designAndrey Breslav
 
Kotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developersKotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developersBartosz Kosarzycki
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?Tomasz Wrobel
 
Kotlin cheat sheet by ekito
Kotlin cheat sheet by ekitoKotlin cheat sheet by ekito
Kotlin cheat sheet by ekitoArnaud Giuliani
 
API management with Taffy and API Blueprint
API management with Taffy and API BlueprintAPI management with Taffy and API Blueprint
API management with Taffy and API BlueprintKai Koenig
 

La actualidad más candente (20)

eMan Dev Meetup: Kotlin - A Language we should know it exists (part 02/03) 18...
eMan Dev Meetup: Kotlin - A Language we should know it exists (part 02/03) 18...eMan Dev Meetup: Kotlin - A Language we should know it exists (part 02/03) 18...
eMan Dev Meetup: Kotlin - A Language we should know it exists (part 02/03) 18...
 
Anko - The Ultimate Ninja of Kotlin Libraries?
Anko - The Ultimate Ninja of Kotlin Libraries?Anko - The Ultimate Ninja of Kotlin Libraries?
Anko - The Ultimate Ninja of Kotlin Libraries?
 
Building microservices with Kotlin
Building microservices with KotlinBuilding microservices with Kotlin
Building microservices with Kotlin
 
Kotlin a problem solver - gdd extended pune
Kotlin   a problem solver - gdd extended puneKotlin   a problem solver - gdd extended pune
Kotlin a problem solver - gdd extended pune
 
The Kotlin Programming Language
The Kotlin Programming LanguageThe Kotlin Programming Language
The Kotlin Programming Language
 
Kotlin - Better Java
Kotlin - Better JavaKotlin - Better Java
Kotlin - Better Java
 
K is for Kotlin
K is for KotlinK is for Kotlin
K is for Kotlin
 
Intro to Kotlin
Intro to KotlinIntro to Kotlin
Intro to Kotlin
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlin
 
Develop your next app with kotlin @ AndroidMakersFr 2017
Develop your next app with kotlin @ AndroidMakersFr 2017Develop your next app with kotlin @ AndroidMakersFr 2017
Develop your next app with kotlin @ AndroidMakersFr 2017
 
Kotlin in action
Kotlin in actionKotlin in action
Kotlin in action
 
Swift and Kotlin Presentation
Swift and Kotlin PresentationSwift and Kotlin Presentation
Swift and Kotlin Presentation
 
Kotlin, smarter development for the jvm
Kotlin, smarter development for the jvmKotlin, smarter development for the jvm
Kotlin, smarter development for the jvm
 
Kotlin hands on - MorningTech ekito 2017
Kotlin hands on - MorningTech ekito 2017Kotlin hands on - MorningTech ekito 2017
Kotlin hands on - MorningTech ekito 2017
 
Little Helpers for Android Development with Kotlin
Little Helpers for Android Development with KotlinLittle Helpers for Android Development with Kotlin
Little Helpers for Android Development with Kotlin
 
Kotlin: Challenges in JVM language design
Kotlin: Challenges in JVM language designKotlin: Challenges in JVM language design
Kotlin: Challenges in JVM language design
 
Kotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developersKotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developers
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
 
Kotlin cheat sheet by ekito
Kotlin cheat sheet by ekitoKotlin cheat sheet by ekito
Kotlin cheat sheet by ekito
 
API management with Taffy and API Blueprint
API management with Taffy and API BlueprintAPI management with Taffy and API Blueprint
API management with Taffy and API Blueprint
 

Similar a Kotlin boost yourproductivity

Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
Functional Programming - Past, Present and Future
Functional Programming - Past, Present and FutureFunctional Programming - Past, Present and Future
Functional Programming - Past, Present and FuturePushkar Kulkarni
 
Functional Programming Past Present Future
Functional Programming Past Present FutureFunctional Programming Past Present Future
Functional Programming Past Present FutureIndicThreads
 
Cocoa Design Patterns in Swift
Cocoa Design Patterns in SwiftCocoa Design Patterns in Swift
Cocoa Design Patterns in SwiftMichele Titolo
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with ScalaNeelkanth Sachdeva
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)Pavlo Baron
 
Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With ScalaKnoldus Inc.
 
Kotlin coroutines and spring framework
Kotlin coroutines and spring frameworkKotlin coroutines and spring framework
Kotlin coroutines and spring frameworkSunghyouk Bae
 
2019-01-29 - Demystifying Kotlin Coroutines
2019-01-29 - Demystifying Kotlin Coroutines2019-01-29 - Demystifying Kotlin Coroutines
2019-01-29 - Demystifying Kotlin CoroutinesEamonn Boyle
 
Emerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonEmerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonAlex Payne
 
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...GeeksLab Odessa
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java ProgrammersEric Pederson
 
Introduction to Scalding and Monoids
Introduction to Scalding and MonoidsIntroduction to Scalding and Monoids
Introduction to Scalding and MonoidsHugo Gävert
 

Similar a Kotlin boost yourproductivity (20)

Scala in Places API
Scala in Places APIScala in Places API
Scala in Places API
 
Introduction to Kotlin
Introduction to KotlinIntroduction to Kotlin
Introduction to Kotlin
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Functional Programming - Past, Present and Future
Functional Programming - Past, Present and FutureFunctional Programming - Past, Present and Future
Functional Programming - Past, Present and Future
 
Functional Programming Past Present Future
Functional Programming Past Present FutureFunctional Programming Past Present Future
Functional Programming Past Present Future
 
Cocoa Design Patterns in Swift
Cocoa Design Patterns in SwiftCocoa Design Patterns in Swift
Cocoa Design Patterns in Swift
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with Scala
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With Scala
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
 
Kotlin coroutines and spring framework
Kotlin coroutines and spring frameworkKotlin coroutines and spring framework
Kotlin coroutines and spring framework
 
2019-01-29 - Demystifying Kotlin Coroutines
2019-01-29 - Demystifying Kotlin Coroutines2019-01-29 - Demystifying Kotlin Coroutines
2019-01-29 - Demystifying Kotlin Coroutines
 
Emerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonEmerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the Horizon
 
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java Programmers
 
Introduction to Scalding and Monoids
Introduction to Scalding and MonoidsIntroduction to Scalding and Monoids
Introduction to Scalding and Monoids
 

Más de nklmish

Demystifying Kafka
Demystifying KafkaDemystifying Kafka
Demystifying Kafkanklmish
 
Scaling CQRS in theory, practice, and reality
Scaling CQRS in theory, practice, and realityScaling CQRS in theory, practice, and reality
Scaling CQRS in theory, practice, and realitynklmish
 
CQRS and EventSourcing with Spring & Axon
CQRS and EventSourcing with Spring & AxonCQRS and EventSourcing with Spring & Axon
CQRS and EventSourcing with Spring & Axonnklmish
 
(SPRING)KAFKA - ONE MORE ARSENAL IN A DISTRIBUTED TOOLBOX
(SPRING)KAFKA - ONE MORE ARSENAL IN A DISTRIBUTED TOOLBOX(SPRING)KAFKA - ONE MORE ARSENAL IN A DISTRIBUTED TOOLBOX
(SPRING)KAFKA - ONE MORE ARSENAL IN A DISTRIBUTED TOOLBOXnklmish
 
Distributed tracing - get a grasp on your production
Distributed tracing - get a grasp on your productionDistributed tracing - get a grasp on your production
Distributed tracing - get a grasp on your productionnklmish
 
Microservice no fluff, the REAL stuff
Microservice no fluff, the REAL stuffMicroservice no fluff, the REAL stuff
Microservice no fluff, the REAL stuffnklmish
 
Mongo - an intermediate introduction
Mongo - an intermediate introductionMongo - an intermediate introduction
Mongo - an intermediate introductionnklmish
 
Detailed Introduction To Docker
Detailed Introduction To DockerDetailed Introduction To Docker
Detailed Introduction To Dockernklmish
 

Más de nklmish (10)

Demystifying Kafka
Demystifying KafkaDemystifying Kafka
Demystifying Kafka
 
Scaling CQRS in theory, practice, and reality
Scaling CQRS in theory, practice, and realityScaling CQRS in theory, practice, and reality
Scaling CQRS in theory, practice, and reality
 
CQRS and EventSourcing with Spring & Axon
CQRS and EventSourcing with Spring & AxonCQRS and EventSourcing with Spring & Axon
CQRS and EventSourcing with Spring & Axon
 
(SPRING)KAFKA - ONE MORE ARSENAL IN A DISTRIBUTED TOOLBOX
(SPRING)KAFKA - ONE MORE ARSENAL IN A DISTRIBUTED TOOLBOX(SPRING)KAFKA - ONE MORE ARSENAL IN A DISTRIBUTED TOOLBOX
(SPRING)KAFKA - ONE MORE ARSENAL IN A DISTRIBUTED TOOLBOX
 
Distributed tracing - get a grasp on your production
Distributed tracing - get a grasp on your productionDistributed tracing - get a grasp on your production
Distributed tracing - get a grasp on your production
 
Spock
SpockSpock
Spock
 
Microservice no fluff, the REAL stuff
Microservice no fluff, the REAL stuffMicroservice no fluff, the REAL stuff
Microservice no fluff, the REAL stuff
 
Neo4J
Neo4JNeo4J
Neo4J
 
Mongo - an intermediate introduction
Mongo - an intermediate introductionMongo - an intermediate introduction
Mongo - an intermediate introduction
 
Detailed Introduction To Docker
Detailed Introduction To DockerDetailed Introduction To Docker
Detailed Introduction To Docker
 

Último

What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 

Último (20)

What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 

Kotlin boost yourproductivity

  • 1. Kotlin - Boost Your Productivity By Nklmish @nklmish
  • 2. Jetbrains • Develops tools dedicated for software developers. • Large code base written in Java (IDE and server side tools). • E.g. IntelliJ-Community edition, 3M+ lines of Java code. @nklmish
  • 3. Back in 2010, Jetbrains were looking for a language… Java Interoperability Can use existing Java code base & eco system Reduce boilerplate code Concise Expressive Easy tooling Should be easy to prepare tooling for the language Pragmatic Solve real world problem @nklmish
  • 4. Why not X language ? • “Most languages did not have the features we were looking for, with the exception of Scala” - Dmitry Jemerov • So why not Scala? • Slow compilation time • Tooling @nklmish
  • 5. Kotlin • Open source programming language. • Targets : Server side, client side web, mobile and native. • First commit - 8 Nov 2010, First release - 15 Feb 2016 • Gaining momentum - 20K+ repos and millions of lines of code • Google officially support it for android development. @nklmish
  • 6. Why Kotlin ? Java Interoperability We can use existing Java code & libraries as well As call Java code from Kotlin and vice-versa Null safety baked into type system Safe Statically Typed Easy tooling Pragmatic Reduce boilerplate code Concise Expressive Small Learning Curve Java developers can leverage there existing knowledge Support Both
  • 8. Hello fun main(args: Array<String>) { println("Hello") } @nklmish
  • 9. Hello - source code level fun main(args: Array<String>) { println("Hello") } kotlin.Array @nklmish
  • 10. Hello - source code level fun main(args: Array<String>) { println("Hello") } kotlin.String @nklmish
  • 11. Hello - source code level fun main(args: Array<String>) { println("Hello") } kotlin.io.println @nklmish
  • 12. Hello- bytecode level public final class com/nklmish/presentation/demo/s/_00Kt { // access flags 0x19 public final static main([Ljava/lang/String;)V @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 L0 ALOAD 0 LDC "args" INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V L1 LINENUMBER 7 L1 LDC "Hello" ASTORE 1 L2 GETSTATIC java/lang/System.out : Ljava/io/PrintStream; ALOAD 1 INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V L3 L4 LINENUMBER 8 L4 RETURN L5 LOCALVARIABLE args [Ljava/lang/String; L0 L5 0 MAXSTACK = 2 MAXLOCALS = 2 @Lkotlin/Metadata;(mv={1, 1, 7}, bv={1, 0, 2}, k=2, d1={"u0000u0014nu0000nu0002u0010u0002nu0000nu0002u0010u0011nu0002u0010u000enu0002u0008u0002u001au0019u0010u0000u0 01au00020u00012u000cu0010u0002u001au0008u0012u0004u0012u00020u00040u0003u00a2u0006u0002u0010u0005u00a8u0006u0006"}, d2={"main", "", "args", "", "", "([Ljava/lang/String;)V", "production sources for module kotlin-presentation_main"}) // compiled from: 00.kt // debug info: SMAP 00.kt Kotlin *S Kotlin *F + 1 00.kt com/nklmish/presentation/demo/s/_00Kt *L 1#1,8:1 *E} @nklmish
  • 14. Let’s understand build process @nklmish
  • 15. Variable @nklmish List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3)); val list: List<Int> = listOf(1, 2, 3) Java Kotlin
  • 16. Variable @nklmish List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3)); val list: List<Int> = listOf(1, 2, 3) Java Kotlin Why Opposite ?
  • 17. Variable @nklmish List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3)); val list = listOf(1, 2, 3) Java Kotlin Type inference
  • 18. Variable @nklmish List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3)); val list = listOf(1, 2, 3) Java Kotlin IntelliJ view!
  • 20. Function fun calculateBonus(base : Int, factor : Double) : Double { return base * factor } @nklmish
  • 21. Function fun calculateBonus(base : Int, factor : Double) : Double { return base * factor } Single Expression ? @nklmish
  • 22. Function fun calculateBonus(base : Int, factor : Double) : Double { return base * factor } Single Expression ? Can be omitted @nklmish
  • 23. Function fun calculateBonus(base : Int, factor : Double) : Double = base * factor @nklmish
  • 24. Function fun calculateBonus(base : Int, factor : Double) : Double = base * factor Type Inference @nklmish
  • 25. Function fun calculateBonus(base : Int, factor : Double) = base * factor @nklmish Useful ?
  • 26. Function fun calculateBonus(base : Int, factor : Double) = base * factor @nklmish Concise + refactor
  • 27. Infix function == function prefixed with “infix” Must be a member/
 extension function @nklmish Must take only one parameter class Stack { infix fun push(num : Int) { // } } fun main(args: Array<String>) { val stack = Stack() stack push 1 } class Stack { fun push(num : Int) { // } } fun main(args: Array<String>) { val stack = Stack() stack.push(1) }
  • 28. Infix function - real life @nklmish "should assign a default state for a newly launched game" { game.states.count() shouldBe 1 } val map = mapOf("Bob" to "123 North Avenue") kotlintest Kotlin
  • 29. Extension functions == replace utility classes @nklmish fun LocalDateTime.toDate(): Date = Date.from(this.toInstant(OffsetDateTime.now().offset))
  • 30. Higher order function @nklmish fun calculateTotal(amount : Double, exchange: (Double) -> Double) : Double { val convertedAmount = exchange(amount) return convertedAmount + (convertedAmount * 0.23) }
  • 31. Higher order function @nklmish fun calculateTotal(amount : Double, exchange: (Double) -> Double) : Double { val convertedAmount = exchange(amount) return convertedAmount + (convertedAmount * 0.23) } calculateTotal(100.00) { amount -> amount * 4.5 } calculateTotal(100.00) { amount -> amount * 3.7 } Invocation
  • 32. Higher order function fun calculateTotal(amount : Double, exchange: (Double) -> Double) : Double { val convertedAmount = exchange(amount) return convertedAmount + (convertedAmount * 0.23) } calculateTotal(100.00) { amount -> amount * 4.5 } calculateTotal(100.00) { amount -> amount * 3.7 } Lambda, extra cost (Wrapper Function), worried about runtime overhead ? @nklmish
  • 33. Inline function == avoid runtime overhead @nklmish inline fun calculateTotal(amount : Double, exchange: (Double) -> Double) : Double { val convertedAmount = exchange(amount) return convertedAmount + (convertedAmount * 0.23) }
  • 34. Inline function == avoid runtime overhead @nklmish inline fun calculateTotal(amount : Double, exchange: (Double) -> Double) : Double { val convertedAmount = exchange(amount) return convertedAmount + (convertedAmount * 0.23) } Compiler will replace this call with inline (copy and paste) code
  • 35. Inline function lambda bytecode @nklmish inline fun calculateTotal(amount : Double, exchange: (Double) -> Double) : Double { val convertedAmount = exchange(amount) return convertedAmount + (convertedAmount * 0.23) } calculateTotal(100.00) { amount -> amount * 4.5 } calculateTotal(100.00) { amount -> amount * 3.7 }
  • 36. Inline function - time measurement @nklmish val elapsedTime = measureTimeMillis { //execute the given code & returns elapsed time in ms. calculateTotal(100.00) { amount -> amount * 4.5 } } val elapsedTime = measureNanoTime { //execute the given block & returns elapsed time in ns. ... } Inline functions
  • 37. Inline + reified == access generic type info @nklmish @Suppress("UNCHECKED_CAST") fun <T> Node.parent(clazz: Class<T>): T? { var tmp = parent while (tmp != null && !clazz.isInstance(tmp)) tmp = tmp.parent return tmp as T? } //invocation node.parent(Node::class.java) Without reified inline fun <reified T> Node.parent(): T? { var tmp = parent while (p != null && p !is T) tmp = tmp.parent return p as T? } //invocation node.parent<Node>() Reified
  • 38. Function literal with receiver == recipe for DSL @nklmish class Delivery { fun person(function: Person.() -> Unit) : Person { ... } fun address(function: Address.() -> Unit) : Address { ... } } fun delivery(function: Delivery.() -> Unit): Delivery { ... } Extension fun on Delivery
  • 39. Function literal with receiver == recipe for DSL @nklmish class Delivery { fun person(function: Person.() -> Unit) : Person { ... } fun address(function: Address.() -> Unit) : Address { ... } } fun delivery(function: Delivery.() -> Unit): Delivery { ... } Extension fun on Delivery => we can access
  • 40. Function literal with receiver == recipe for DSL @nklmish delivery({ }) Syntactic sugar (if lambda is last argument) delivery() { }== delivery { }== Calling function “delivery” passing lambda as argument
  • 41. Function literal with receiver == recipe for DSL @nklmish
  • 42. Function literal with receiver == recipe for DSL @nklmish class Delivery { fun person(function: Person.() -> Unit) : Person { ... } fun address(function: Address.() -> Unit) : Address { ... } } fun delivery(function: Delivery.() -> Unit): Delivery { ... } fun onTransit(function: () -> Unit) : TransitInfo { … } fun sendSMS(message: String) { ... } Extension fun on Delivery Extension fun on Address Extension fun on Person Higher Order Function
  • 43. Function literal with receiver == recipe for DSL @nklmish delivery { person { name = "Bob" surname = "Smith" } address { city = “paris" street = "abc street" postalCode = "12345" onTransit { sendSMS("...") } } } Final Result
  • 44. Real life DSL - Anko verticalLayout { val name = editText() button("Say Hello") { onClick { toast("Hello, ${name.text}!") } } } https://github.com/Kotlin/anko @nklmish
  • 45. Real life DSL - GradleKotlinDSL https://github.com/gradle/kotlin-dsl @nklmish
  • 47. Overloading - Java Which argument is which ? @nklmish
  • 48. Overloading - Kotlin fun print(firstName : String, middleName: String = "", lastName : String = "") = { println("$firstName $middleName $lastName”) } fun main(args: Array<String>) { print(firstName = "john") print(firstName = "john", lastName = "smith") print(firstName = "john", middleName = "mac", lastName = "smith") } Default value Default value @nklmish
  • 49. Overloading - Kotlin fun print(firstName : String, middleName: String = "", lastName : String = "") = println("$firstName $middleName $lastName") fun main(args: Array<String>) { print(firstName = "john") print(firstName = "john", lastName = "smith") print(firstName = "john", middleName = "mac", lastName = "smith") } Named arguments can further improve readability
  • 51. Class - Java public class Schedule { private final LocalDateTime start; private final LocalDateTime end; private String notes; public Schedule(LocalDateTime start, LocalDateTime end) { this.start = start; this.end = end; } public LocalDateTime getStart() { return start; } public LocalDateTime getEnd() { return end; } public String getNotes() { return notes; } public void setNotes(String notes) { this.notes = notes; } } @nklmish
  • 52. Class - Kotlin class Schedule(val start: LocalDateTime, val end: LocalDateTime, var note : String) @nklmish
  • 53. Class - Kotlin class Schedule(val start: LocalDateTime, val end: LocalDateTime, var note : String) Default: public and final @nklmish
  • 54. Class - Kotlin class Schedule(val start: LocalDateTime, val end: LocalDateTime, var note : String) Properties @nklmish
  • 55. Class - Kotlin class Schedule(val start: LocalDateTime, val end: LocalDateTime, var note : String) Immutable Immutable @nklmish
  • 56. Class - Kotlin class Schedule(val start: LocalDateTime, val end: LocalDateTime, var note : String) Mutable @nklmish
  • 57. Data class == data holders data class Schedule(val start : LocalDateTime, val end : LocalDateTime) @nklmish
  • 58. Data class data class Schedule(val start : LocalDateTime, val end : LocalDateTime) Autogenerate: meaningful toString(), copy(), equals(), hashcode() @nklmish
  • 59. Data class - copy() val schedule = Schedule(LocalDateTime.now(), LocalDateTime.now().plusSeconds(1)) val copy = schedule.copy() val copyWithModifiedEndDate = schedule.copy(end = schedule.end.plusSeconds(1)) // we can change specific fields during copy, comes handy during unit testing @nklmish
  • 60. Data class - validation data class Schedule(val start : LocalDateTime, val end : LocalDateTime) { init { if (end.isBefore(start)) throw IllegalArgumentException("end $end should be after start $start") } } @nklmish String interpolation Note: String interpolation comes handy when dealing with JSON strings. e.g. private val expectedServerContent = """ {"name":"$canonicalName","json":"{"id":"$expectedGameProviderId"}","data":{"@foo":".bar","number":"123"},"policy":"","password":""} """.trimIndent()
  • 61. Sealed class ~ extension of enum classes sealed class Bonus { data class Yearly(val amount : BigDecimal) : Bonus() data class Monthly(val amount : BigDecimal, val factor : BigDecimal) : Bonus() } @nklmish Each enum constant exists only as 
 a single instance Enum Subclass of a sealed class can have multiple instances which can contain state Sealed class
  • 62. Sealed class ~ extension of enum classes sealed class Bonus { data class Yearly(val amount : BigDecimal) : Bonus() data class Monthly(val amount : BigDecimal, val factor : BigDecimal) : Bonus() } fun evaluate(bonus: Bonus) = when(bonus) { is Yearly -> bonus.amount is Monthly -> bonus.amount.multiply(bonus.factor) } Abstract class @nklmish
  • 64. Delegation class NetworkChaosSimulator{ private ChaosSwitch chaosSwitch = new DefaultSwitch(); public void enableActivationChaos() { chaosSwitch.enableActivationChaos(); } public void disableActivationChaos() { chaosSwitch.disableActivationChaos(); } public void enableDeactivationChaos() { chaosSwitch.enableDeactivationChaos(); } public void disableDeactivationChaos() { chaosSwitch.disableDeactivationChaos(); } public boolean isActivationChaosEnabled() { return chaosSwitch.isActivationChaosEnabled(); } public boolean isDeactivationChaosEnabled() { return chaosSwitch.isDeactivationChaosEnabled(); } } @nklmish class NetworkChaosSimulator(switch: ChaosSwitch = DefaultSwitch()) : ChaosSwitch by switch Java Kotlin
  • 65. Delegated properties • Wrap objects with custom behaviour. @nklmish
  • 66. Lazy • Create a new instance only when an object get accessed for the very first time. @nklmish
  • 67. Lazy class GameRound(val player : String) { val bets by lazy { fetchBets(this) } private fun fetchBets(gameRound: GameRound): Int { ... } } @nklmish
  • 68. Lazy - thread safety ? class GameRound(val player : String) { val bets by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { fetchBets(this) } private fun fetchBets(gameRound: GameRound): Int { ... } } Only a single thread can initialise the Lazy instance. @nklmish
  • 69. Lazy - thread safety ? class GameRound(val player : String) { val bets by lazy(mode = LazyThreadSafetyMode.PUBLICATION) { fetchBets(this) } private fun fetchBets(gameRound: GameRound): Int { ... } } Concurrent access permissible but only first returned value will be used. @nklmish
  • 70. Lazy - thread safety ? class GameRound(val player : String) { val bets by lazy(mode = LazyThreadSafetyMode.NONE) { fetchBets(this) } private fun fetchBets(gameRound: GameRound): Int { ... } } multiple threads == undefined behaviour @nklmish There are more builtin delegated properties like notNull, observable, etc. We can also create our own.
  • 72. players.filter({p -> p.score > 70}) @nklmish
  • 73. players.filter({p -> p.score > 70}) players.filter() {p -> p.score > 70} players.filter {p -> p.score > 70} players.filter {it.score > 70} syntactic sugar Implicit name for a single parameter @nklmish
  • 74. • Allows to invoke methods of different object (w/o any qualifiers) inside there body. @nklmish@nklmish with receiver @nklmish
  • 75. @nklmish@nklmish@nklmish public String toCSVFormat(List<Integer> list) { StringBuilder sb = new StringBuilder("["); for (Integer integer : list) { sb.append(integer).append(“;"); } sb.deleteCharAt(sb.length() - 1); sb.append("]"); return sb.toString(); } Java Kotlin : with (returns result of last call) fun toCSVFormat(list: List<Int>) = with(StringBuilder()) { append("[") for (i in list) { append(i).append(";") } deleteCharAt(length - 1) append("]") toString() } with receiver - with
  • 76. @nklmish@nklmish@nklmish public String toCSVFormat(List<Integer> list) { StringBuilder sb = new StringBuilder("["); for (Integer integer : list) { sb.append(integer).append(“;"); } sb.deleteCharAt(sb.length() - 1); sb.append("]"); return sb.toString(); } Java Kotlin : apply (returns the receiver) fun toCSVFormat(list: List<Int>) = StringBuilder().apply { append("[") for (i in list) { append(i).append(";") } deleteCharAt(length - 1) append("]") }.toString() with receiver - apply
  • 78. Null safety - baked into type system @nklmish var message : String = "hello" message = null // compile time error var message : String? = "hello" message = null // ok println(message?.length) //safe operator, if not null then invoke length Java message?.let { process(it) } Kotlin if (message != null) { process(message); }
  • 79. Null safety - using Java API from Kotlin? • Annotate Java code with nullability annotations. • Kotlin can understand annotations from: • Jetbrains (org.jetbrains.annotations) • JSR-305 (javax.annotation) • Android (android.support.annotation) @nklmish
  • 81. For loop - Java for (int i = 0; i < 10; i++) { System.out.println(i); } @nklmish
  • 82. For loop - Kotlin
  • 83. Progressions - to rescue for (i in 0..9) println(i) @nklmish
  • 84. Progressions - to rescue for (i in 0..9) println(i) Lots of useful methods : downTo(), stepTo(), until… @nklmish
  • 85. Collection • No Kotlin specific collections. • Kotlin Collection == Java collection classes + enrichment. @nklmish
  • 87. Typealias • Synonyms for pre-existing types
  • 88. Typealias - without fun main(args: Array<String>) { val map : Map<String,String> = mapOf("Bob" to "North Avenue") } @nklmish Less semantics
  • 89. Typealias - with typealias FirstName = String typealias Street = String fun main(args: Array<String>) { val map : Map<FirstName, Street> = mapOf("Bob" to "North Avenue") } @nklmish Better Semantics
  • 90. Casting - Java Object obj = "Any" if (obj instanceof String) { String str = (String) obj; str.toUpperCase(); } @nklmish
  • 91. Casting - Kotlin (smartcast) val obj:Any = "Any" if (obj is String) { obj.toUpperCase() // compiler smartness, auto cast to String // Works only, if obj is immutable or 
 // haven’t changed after check } @nklmish
  • 92. Deprecation @Deprecated(level = DeprecationLevel.WARNING, message = "we are going to replace with StringUtils", replaceWith = @ReplaceWith( expression = "StringUtils.isEmpty(input)", imports = {"org.apache.commons.lang3.StringUtils"}) ) public static boolean isEmpty(String input) { ... } @nklmish
  • 93. Deprecation @Deprecated(level = DeprecationLevel.WARNING, message = "we are going to replace with StringUtils", replaceWith = @ReplaceWith( expression = "StringUtils.isEmpty(input)", imports = {"org.apache.commons.lang3.StringUtils"}) ) public static boolean isEmpty(String input) { ... } level: Warning, Error, Hidden @nklmish
  • 94. Deprecation @Deprecated(level = DeprecationLevel.WARNING, message = "we are going to replace with StringUtils", replaceWith = @ReplaceWith( expression = "StringUtils.isEmpty(input)", imports = {"org.apache.commons.lang3.StringUtils"}) ) public static boolean isEmpty(String input) { ... } Method to replace with @nklmish
  • 95. Deprecation @Deprecated(level = DeprecationLevel.WARNING, message = "we are going to replace with StringUtils", replaceWith = @ReplaceWith( expression = "StringUtils.isEmpty(input)", imports = {"org.apache.commons.lang3.StringUtils"}) ) public static boolean isEmpty(String input) { ... } Which class to import @nklmish
  • 96. Deprecation - final result @nklmish
  • 97. when == powerful switch fun playerPrivileges(rank : Int) = when(rank) { in 1..3 -> "VIP" in 4..50 -> "Elevated" in 51..1000 -> "Classic" else -> "Regular" } @nklmish
  • 98. when == powerful switch fun playerPrivileges(rank : Int) = when(rank) { in 1..3 -> "VIP" in 4..50 -> "Elevated" in 51..1000 -> "Classic" else -> "Regular" } Can be any type, no limitations @nklmish
  • 99. when == powerful switch fun playerPrivileges(rank : Int) = when(rank) { in 1..3 -> "VIP" in 4..50 -> "Elevated" in 51..1000 -> "Classic" else -> "Regular" } No need to type break @nklmish
  • 100. Operator overloading - Java?public class Wallet { public Wallet(Integer amount) { this.amount = amount; } private final Integer amount; public Wallet plus(Wallet w) { return new Wallet(this.amount + w.amount); } public Wallet minus(Wallet w) { return new Wallet(this.amount - w.amount); } public Wallet multiply(Wallet w) { return new Wallet(this.amount * w.amount); } } Wallet walletA = new Wallet(100); Wallet walletB = new Wallet(200); walletA.plus(walletB); walletA.subtract(walletB); walletA.multiply(walletB); @nklmish
  • 101. Operator overloading - Kotlin data class Wallet(val amount : Int) { operator fun plus(w : Wallet) = Wallet(amount.plus(w.amount)) operator fun minus(w : Wallet) = Wallet(amount.minus(w.amount)) operator fun times(w : Wallet) = Wallet(amount.minus(w.amount)) } val walletA = Wallet(100) val walletB = Wallet(200) walletA + walletB walletA - walletB walletA * walletB @nklmish
  • 102. Operator overloading - Kotlin Naming Convention Syntax plus walletA + walletB unaryPlus +walletA minus walletA - walletB unaryMinus -walletA inc ++walletA dec — walletA times walletA * walletB div walletA / walletB mod walletA % walletB not !walletA @nklmish
  • 103. Co-routines == asyn programming made simple @nklmish val jobs = List(1_000_000) { async(CommonPool) { delay(10L) 1.0 } } runBlocking { println(jobs.sumByDouble { it.await() }) }
  • 104. Co-routines == asyn programming made simple @nklmish val jobs = List(1_000_000) { async(CommonPool) { delay(10L) 1.0 } } runBlocking { println(jobs.sumByDouble { it.await() }) } Lightweight
  • 108. Kotlin + Spring - build.gradle @nklmish dependencies { classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion") }
  • 109. Kotlin + Spring - build.gradle @nklmish dependencies { classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion") } Before plugin After Plugin @SpringBootApplication open class PhoneBookApplication { @Bean open fun passwordEncoder(): PasswordEncoder { return BCryptPasswordEncoder() } } @SpringBootApplication class PhoneBookApplication { @Bean fun passwordEncoder(): PasswordEncoder { return BCryptPasswordEncoder() } }
  • 110. Kotlin + Spring - build.gradle @nklmish dependencies { classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion") } @Document data class Contact(@Id val id: String = UUID.randomUUID().toString(), val firstName: String, var lastName: String, val phones: List<String> = emptyList() )
  • 111. Kotlin + Spring - controller @nklmish
  • 112. Kotlin + Spring - controller @nklmish Constructor injection(no @Autowired required)
  • 113. Kotlin + Spring - controller @nklmish Type Inference
  • 114. Kotlin + Spring - 
 null safety? @nklmish @GetMapping("/schedule") fun getSchedule(@RequestParam id: Long): Mono<ScheduleDto> = scheduleService.findOne(id).map { it.get().dto() } @GetMapping("/schedule") fun getSchedule(@RequestParam id: Long?): Mono<ScheduleDto> = scheduleService.findOne(id).map { it.get().dto() }
  • 115. Kotlin + Spring - null safety @nklmish
  • 116. Kotlin + Spring @nklmish @GetMapping(path = arrayOf("/schedules"), produces = arrayOf(TEXT_EVENT_STREAM_VALUE)) fun getSchedules(): Flux<ScheduleDto> = scheduleService.findAll().map { it.dto() } route( path(“/schedules”).and(accept(TEXT_EVENT_STREAM_VALUE)), ) Same thing expressed in Kotlin
  • 117. Who uses Kotlin… • Amazon • Uber • Netflix • Foursquare • Expedia • HSBC • Goldman Sachs • Trello • Casumo • … @nklmish
  • 118. Useful links • http://slack.kotlinlang.org/ • https://kotlin.link/ @nklmish