Kotlin Multiplatform

JVM

Android

Browser

Native

Kotlin 1.5

Tobse Fritz

  •       Reich
  •       Gut aussehend
     
  •       ITscope GmbH
  •       Kotlin Fanboy
  •        Java Entwickler
  •       Clean Coder  
  •       Hobby Fotograf
  •       Gaming Nerd  
  •       3D Printer
  •       Daddy

Tobse Fritz

GitHub

DevLand

BackEndHills

DesktopCountry

VeganGrounds

MobileRivers

CloudMountains

ConfigIsland

FrontendArea

NativeGrounds

DevLand

BackEndHills

DesktopCountry

VeganGrounds

MobileRivers

CloudMountains

ConfigIsland

FrontendArea

NativeGrounds

Und wo wohnst DU?

https://www.menti.com
Code: 1842 9218

Kotlin Features

  • Prägnant
  • Sicher
  • Interoperabel
  • Optimales Tooling

Kotlin Features

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

Prägnanz

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

Kotlin Features

  • Prägnant
  • Sicher
  • Interoperabel
  • Optimales Tooling
  • Frei & OpenSource

Kotlin Features

Prägnant

Sicher

Interoperabel

Optimales Tooling

Frei & OpenSource

Inline Classes

Extensions

Delegtions

String Builders

Contracts

Operator Overloading

Gradle DSL

Data Classes

Coroutines

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

Kotlin Native v0.4 & Multiplatform

Okt 2018 - Gründung Kotlin Foundation

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

Aug 2020 - Release Kotlin 1.4

Kotlin Native v0.4 & Multiplatform

Okt 2018 - Gründung Kotlin Foundation

Aug 2020 - Kotlin Multiplatform Mobile - Alpha

Nov 2020 - Jetpack Compose for Desktop - M1

Mai 2021 - Jetpack Compose for Web

Mai 2021 - Release Kotlin 1.5

Wer hat's erfunden?

DevLand

BackEndHills

DesktopCountry

VeganGrounds

MobileRivers

CloudMountains

ConfigIsland

FrontendArea

NativeGrounds

Kotlin JVM

Kotlin
Compiler

Java
Compiler

Kotlin

Runtime

*.kt
*.class
*.java
*.jar

Kotlin JVM

Kotlin JVM

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 JVM

@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

DevLand

BackEndHills

DesktopCountry

VeganGrounds

MobileRivers

CloudMountains

ConfigIsland

FrontendArea

NativeGrounds

Welcome
to the Native World

Kotlin Native / Native

Kotlin Native

Kotlin Multiplatform

!=

Kotlin Native

Technologie um Kotlin Code zu nativen Binaries zu kompilieren, die ohne VM laufen.

  • Bestmögliche Integration in existierende Systeme
  • Einfache Anwendung
  • Nützliches Tooling

Kotlin Native

  • 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)

JVM

Android

Browser

Native

Kotlin Native

Kotlin
Compiler

LLVM
Compiler

*.kt
LLVM IR
*.exe

The LLVM Compiler Infrastructure.
IR =
 Intermediate Representation 

Kotlin Native

Kotlin
Compiler

Kotlin
Compiler

*.kt
LLVM IR
*.exe

The LLVM Compiler Infrastructure.
IR =
 Intermediate Representation 

Frontend

Backend

Kotlin Native

Kotlin Native

DevLand

BackEndHills

DesktopCountry

VeganGrounds

MobileRivers

CloudMountains

ConfigIsland

FrontendArea

NativeGrounds

Kotlin JS

Kotlin
Transpiler

*.kt
*.js
*.map

Kotlin JS

Kotlin
Transpiler

*.kt
*.ts
*.js
*.map

Kotlin 1.5

🆕 dead code elimination (DCE) tool.

DevLand

BackEndHills

DesktopCountry

VeganGrounds

MobileRivers

CloudMountains

ConfigIsland

FrontendArea

NativeGrounds

Kotlin Android

Kotlin
Compiler

Java
Compiler

*.kt
*.class
*.java

JVM
Java Virtual Machine

Kotlin Android

Kotlin
Compiler

Java
Compiler

*.kt
*.class
*.java

DEX
Compiler

DVM
Dalvik Virtual Machine

DevLand

BackEndHills

DesktopCountry

VeganGrounds

MobileRivers

CloudMountains

ConfigIsland

FrontendArea

NativeGrounds

