Meine neue Lieblingsprogrammiersprache

Kotlin

Quarantäne Ed.

Kotlin

Meine neue Lieblingsprogrammiersprache

Quarantäne Ed.

Tobse Fritz

  •       Reich
  •       Gut aussehend
     
  •       Kotlin Fanboy
  •        Java Entwickler
  •       Clean Coder  
  •       Hobby Photographer
  •       Gaming Nerd  
  •       ITscope GmbH

github.com/TobseF
stackoverflow.com/story/tobse

unsplash.com/@tobsef

Was

macht

meine Lieblingssprache aus?

Wichtig

  • Intuitive Sprache
  • Sehr gute IDE Unterstützung
  • Entwicklung macht Spaß 
  • Sinvolle Standardlib
  • Libs, Libs und PackageManager
  • Gute Community

Bedeutend

A programming language
that doesn’t change the way
you think about programming
is not worth knowing.

 

Alan Perlis, 1922-1990

Nice to have

  • Einfacher Wechsel
  • Produktiver
  • Weniger Fehler
  • Open Source
  • Regelmäßig Updates
  • Mein PO ist auch begeistert

Kotlin Features

  • Prägnant
  • Sicher
  • Interoperabel
  • Optimales Tooling

Kotlin Features

Prägnant

public class Person {

    private final String firstName;
    private final String lastName;
    private final LocalDate birthDay;

    public Person(String firstName, String lastName, 
                  LocalDate birthDay) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.birthDay = birthDay;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public LocalDate getBirthDay() {
        return birthDay;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return Objects.equals(firstName, person.firstName) &&
                Objects.equals(lastName, person.lastName) &&
                Objects.equals(birthDay, person.birthDay);
    }

    @Override
    public int hashCode() {
        return Objects.hash(firstName, lastName, birthDay);
    }

    @Override
    public String toString() {
        return "Person{" +
                "firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", birthDay=" + birthDay +
                '}';
    }
}
data class PersonK(
    val firstName: String,
    val lastName: String,
    val birthDay: LocalDate
)

Java

Kotlin

Kotlin Features

Sicher

var output: String
output = null

Kotlin

val name: String? = null
println(name.length)
fun calculateTotal(obj: Any) {
    if (obj is Invoice){
        obj.calculateTotal()
    }
}
fun isCloneBaby(father: Person, son: Person): Boolean {
    return father == son
}
// Compile Error
// Compile Error
// Autocast
// equals()

Kotlin Features

Interoperabel

  • iOS (arm32, arm64, simulator x86_64)
  • MacOS (x86_64)
  • Android (arm32, arm64)
  • Windows (mingw x86_64, x86)
  • Linux (x86_64, arm32, MIPS, MIPS little endian, Raspberry Pi)
  • WebAssembly (wasm32)

Kotlin Features

Interoperabel

fun callJava(){
  val backend = LegacyBackend()
  backend.sendMail("Be prepared... we deploy")
}

Kotlin

private void callKotlin(){
  var backend = new NewBackend();
  backend.sendSlack("We introduced NetID oAuth!");
}

Java

Kotlin Features

Optimales Tooling

Wer hat's erfunden?

Jul  2011  - Öffentliche Bekanntmachung

Feb 2016 - Release Version 1.0

Nov 2017 - Release Version 1.2

Mai 2017 - Offizielle Sprache für Android

Mai 2020 - Release Version 1.3.72
                     Kotlin 1.4-M1

Kotlin Native v0.4 & Multiplatform

Okt 2018 - Gründung Kotlin Foundation

Kotlin Features

  • Prägnant
  • Sicher
  • Interoperabel
  • Optimales Tooling

 

  • Frei & OpenSource

Kotlin Highlights  

  • Unveränderbare Typen
  • String Builders
  • Typisierte Lamdas
  • Ein Leben ohne NPEs
  • Data - Klassen
  • Delegtions
  • Extensions
  • Coroutines
  • •••

Bin ich ?

val theSolution = 42
theSolution = 24
// compile Error
var daysBeforeChristmas = 25
daysBeforeChristmas = 24

Und wenn Ja, wie lange?

You will never change me!

val daltons = listOf("Joe", "William", "Jack", "Averell ")
daltons += "Lucky Luke"
// compile Error
val characters = mutableListOf("Joe", "William", "Jack", "Averell ")
characters += "Lucky Luke"

Ein String sie zu knechten

val ringNumber = 2

val logMessage = "💍 This ring No $ringNumber was destroyed at ${System.currentTimeMillis()}"
val htmlSnippet = """
    <h1>🗺 Die Welt</h1>
    <ul>
      <li>Gondor</li>
      <li>Mordor</li>
      <li>Eriador</li>
    </ul>
</li>
""".trimIndent()

Type Safe Builders

fun theWorld() = html {
    body {
        h1 { + "🗺 Die Welt" }
        p  { + "Gondor" }
        p  { + "Mordor" }
        p  { + "Eriador" }
        a (href = "https://en.wikipedia.org/wiki/Minor_places_in_Middle-earth") {
            +"Middle Earth"
        }
    }
}

