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
https://stackshare.io/kotlin
https://octoverse.github.com
https://github.com/ygaller/kotlin-companies/wiki
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
- Ressourcen
- flaticon.com
- kotlinlang.org/community/kotlin-nights.html
- clture.org/event/movie-nights-at-seventh-tryon
Kotlin - Meine neue Lieblingsprogrammiersprache
By Tobse Fritz
Kotlin - Meine neue Lieblingsprogrammiersprache
❤♥ Meine Liebesgeschichte mit Kotlin ♥❤
- 890