Kotlin Multiplatform

Technologie um Kotlin Code auf unterschiedlichen Plattformen
wiederzuverwenden.

  • Interoperabilität
  • Maximale Code Wiederverwendung
    • Über ein Kotlin Common Modul

Kotlin Multiplatform

  • Kann sich ändern
  • Offizielle Doku ist Referenz

Kotlin Multiplatform

Kotlin 1.3

JVM

image/svg+xml

JS

Linux

macOS

Common

Kotlin Multiplatform

Kotlin 1.4

JVM

image/svg+xml

JS

Linux

macOS

Common

Native

JVM + JS

Kotlin Multiplatform

JVM

JS

Linux

macOS

Common

Native

JVM + JS

Kotlin Multiplatform

JVM

JS

Linux

macOS

Common

Native

JVM + JS

Kotlin Multiplatform

*.kt

Kotlin
Compiler

image/svg+xml

Kotlin
Compiler

image/svg+xml

Kotlin
Compiler

image/svg+xml
*.js
*.class
*.kt
*.kt

Kotlin 1.4

*.exe

Kotlin
Compiler

Backend

LLVM IR

Kotlin Multiplatform

Kotlin
Compiler

image/svg+xml
*.kt

Kotlin
Compiler

image/svg+xml

Kotlin
Compiler

image/svg+xml

Kotlin
Compiler

image/svg+xml
*.js
*.class
*.kt
*.kt
LLVM IR

Kotlin 1.5

*.exe

Backend

Frontend

JVM

image/svg+xml

JS

Linux

IOS

Common

Kotlin Multiplatform

Android

Dependency Management

JVM

image/svg+xml

JS

Linux

IOS

Common

Kotlin Multiplatform

Android

Dependency Management

JVM

image/svg+xml

Common-Date-Util-Lib

JVM

image/svg+xml

JS

Linux

IOS

Common

Kotlin Multiplatform

Android

Dependency Management

Mobile-DB-OR-Mapper-Lib

Android

JVM

image/svg+xml

JS

Linux

IOS

Common

Kotlin Multiplatform

Android

Dependency Management

Twitter-Rest-API

JS

Kotlin Multiplatform

internal expect fun writeLogMessage(message: String, logLevel: LogLevel)
internal actual fun writeLogMessage(message: String, logLevel: LogLevel) {
    println("[$logLevel]: $message")
}

Common

internal actual fun writeLogMessage(message: String, logLevel: LogLevel) {
    when (logLevel) {
        LogLevel.DEBUG -> console.log(message)
        LogLevel.WARN -> console.warn(message)
        LogLevel.ERROR -> console.error(message)
    }
}
expect
actual

DevLand

BackEndHills

DesktopCountry

VeganGrounds

MobileRivers

CloudMountains

ConfigIsland

FrontendArea

NativeGrounds

Kotlin Gradle DSL

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

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

repositories {
    mavenCentral()
}

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

configure<JavaPluginConvention> {
    languageVersion.set(JavaLanguageVersion.of(11))
}

Kotlin Gradle DSL

Example 1. Dependency declarations for a JVM-based project

Groovy

Kotlin

plugins {
    id 'java-library'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.hibernate:hibernate-core:3.6.7.Final'
    api 'com.google.guava:guava:23.0'
    testImplementation 'junit:junit:4.+'
}

Kotlin Gradle DSL

Example 1. Dependency declarations for a JVM-based project

Groovy

Kotlin

plugins {
    `java-library`
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.hibernate:hibernate-core:3.6.7.Final")
    api("com.google.guava:guava:23.0")
    testImplementation("junit:junit:4.+")
}

Kotlin Scratch Files

fun ourCoolBuildScript(){
    val timeStamp = LocalDateTime.now()
    downloadI18nMessages()
    formatMessageProperties()
    mergeChangeLogEntries(timeStamp)
    sendSlackMessage("We're gonna deploy that stuff 🤘")
}

One-Click Scripts

*.kts

Kotlin Scratch Files

  • Build scripts (Gradle/Kobalt)
  • Test scripts (Spek)
  • Command-line Utilities
  • Routing Skripte (ktor)
  • Type-safe configuration files (TeamCity)
  • In-process scripting and REPL for IDE
  • Consoles like IPython/Jupyter Notebook
  • Game scripting engines

Multiplatform

Mobile

Kotlin

Multiplatform

Mobile

Kotlin