Bob der Baumeister

<html>
    <body>
        <h1>🗺 Die Welt</h1>
        <p>Gondor</p>
        <p>Mordor</p>
        <p>Eriador</p>
        <a href="https://en.wikipedia.org/wiki/Minor_places_in_Middle-earth">Middle Earth</a>
    </body>
</html>

Lamdas

Richtige konkrete Typen

fun message(messageKey: String, locale: Locale) = "Lorem ipsum"

fun getCurrentUserLocale() = Locale.GERMANY

fun localize(messageKey: String, translateable: (String, Locale) -> String): String {
    return translateable.invoke(messageKey, getCurrentUserLocale())
}

Klasse Klasse

class Company(name: String)
class Company(val name: String)
class Company(var name: String)
  • Konstruktor Param name

     Du bekommst

  • Alles vom ersten Paket
  • + getName()
  • Alles vom zweiten Paket
  • + setName()
data class Company(var name: String)
  • Alles vom dritten Paket
  • + hashCode()
  • + equals()
  • + toString()

ANGEBOT

„Hasta la vista NPE!“

class Company(val name: String)

fun loadCompany(): Company {
    return Company("Reynholm Industries")
}

val company = loadCompany()
println(company.name)

fun loadCompanyByName(name: String): Company? {
    return Company(name)
}

val loadedCompany = loadCompanyByName("Die Anstalt")
if (loadedCompany != null) {
    println(loadedCompany.name)
}

Prima Parameter

fun sendMail(address: String, subject: String, message : String){
 // ...
}
fun sendMail(
    address: String, subject: String, message: String,
    cc: String, bcc: String = "", attachment: Attachment?,
    timeout: Duration
) {...}
fun sendMail(
    address: String = "", subject: String = "", message: String = "",
    cc: String = "", bcc: String = "", attachment: Attachment? = null,
    timeout: Duration = Duration.ofSeconds(12)
) {...}
sendMail(address = "diskette@mail.org", message = "Your time is over")

Extensions

Nie wieder Util Klassen

val email = "Tobse4Git@gmail.com"
email.toLowerCase()
val username = "emil"
println(username.toFirstUpperCase())
fun String.toFirstUpperCase(): String {
    return if (this.isEmpty()) {
        ""
    } else {
        this[0].toTitleCase() + this.substring(1)
    }
}

Delegation

Komposition statt Vererbung

Delegation

Delegation

Delegation

Delegation

IRectangle by Rectangle(), IMoveable by Moveable()
class PacMan :
Rectangle()
IRectangle by Rectangle()
class GameField :
class GameField :

Delegation

Toll ein anderer macht's

val lazyValue: String by lazy {
    println("computed!")
    "Hello Kotliners"
}

println(lazyValue)
println(lazyValue)
computed!
Hello Kotliners
Hello Kotliners

Delegation

var name by CountAccess()

class CountAccess {

    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "Do you need help?"
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("Hallo my name is $value... and I will help you'")
    }
}

name = "Hannibal"
name = "Murdock"
name = "Face"
println(name)
Hallo my name is Hannibal... and I will help you'
Hallo my name is Murdock... and I will help you'
Hallo my name is Face... and I will help you'
Do you need help?
  • Callback Hell
  • Was kostet ein Thread?

Coroutines

Coroutines

synchron & blockierend

main Thread

IO

Verarbeitung

App tut nix. CPU schläft.

Coroutines

Neue Threads
sind teuer!

komplex!

asynchron & blockierend

main Thread

wait & join

Coroutines

Coroutinen sind leichtgewichtige Threads.
Sie können angehalten werden,
ohne den Thread zu blockieren.

Suspending

Launch startet eine Coroutine und

gibt einen Job zurück.

Async ist wie Launch, nur mit Rückgabewert.

Await wartet auf den Rückgabewert.

Async / Await

Launch

Coroutines

suspend fun checkPosition(): Position {
    delay(1000)
    println("🔍 Checked Position")
    return Position()
}

suspend fun getWeather(): Weather {
    delay(1000)
    println("☀ Checked Weather")
    return Weather()
}

suspend fun playForecast() {
    delay(1000)
    println("🔊 Play Forecast")
}
val start = System.currentTimeMillis()

val position = launch { checkPosition() }
println("Having so much time 💤")

val weather = launch { getWeather() }
println("We can do everything 💤")

val forecast = launch { playForecast() }
println("Lets count Kotliners 💤")

forecast.join()
position.join()
weather.join()
println(System.currentTimeMillis() - start)
Having so much time 💤
We can do everything 💤
Lets count Kotliners 💤
🔍 Checked Position
☀ Checked Weather
🔊 Play Forecast
1013

Coroutines

val fibonacci = sequence {

    yield(1) // first Fibonacci number

    var current = 1
    var next = 1

    while (true) {

        yield(next) // next Fibonacci number

        val tmp = current + next
        current = next
        next = tmp
    }

}

println(fibonacci.take(42).joinToString())
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296

Coroutines