Multiplatform

Mobile

Kotlin

  • DRY
  • Bestpractise und Architektur der
    Platform beibehalten
  • Nativ = Keine Crossplatform Technologie
  • Keine Änderung für Android
  • Für IOS ist es nur ein Library import
  • Nur die UI-Layer wird doppelt geschrieben

Jetpack Compose

Jetpack Compose

@Composable
fun App() {
  MaterialTheme {
    Button(){
      Text("Hallo World")
    }
  }
}
  • Funktional
    • Stateless
    • Keine Seiteneffekte
    • Idempotent
    • Kein return
  • Deklarativ
  • Reaktiv
  • UI in Code

f(   )

Data

UI

Jetpack Compose

@Composable
fun App() {
  MaterialTheme {
    halloButton("Hallo World")
  }
}

@Composable
private fun halloButton(text: String) {
  Button() {
    Text(text)
  }
}

f(   )

Data

UI

Jetpack Compose

@Composable
fun App() {
  MaterialTheme {
    halloButton("Hallo World")
  }
}

@Composable
private fun halloButton(text: String) {
  var textProperty by remember { mutableStateOf(text) }
  Button( onClick = { text += " - Live in Peace" }) {
    Text(textProperty)
  }
}

Jetpack Compose

For
Android

For
Desktop

For
Web

Nov 2020

TECHNICAL
PREVIEW

Mai 2021

TECHNICAL
PREVIEW

BETA

 FEB 2021 

 Mai 2019 

Jetpack Compose

@Composable
private fun halloButton(text: String) {

Kotlin Compiler

Compose Compiler Plugin

Kotlin Multiplatform

Pac-Man

Kotlin JVM

Kotlin Native

Kotlin JS

Desktop

IOS

JAR

APK

Native Exe

Native App

Web

App

Android

Kotlin Multiplatform

Demo Projekte

Kotlin JS

Game Wishlist

Kotlin Native

IntelliJ Launcher - Win 32 API

Kotlin Multiplatform

HitKlack Spiel - Korge

Wie schnell ist das denn?

Wie schnell ist das denn?

fun main(args: Array<String>) {

    val start =  getTimeMillis()

    var c = 0L
    var string = ""
    for(i in 0.. 100_000){
        c += (i / 2)
        c += 1
        string += c
    }

    println( getTimeMillis() - start)
}

BENCHMARK

Benchmark

[ millisekunden / run ]   weniger ist besser

IT DEPENDS

Source Code

Runtime

VM

Graal

VM

Graal

JVM
Java 15

JVM
Java 15

Math

String

Memory

Math

String

Memory

Chromium

Native Win x64

Kotlin 1.5

image/svg+xml

Kotlin 1.4

image/svg+xml

Compiler

fun benchMath(iterations: Int): Double {
  var c = 0.0
  for (i in 0..iterations) {
    c += (i / 2.0)
    c += (i % 3.0)
    c += sqrt(i * 3.0)
    c += 1
  }
  return c
}

Math Benchmark

100_000_000

fun benchString(iterations: Int) {
  var c = 0L
  var string = ""
  for (i in 0..iterations) {
    c += (i / 3)
    c += 1
    val next = c % 10
    string += next
  }
}

String Benchmark

100_000

fun benchObjectList(iterations: Int): Int {
  val list = mutableListOf<Machine>()
  for (i in 0..iterations) {
  	list.add(Machine("ABC-0$i", i, i / 3.0))
  }
  return list.size
}

class Machine(val name: String, val wheels: Int, val weight: Double)

Memory Benchmark

10_000_000

void benchMath(int iterations) {
  var c = 0.0;
  for (int i =0; i < iterations; i++) {
    c += (i / 2.0);
    c += (i % 3.0);
    c += Math.sqrt(i * 3.0);
    c += 1;
  }
}

Math Benchmark

100_000_000

void benchString(int iterations) {
  var c = 0;
  var string = "";
  for (int i = 0; i < iterations; i++) {
    c += (i / 3);
    c += 1;
    var next = c % 10;
    string += next;
  }
}

String Benchmark

100_000

Math Benchmark

100_000_000

public class BenchmarkMemory {

  void benchObjectList(int iterations) {
    var list = new ArrayList<PerpetuumMobile>();
    for (int i = 0; i < iterations; i++) {
    	list.add(new PerpetuumMobile("ABC-0" + i, i, (i / 3.0)));
    }
  }

  private static class Machine {
    String name;
    Integer wheels;
    Double weight;

    public Machine(String name, int wheels, double weight) {
      this.name = name;
      this.wheels = wheels;
      this.weight = weight;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;
      Machine that = (Machine) o;
      return wheels == that.wheels && Double.compare(that.weight, weight) 
      == 0 && Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {
    	return Objects.hash(name, wheels, weight);
    }

  }
}
Chrome Headless 90.4430.93
Open JDK 15.0.2
GraalVM Native-Image 21.0.0.2
Windows 10 x64 AMD Ryzen 7 1800X
64GB RAM

Messungen

Multiplatform Benchmark

Multiplatform Benchmark

Benchmark

Benchmark

Benchmark

Benchmark

Und der Speicher?
Und der Speicher?

Memory Benchmark 10_000_000

Und der Speicher?
Und der Speicher?
Wie groß ist es?
Wie groß ist es?
Wie groß ist es?

Kotlin Native Hallo World 

Kotlin Native

vs

Graal

VM

Graal

VM

Language Choice

High Performance

Advanced Tools

Ahead-of-Time Compilation

Startup Time

Memory Footprint

Graal

VM

Graal

VM

Kotlin Native Graal VM
Fokus Interoperabilität Polyglot + Performance
Sprache Kotlin 1.5 Java 11, R, JS, Python 
Status Beta 21.5
Platform Win, Linux, Mac, IOS, Android, Embedded Linux, Mac, (Win)
Lizenz Apache License 2.0 GPL - Community  Ed.

Kotlin Native

vs

🔩Stabilitätscheck

BETA

STABLE

ALPHA

EXPERIMENTAL

try it only in toy projects

use at your own risk,
     expect migration issues

you can use it, we'll do our best to      minimize migration issues for you

use it even in most             conservative scenarios

🔩Stabilitätscheck

Kotlin/JVM

STABLE

kotlin-stdlib (JVM)

STABLE

Kotlin/Native Runtime

BETA

KLib binaries

ALPHA

Kotlin Scripts (*.kts)

BETA

Multiplatform Projects

ALPHA

expect/actual feature

BETA

Compiler Plugin API

EXPERIMENTAL

KMM IDE Plugin

EXPERIMENTAL

🔩Stabilitätscheck

Kotlin/JVM

STABLE

kotlin-stdlib (JVM)

STABLE

Kotlin/Native Runtime

BETA

KLib binaries

ALPHA

Kotlin Scripts (*.kts)

BETA

Multiplatform Projects

ALPHA

expect/actual feature

BETA

Compiler Plugin API

EXPERIMENTAL

KMM IDE Plugin

EXPERIMENTAL

Kotlin Everywhere

Trello

Evernote

Trivago

Runtastic

Tinder

Uber

My Taxi

Klarna

Mastercard

N26

182 %
Wachstum auf GitHub 2019

Kotlin Everywhere

https://kotlinlang.org/lp/mobile/case-studies/

DevLand

BackEndHills

DesktopCountry

VeganGrounds

MobileRivers

CloudMountains

ConfigIsland

FrontendArea

NativeGrounds

Die große Commonwealth Kotliothek

DevLand

  • Kotlin in fast jedem Land
  • Die Leute übernehmen die Sprache mit Leichtigkeit
  • Die gemeinsame Sprache lässt die einzelnen Länder zusammenwachsen
  • Das geteilte Wissen der Common Bib erspart jedem Land viel Arbeit
  • Der neue Schlachtruf: "Sharing is caring"
  • Die Götter haben die Zeichen für ein neues Zeitalter mit neuen Werkzeugen und Möglichkeiten angekündigt
  • Mutige Helden beschreiten schon heute den Weg der Götter

THE END

Quellen

Kotlin JS Beispiel - Game Wishlist

github.com/TobseF/KotlinJsGameWishlist

 

Kotlin Native Beispiel - IntelliJ Launcher

github.com/TobseF/IntelliJ-Launcher-n

 

Multiplatform Beispiel - Hit Klack - Korge

github.com/TobseF/HitKlack

 

Multiplatform Benchmark

github.com/TobseF/kotlin-multiplatform-benchmark

Quellen

Kotlin 1.5 Multiplatform

By Tobse Fritz

Kotlin 1.5 Multiplatform

Platform übergreifende und native Entwicklung mit Koltin 1.5

  • 204