fun loopWithThreads() {
    val c = AtomicLong()
    println("🦙🦙🦙🦙🦙🦙🦙🦙🦙🦙")

    measureTime {
        for (i in 1..100_000) {
            thread(start = true) {
                c.addAndGet(1).printProgress()
            }
        }
    }
}
fun loopWithCoroutine() {
    val c = AtomicLong()
    println("🦙🦙🦙🦙🦙🦙🦙🦙🦙🦙")

    measureTime {
        for (i in 1..100_000) {
            GlobalScope.launch {
                c.addAndGet(1).printProgress()
            }
        }
    }
}
🦙🦙🦙🦙🦙🦙🦙🦙🦙🦙
🥩🥩🥩
Lama Progress Bar

Coroutines

fun loopWithThreads() {
    val c = AtomicLong()
    println("🦙🦙🦙🦙🦙🦙🦙🦙🦙🦙")

    measureTime {
        for (i in 1..loopCount) {
            thread(start = true) {
                c.addAndGet(1).printProgress()
            }
        }
    }
}
fun loopWithCoroutine() {
    val c = AtomicLong()
    println("🦙🦙🦙🦙🦙🦙🦙🦙🦙🦙")

    measureTime {
        for (i in 1..loopCount) {
            GlobalScope.launch {
                c.addAndGet(1).printProgress()
            }
        }
    }
}
🦙🦙🦙🦙🦙🦙🦙🦙🦙🦙
🥩🥩🥩🥩🥩🥩🥩🥩🥩🥩
time: 0m 5s 363ms
🦙🦙🦙🦙🦙🦙🦙🦙🦙🦙
🥩🥩🥩🥩🥩🥩🥩🥩🥩🥩
time: 0m 0s 145ms

Coroutines

  • Leserlich wie imperativer Code
  • Keine Callback Hell
  • Leichtgewichtiger als Threads
    • ​Geringerer Speicherverbrauch
    • Schneller Wechsel
  • Syntax ist unabhängig von Implementierung
  • Verfügbar in JVM, JS und Native Kotlin

Coroutines  

  • Channels
  • Actors
  • Sequence Builder
  • Coroutine Dispatcher
  • Coroutine Scope

Ausblick

  • Inline Classes
  • Operator Overloading
  • Unsigned Integers
  • Contracts
  • Gradle DSL
  • Multiplatform
  • Kotlin Native
  • Kotlin 1.4

Kotlin Multiplatform

Pac-Man

Kotlin JVM

Kotlin Native

Kotlin JS

Android

Desktop

IOS

JAR

APK

Native Exe

Native App

Web

App

Kotlin Multiplatform

Native Android

Kotlin Multiplatform

Native IOS

10110

01010

10101

10110

01010

10101

Kotlin Multiplatform

Kotlin Multiplatform

Kotlin JS

JS

Kotlin JVM

Kotlin Script

Kotlin Native

10110

01010

10101

Kotlin Everywhere

https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String handle() {
        return "Hello WebFlux";
    }
}

Spring WebFlux provides an annotation-based programming model, where @Controller and @RestController components use annotations to express request mappings, request input, handle exceptions, and more. Annotated controllers have flexible method signatures and do not have to extend base classes nor implement specific interfaces.

The following listing shows a basic example:

https://docs.spring.io/spring/docs/.../web-reactive.html

Kotlin

Java

Kotlin Everywhere

@RestController
class HelloController {

    @GetMapping("/hello")
    fun handle() = "Hello WebFlux"
}

Spring WebFlux provides an annotation-based programming model, where @Controller and @RestController components use annotations to express request mappings, request input, handle exceptions, and more. Annotated controllers have flexible method signatures and do not have to extend base classes nor implement specific interfaces.

The following listing shows a basic example:

https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html

https://docs.spring.io/spring/docs/.../web-reactive.html

Kotlin

Java

Kotlin

Java

Kotlin Everywhere

Kotlin Everywhere

plugins {
    kotlin("jvm") version "1.3.30"
    java
}

group = "de.tfr.presentation"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    implementation(kotlin("stdlib-js"))
    testCompile("junit", "junit", "4.12")
}

configure<JavaPluginConvention> {
    sourceCompatibility = JavaVersion.VERSION_1_8
}
build.gradle.kts

Kotlin Everywhere

Java

Kotlin Everywhere

Trello

Evernote

Trivago

Runtastic

Tinder

Uber

My Taxi

Klarna

Mastercard

N26

182 %
Wachstum auf GitHub 2019

📢

📧

Kotlin Everywhere

Kotlin Everywhere

Kotliners 2020  - 5 Juni 2020

🎤

Effective Kotlin - Marcin Moskala

📚

THE END

Quellen

  • kotlinlang.org/docs/reference/
  • https://stackshare.io/kotlin
  • https://github.com/ygaller/kotlin-companies/wiki
  • https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html
  • https://stackabuse.com/spring-reactor-tutorial/
  • https://github.com/korlibs/korge
  • https://octoverse.github.com

 

Kotlin - Meine neue Lieblingsprogrammiersprache

By Tobse Fritz

Kotlin - Meine neue Lieblingsprogrammiersprache

❤♥ Meine Liebesgeschichte mit Kotlin ♥❤

  • 869