SlideShare a Scribd company logo
Dip into Coroutines
A story full of suspends
Software Engineer @ Gradle
Formerly @ dxFeed
Twitter @alllexist — GitHub @alllex
Alex Semin
Awesome Kotlin coroutines
fun main() = runBlocking {
val jobs: List<Deferred<Boolean?> = List(100_000) {
async { request(it) }
}
val evenCount = jobs.count { it.await() }
println("There $evenCount even numbers")
}
suspend fun request(id: Int): Boolean {
delay(1.seconds)
return id % 2 ?= 0
}
fun main() = runBlocking {
val jobs: List<Deferred<Boolean?> = List(100_000) {
async { request(it) }
}
val evenCount = jobs.count { it.await() }
println("There $evenCount even numbers")
}
suspend fun request(id: Int): Boolean {
delay(1.seconds)
return id % 2 ?= 0
}
fun main() = runBlocking {
val jobs: List<Deferred<Boolean?> = List(100_000) {
async { request(it) }
}
val evenCount = jobs.count { it.await() }
println("There $evenCount even numbers")
}
suspend fun request(id: Int): Boolean {
delay(1.seconds)
return id % 2 ?= 0
}
import kotlinx.coroutines.*
What’s where?
kotlinx.coroutines kotlin.coroutines
launch
async await
…
Job
runBlocking coroutineScope
Deferred
withTimeout
Continuation
CoroutineContext
createCoroutine* suspendCoroutine*
COROUTINE_SUSPENDED
ContinuationInterceptor
delay
…
…
Awesome Sequence Builders
Sequences
list.asSequence()
.filter { … }
.map { … }
.filter { … }
// 1, 2, 4, 8, //.
val seq = generateSequence(1) { it * 2 }
for (item in seq) {
println(item)
}
interface Sequence<out T> {
operator fun iterator(): Iterator<T>
}
interface Iterator<out T> {
operator fun next(): T
operator fun hasNext(): Boolean
}
val iter = seq.iterator()
while (iter.hasNext()) {
val item = iter.next()
println(item)
}
Sequence builders
val fib = sequence {
print("Start ")
yield(1)
// Label 1
var cur = 1
var next = 1
while (true) {
print("Next ")
yield(next)
// Label 2
val tmp = cur + next
cur = next
next = tmp
}
}
fib.take(4).forEach { print("$it ") }
// Start 1 Next 1 Next 2 Next 3
fun <T> sequence(
block: suspend SequenceScope<T>.() ?> Unit
): Sequence<T>
abstract class SequenceScope<in T> {
abstract suspend fun yield(value: T)
}
class SequenceBuilder<T> : SequenceScope<T>(), Iterator<T> {
var state: State = State.NotReady // enum NotReady, Ready, Done
var nextValue: T? = null
var nextStep: Continuation<Unit>? = null
override fun next(): T = when (state) {
…
}
override fun hasNext(): Boolean {
…
}
override suspend fun yield(value: T) {
…
}
}
class SequenceBuilder<T> : SequenceScope<T>(), Iterator<T> {
var state: State = State.NotReady // enum NotReady, Ready, Done
var nextValue: T? = null
var nextStep: Continuation<Unit>? = null
override fun next(): T = when (state) {
State.NotReady ?> if (hasNext()) next() else error("oops")
State.Ready ?> {
state = State.NotReady
nextValue as T
}
else ?> error("oops")
}
override fun hasNext(): Boolean {
…
}
override suspend fun yield(value: T) {
…
}
}
class SequenceBuilder<T> : SequenceScope<T>(), Iterator<T> {
var state: State = State.NotReady // enum NotReady, Ready, Done
var nextValue: T? = null
var nextStep: Continuation<Unit>? = null
override fun next(): T = when (state) {}
override fun hasNext(): Boolean {
while (true) {
when (state) {
State.NotReady ?> {
state = State.Done
nextStep?!.resume(Unit)
}
State.Done ?> return false
State.Ready ?> return true
}
}
}
override suspend fun yield(value: T) {
…
}
}
interface Continuation<in T> {
val context: CoroutineContext
fun resumeWith(result: Result<T>)
}
fun <T> Continuation<T>.resume(value: T) =
resumeWith(Result.success(value))
class SequenceBuilder<T> : SequenceScope<T>(), Iterator<T> {
var state: State = State.NotReady // enum NotReady, Ready, Done
var nextValue: T? = null
var nextStep: Continuation<Unit>? = null
override fun next(): T = when (state) {}
override fun hasNext(): Boolean {
while (true) {
when (state) {
State.NotReady ?> {
state = State.Done
nextStep?!.resume(Unit)
}
State.Done ?> return false
State.Ready ?> return true
}
}
}
override suspend fun yield(value: T) {
…
}
}
val fib = sequence {
print("Start ")
yield(1)
// Label 1
var cur = 1
var next = 1
while (true) {
print("Next ")
yield(next)
// Label 2
val tmp = cur + next
cur = next
next = tmp
}
}
class SequenceBuilder<T> : SequenceScope<T>(), Iterator<T> {
var state: State = State.NotReady // enum NotReady, Ready, Done
var nextValue: T? = null
var nextStep: Continuation<Unit>? = null
override fun hasNext(): Boolean {
…
}
override fun next(): T = when (state) {
…
}
override suspend fun yield(value: T) {
nextValue = value
state = State.Ready
}
}
val fib = sequence {
print("Start ")
yield(1)
// Label 1
var cur = 1
var next = 1
while (true) {
print("Next ")
yield(next)
// Label 2
val tmp = cur + next
cur = next
next = tmp
}
}
class SequenceBuilder<T> : SequenceScope<T>(), Iterator<T> {
var state: State = State.NotReady // enum NotReady, Ready, Done
var nextValue: T? = null
var nextStep: Continuation<Unit>? = null
override fun hasNext(): Boolean {
…
}
override fun next(): T = when (state) {
…
}
override suspend fun yield(value: T) {
nextValue = value
state = State.Ready
return suspendCoroutineUninterceptedOrReturn { c ->
nextStep = c
COROUTINE_SUSPENDED
}
}
}
val fib = sequence {
print("Start ")
yield(1)
// Label 1
var cur = 1
var next = 1
while (true) {
print("Next ")
yield(next)
// Label 2
val tmp = cur + next
cur = next
next = tmp
}
}
Continuation Passing Style
T | COROUTINE_SUSPENDED
suspend fun yield(value: T): Unit
source code
fun yield(value: T, cont: Continuation<Unit>): Any?
compiled code
Continuation Passing Style
override suspend fun yield(value: T) {
nextValue = value
state = State.Ready
return suspendCoroutineUninterceptedOrReturn { cont ->
nextStep = cont
COROUTINE_SUSPENDED
}
}
override suspend fun yield(value: T, cont: Continuation<Unit>): Any? {
nextValue = value
state = State.Ready
nextStep = cont
return COROUTINE_SUSPENDED
}
Awesome Deep Recursion
Deeply recursive functions
fun depth(t: Tree?): Int =
if (t ?= null) 0 else maxOf(depth(t.left), depth(t.right)) + 1
println(depth(deepTree)) // StackOverflowError
class Tree(val left: Tree? = null, val right: Tree? = null)
val deepTree = generateSequence(Tree()) { Tree(left = it) }.take(100_000).last()
val depth = DeepRecursiveFunction<Tree?, Int> { t ->
if (t ?= null) 0 else maxOf(
callRecursive(t.left),
callRecursive(t.right)
) + 1
}
println(depth(deepTree)) // Ok
Deeply recursive functions
sealed class DeepRecursiveScope<T, R> {
abstract suspend fun callRecursive(value: T): R
}
override suspend fun callRecursive(value: T): R {
return suspendCoroutineUninterceptedOrReturn { c ->
this.cont = c as Continuation<Any?>
this.value = value
COROUTINE_SUSPENDED
}
}
fun runCallLoop(): R {
while (true) {
val result = this.result
val cont = this.cont
?: return result.getOrThrow()
if (UNDEFINED_RESULT ?= result) {
val r = try {
function(this, value, cont)
} catch (e: Throwable) {
cont.resumeWithException(e)
continue
}
if (r ??= COROUTINE_SUSPENDED)
cont.resume(r as R)
} else {
this.result = UNDEFINED_RESULT
cont.resumeWith(result)
}
}
}
Deeply recursive functions
sealed class DeepRecursiveScope<T, R> {
abstract suspend fun callRecursive(value: T): R
}
override suspend fun callRecursive(value: T): R {
return suspendCoroutineUninterceptedOrReturn { c ->
this.cont = c as Continuation<Any?>
this.value = value
COROUTINE_SUSPENDED
}
}
fun runCallLoop(): R {
while (true) {
val result = this.result
val cont = this.cont
?: return result.getOrThrow()
if (UNDEFINED_RESULT ?= result) {
val r = try {
function(this, value, cont)
} catch (e: Throwable) {
cont.resumeWithException(e)
continue
}
if (r ??= COROUTINE_SUSPENDED)
cont.resume(r as R)
} else {
this.result = UNDEFINED_RESULT
cont.resumeWith(result)
}
}
}
Awesome Parser Combinators
Parsing expressions
sealed class Expr {
object TRUE : Expr()
object FALSE : Expr()
data class Var(val name: String) : Expr()
data class Not(val body: Expr) : Expr()
data class And(val left: Expr, val right: Expr) : Expr()
data class Or(val left: Expr, val right: Expr) : Expr()
data class Impl(val left: Expr, val right: Expr) : Expr()
}
val expr = "a & (b1 ?> c1) | a1 & !b | !(a1 ?> a2) ?> a"
object BooleanGrammar : Grammar<Expr>() {
init { register(regexToken("s+", ignored = true)) }
val tru by literalToken("true")
val fal by literalToken("false")
val id by regexToken("w+")
val lpar by literalToken("(")
val rpar by literalToken(")")
val not by literalToken("!")
val and by literalToken("&")
val or by literalToken("|")
val impl by literalToken("?>")
val negation by parser { -not * term() } map { Not(it) }
val braced by parser { -lpar * expr() * -rpar }
val term: Parser<Expr> by
(tru map TRUE) or (fal map FALSE) or (id map { Var(it.text) }) or negation or braced
val andChain by parser { leftAssociative(term, and) { a, _, b -> And(a, b) } }
val orChain by parser { leftAssociative(andChain, or) { a, _, b -> Or(a, b) } }
val implChain by parser { rightAssociative(orChain, impl) { a, _, b -> Impl(a, b) } }
val expr by implChain
override val root by expr
}
"a & (b1 ?> c1) | a1 & !b | !(a1 ?> a2) ?> a"
object BooleanGrammar : Grammar<Expr>() {
init { register(regexToken("s+", ignored = true)) }
val tru by literalToken("true")
val fal by literalToken("false")
val id by regexToken("w+")
val lpar by literalToken("(")
val rpar by literalToken(")")
val not by literalToken("!")
val and by literalToken("&")
val or by literalToken("|")
val impl by literalToken("?>")
val negation by parser { -not * term() } map { Not(it) }
val braced by parser { -lpar * expr() * -rpar }
val term: Parser<Expr> by
(tru map TRUE) or (fal map FALSE) or (id map { Var(it.text) }) or negation or braced
val andChain by parser { leftAssociative(term, and) { a, _, b -> And(a, b) } }
val orChain by parser { leftAssociative(andChain, or) { a, _, b -> Or(a, b) } }
val implChain by parser { rightAssociative(orChain, impl) { a, _, b -> Impl(a, b) } }
val expr by implChain
override val root by expr
}
suspend fun <T : Any, S : Any> ParsingScope.leftAssociative(
term: Parser<T>,
operator: Parser<S>,
transform: (T, S, T) ?> T
): T {
var l: T = term()
while (true) {
val (o, r) = maybe(parser { operator() to term() }) ?: break
l = transform(l, o, r)
}
return l
}
val input = "K | o | t | l | i | n | i | s | a | w | e | s | o | m | e"
parser { leftAssociative(id, "|") { l, _, r -> "$l$r" } }
https://github.com/alllex/parsus
Awesome Arrow Kt
https://arrow-kt.io/
Awesome! How to learn more?
More watching
More reading
https://kotlinlang.org/docs/coroutines-guide.html https://github.com/Kotlin/KEEP/blob/master/proposals/coroutines.md
More tinkering
Than you!
Twitter @alllexist — GitHub @alllex

More Related Content

Similar to Dip into Coroutines - KTUG Munich 202303

VTU Data Structures Lab Manual
VTU Data Structures Lab ManualVTU Data Structures Lab Manual
VTU Data Structures Lab Manual
Nithin Kumar,VVCE, Mysuru
 
week-18x
week-18xweek-18x
week-17x
week-17xweek-17x
Simpler java
Simpler javaSimpler java
Simpler java
Stefan von Stein
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
Christian Baranowski
 
Go: It's Not Just For Google
Go: It's Not Just For GoogleGo: It's Not Just For Google
Go: It's Not Just For Google
Eleanor McHugh
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4
Emil Vladev
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
Arturo Herrero
 
Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kirill Rozov
 
Atomically { Delete Your Actors }
Atomically { Delete Your Actors }Atomically { Delete Your Actors }
Atomically { Delete Your Actors }
John De Goes
 
I wrote the following change it to having a header, main and cpp fi.pdf
I wrote the following change it to having a header, main and cpp fi.pdfI wrote the following change it to having a header, main and cpp fi.pdf
I wrote the following change it to having a header, main and cpp fi.pdf
rishteygallery
 
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docxjava compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
priestmanmable
 
Kotlinify Your Project!
Kotlinify Your Project!Kotlinify Your Project!
Kotlinify Your Project!
OrNoyman
 
b. (10 pts) Implement the rotate left method for AVL trees.c. (10 .pdf
b. (10 pts) Implement the rotate left method for AVL trees.c. (10 .pdfb. (10 pts) Implement the rotate left method for AVL trees.c. (10 .pdf
b. (10 pts) Implement the rotate left method for AVL trees.c. (10 .pdf
akanshanawal
 
3 kotlin vs. java- what kotlin has that java does not
3  kotlin vs. java- what kotlin has that java does not3  kotlin vs. java- what kotlin has that java does not
3 kotlin vs. java- what kotlin has that java does not
Sergey Bandysik
 
Shapes and calculate (area and contour) / C++ oop concept
Shapes and calculate (area and contour) / C++ oop conceptShapes and calculate (area and contour) / C++ oop concept
Shapes and calculate (area and contour) / C++ oop concept
kinan keshkeh
 
Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017
Roman Elizarov
 
Implement the following sorting algorithms Bubble Sort Insertion S.pdf
Implement the following sorting algorithms  Bubble Sort  Insertion S.pdfImplement the following sorting algorithms  Bubble Sort  Insertion S.pdf
Implement the following sorting algorithms Bubble Sort Insertion S.pdf
kesav24
 
Kotlin coroutine - behind the scenes
Kotlin coroutine - behind the scenesKotlin coroutine - behind the scenes
Kotlin coroutine - behind the scenes
Anh Vu
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
Mario Fusco
 

Similar to Dip into Coroutines - KTUG Munich 202303 (20)

VTU Data Structures Lab Manual
VTU Data Structures Lab ManualVTU Data Structures Lab Manual
VTU Data Structures Lab Manual
 
week-18x
week-18xweek-18x
week-18x
 
week-17x
week-17xweek-17x
week-17x
 
Simpler java
Simpler javaSimpler java
Simpler java
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
Go: It's Not Just For Google
Go: It's Not Just For GoogleGo: It's Not Just For Google
Go: It's Not Just For Google
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3
 
Atomically { Delete Your Actors }
Atomically { Delete Your Actors }Atomically { Delete Your Actors }
Atomically { Delete Your Actors }
 
I wrote the following change it to having a header, main and cpp fi.pdf
I wrote the following change it to having a header, main and cpp fi.pdfI wrote the following change it to having a header, main and cpp fi.pdf
I wrote the following change it to having a header, main and cpp fi.pdf
 
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docxjava compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
 
Kotlinify Your Project!
Kotlinify Your Project!Kotlinify Your Project!
Kotlinify Your Project!
 
b. (10 pts) Implement the rotate left method for AVL trees.c. (10 .pdf
b. (10 pts) Implement the rotate left method for AVL trees.c. (10 .pdfb. (10 pts) Implement the rotate left method for AVL trees.c. (10 .pdf
b. (10 pts) Implement the rotate left method for AVL trees.c. (10 .pdf
 
3 kotlin vs. java- what kotlin has that java does not
3  kotlin vs. java- what kotlin has that java does not3  kotlin vs. java- what kotlin has that java does not
3 kotlin vs. java- what kotlin has that java does not
 
Shapes and calculate (area and contour) / C++ oop concept
Shapes and calculate (area and contour) / C++ oop conceptShapes and calculate (area and contour) / C++ oop concept
Shapes and calculate (area and contour) / C++ oop concept
 
Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017
 
Implement the following sorting algorithms Bubble Sort Insertion S.pdf
Implement the following sorting algorithms  Bubble Sort  Insertion S.pdfImplement the following sorting algorithms  Bubble Sort  Insertion S.pdf
Implement the following sorting algorithms Bubble Sort Insertion S.pdf
 
Kotlin coroutine - behind the scenes
Kotlin coroutine - behind the scenesKotlin coroutine - behind the scenes
Kotlin coroutine - behind the scenes
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
 

Recently uploaded

The Rising Future of CPaaS in the Middle East 2024
The Rising Future of CPaaS in the Middle East 2024The Rising Future of CPaaS in the Middle East 2024
The Rising Future of CPaaS in the Middle East 2024
Yara Milbes
 
Photoshop Tutorial for Beginners (2024 Edition)
Photoshop Tutorial for Beginners (2024 Edition)Photoshop Tutorial for Beginners (2024 Edition)
Photoshop Tutorial for Beginners (2024 Edition)
alowpalsadig
 
Manyata Tech Park Bangalore_ Infrastructure, Facilities and More
Manyata Tech Park Bangalore_ Infrastructure, Facilities and MoreManyata Tech Park Bangalore_ Infrastructure, Facilities and More
Manyata Tech Park Bangalore_ Infrastructure, Facilities and More
narinav14
 
一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理
dakas1
 
Kubernetes at Scale: Going Multi-Cluster with Istio
Kubernetes at Scale:  Going Multi-Cluster  with IstioKubernetes at Scale:  Going Multi-Cluster  with Istio
Kubernetes at Scale: Going Multi-Cluster with Istio
Severalnines
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
Grant Fritchey
 
Transforming Product Development using OnePlan To Boost Efficiency and Innova...
Transforming Product Development using OnePlan To Boost Efficiency and Innova...Transforming Product Development using OnePlan To Boost Efficiency and Innova...
Transforming Product Development using OnePlan To Boost Efficiency and Innova...
OnePlan Solutions
 
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
XfilesPro
 
The Comprehensive Guide to Validating Audio-Visual Performances.pdf
The Comprehensive Guide to Validating Audio-Visual Performances.pdfThe Comprehensive Guide to Validating Audio-Visual Performances.pdf
The Comprehensive Guide to Validating Audio-Visual Performances.pdf
kalichargn70th171
 
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
dakas1
 
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
kalichargn70th171
 
WWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders AustinWWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders Austin
Patrick Weigel
 
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data PlatformAlluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio, Inc.
 
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSISDECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
Tier1 app
 
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
widenerjobeyrl638
 
All you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVMAll you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVM
Alina Yurenko
 
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
gapen1
 
Migration From CH 1.0 to CH 2.0 and Mule 4.6 & Java 17 Upgrade.pptx
Migration From CH 1.0 to CH 2.0 and  Mule 4.6 & Java 17 Upgrade.pptxMigration From CH 1.0 to CH 2.0 and  Mule 4.6 & Java 17 Upgrade.pptx
Migration From CH 1.0 to CH 2.0 and Mule 4.6 & Java 17 Upgrade.pptx
ervikas4
 
Upturn India Technologies - Web development company in Nashik
Upturn India Technologies - Web development company in NashikUpturn India Technologies - Web development company in Nashik
Upturn India Technologies - Web development company in Nashik
Upturn India Technologies
 
一比一原版(sdsu毕业证书)圣地亚哥州立大学毕业证如何办理
一比一原版(sdsu毕业证书)圣地亚哥州立大学毕业证如何办理一比一原版(sdsu毕业证书)圣地亚哥州立大学毕业证如何办理
一比一原版(sdsu毕业证书)圣地亚哥州立大学毕业证如何办理
kgyxske
 

Recently uploaded (20)

The Rising Future of CPaaS in the Middle East 2024
The Rising Future of CPaaS in the Middle East 2024The Rising Future of CPaaS in the Middle East 2024
The Rising Future of CPaaS in the Middle East 2024
 
Photoshop Tutorial for Beginners (2024 Edition)
Photoshop Tutorial for Beginners (2024 Edition)Photoshop Tutorial for Beginners (2024 Edition)
Photoshop Tutorial for Beginners (2024 Edition)
 
Manyata Tech Park Bangalore_ Infrastructure, Facilities and More
Manyata Tech Park Bangalore_ Infrastructure, Facilities and MoreManyata Tech Park Bangalore_ Infrastructure, Facilities and More
Manyata Tech Park Bangalore_ Infrastructure, Facilities and More
 
一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理
 
Kubernetes at Scale: Going Multi-Cluster with Istio
Kubernetes at Scale:  Going Multi-Cluster  with IstioKubernetes at Scale:  Going Multi-Cluster  with Istio
Kubernetes at Scale: Going Multi-Cluster with Istio
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
 
Transforming Product Development using OnePlan To Boost Efficiency and Innova...
Transforming Product Development using OnePlan To Boost Efficiency and Innova...Transforming Product Development using OnePlan To Boost Efficiency and Innova...
Transforming Product Development using OnePlan To Boost Efficiency and Innova...
 
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
 
The Comprehensive Guide to Validating Audio-Visual Performances.pdf
The Comprehensive Guide to Validating Audio-Visual Performances.pdfThe Comprehensive Guide to Validating Audio-Visual Performances.pdf
The Comprehensive Guide to Validating Audio-Visual Performances.pdf
 
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
 
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
 
WWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders AustinWWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders Austin
 
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data PlatformAlluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
 
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSISDECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
 
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
 
All you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVMAll you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVM
 
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
 
Migration From CH 1.0 to CH 2.0 and Mule 4.6 & Java 17 Upgrade.pptx
Migration From CH 1.0 to CH 2.0 and  Mule 4.6 & Java 17 Upgrade.pptxMigration From CH 1.0 to CH 2.0 and  Mule 4.6 & Java 17 Upgrade.pptx
Migration From CH 1.0 to CH 2.0 and Mule 4.6 & Java 17 Upgrade.pptx
 
Upturn India Technologies - Web development company in Nashik
Upturn India Technologies - Web development company in NashikUpturn India Technologies - Web development company in Nashik
Upturn India Technologies - Web development company in Nashik
 
一比一原版(sdsu毕业证书)圣地亚哥州立大学毕业证如何办理
一比一原版(sdsu毕业证书)圣地亚哥州立大学毕业证如何办理一比一原版(sdsu毕业证书)圣地亚哥州立大学毕业证如何办理
一比一原版(sdsu毕业证书)圣地亚哥州立大学毕业证如何办理
 

Dip into Coroutines - KTUG Munich 202303

  • 1. Dip into Coroutines A story full of suspends
  • 2. Software Engineer @ Gradle Formerly @ dxFeed Twitter @alllexist — GitHub @alllex Alex Semin
  • 4. fun main() = runBlocking { val jobs: List<Deferred<Boolean?> = List(100_000) { async { request(it) } } val evenCount = jobs.count { it.await() } println("There $evenCount even numbers") } suspend fun request(id: Int): Boolean { delay(1.seconds) return id % 2 ?= 0 }
  • 5. fun main() = runBlocking { val jobs: List<Deferred<Boolean?> = List(100_000) { async { request(it) } } val evenCount = jobs.count { it.await() } println("There $evenCount even numbers") } suspend fun request(id: Int): Boolean { delay(1.seconds) return id % 2 ?= 0 }
  • 6. fun main() = runBlocking { val jobs: List<Deferred<Boolean?> = List(100_000) { async { request(it) } } val evenCount = jobs.count { it.await() } println("There $evenCount even numbers") } suspend fun request(id: Int): Boolean { delay(1.seconds) return id % 2 ?= 0 } import kotlinx.coroutines.*
  • 7. What’s where? kotlinx.coroutines kotlin.coroutines launch async await … Job runBlocking coroutineScope Deferred withTimeout Continuation CoroutineContext createCoroutine* suspendCoroutine* COROUTINE_SUSPENDED ContinuationInterceptor delay … …
  • 9. Sequences list.asSequence() .filter { … } .map { … } .filter { … } // 1, 2, 4, 8, //. val seq = generateSequence(1) { it * 2 } for (item in seq) { println(item) } interface Sequence<out T> { operator fun iterator(): Iterator<T> } interface Iterator<out T> { operator fun next(): T operator fun hasNext(): Boolean } val iter = seq.iterator() while (iter.hasNext()) { val item = iter.next() println(item) }
  • 10. Sequence builders val fib = sequence { print("Start ") yield(1) // Label 1 var cur = 1 var next = 1 while (true) { print("Next ") yield(next) // Label 2 val tmp = cur + next cur = next next = tmp } } fib.take(4).forEach { print("$it ") } // Start 1 Next 1 Next 2 Next 3 fun <T> sequence( block: suspend SequenceScope<T>.() ?> Unit ): Sequence<T> abstract class SequenceScope<in T> { abstract suspend fun yield(value: T) }
  • 11. class SequenceBuilder<T> : SequenceScope<T>(), Iterator<T> { var state: State = State.NotReady // enum NotReady, Ready, Done var nextValue: T? = null var nextStep: Continuation<Unit>? = null override fun next(): T = when (state) { … } override fun hasNext(): Boolean { … } override suspend fun yield(value: T) { … } }
  • 12. class SequenceBuilder<T> : SequenceScope<T>(), Iterator<T> { var state: State = State.NotReady // enum NotReady, Ready, Done var nextValue: T? = null var nextStep: Continuation<Unit>? = null override fun next(): T = when (state) { State.NotReady ?> if (hasNext()) next() else error("oops") State.Ready ?> { state = State.NotReady nextValue as T } else ?> error("oops") } override fun hasNext(): Boolean { … } override suspend fun yield(value: T) { … } }
  • 13. class SequenceBuilder<T> : SequenceScope<T>(), Iterator<T> { var state: State = State.NotReady // enum NotReady, Ready, Done var nextValue: T? = null var nextStep: Continuation<Unit>? = null override fun next(): T = when (state) {} override fun hasNext(): Boolean { while (true) { when (state) { State.NotReady ?> { state = State.Done nextStep?!.resume(Unit) } State.Done ?> return false State.Ready ?> return true } } } override suspend fun yield(value: T) { … } } interface Continuation<in T> { val context: CoroutineContext fun resumeWith(result: Result<T>) } fun <T> Continuation<T>.resume(value: T) = resumeWith(Result.success(value))
  • 14. class SequenceBuilder<T> : SequenceScope<T>(), Iterator<T> { var state: State = State.NotReady // enum NotReady, Ready, Done var nextValue: T? = null var nextStep: Continuation<Unit>? = null override fun next(): T = when (state) {} override fun hasNext(): Boolean { while (true) { when (state) { State.NotReady ?> { state = State.Done nextStep?!.resume(Unit) } State.Done ?> return false State.Ready ?> return true } } } override suspend fun yield(value: T) { … } } val fib = sequence { print("Start ") yield(1) // Label 1 var cur = 1 var next = 1 while (true) { print("Next ") yield(next) // Label 2 val tmp = cur + next cur = next next = tmp } }
  • 15. class SequenceBuilder<T> : SequenceScope<T>(), Iterator<T> { var state: State = State.NotReady // enum NotReady, Ready, Done var nextValue: T? = null var nextStep: Continuation<Unit>? = null override fun hasNext(): Boolean { … } override fun next(): T = when (state) { … } override suspend fun yield(value: T) { nextValue = value state = State.Ready } } val fib = sequence { print("Start ") yield(1) // Label 1 var cur = 1 var next = 1 while (true) { print("Next ") yield(next) // Label 2 val tmp = cur + next cur = next next = tmp } }
  • 16. class SequenceBuilder<T> : SequenceScope<T>(), Iterator<T> { var state: State = State.NotReady // enum NotReady, Ready, Done var nextValue: T? = null var nextStep: Continuation<Unit>? = null override fun hasNext(): Boolean { … } override fun next(): T = when (state) { … } override suspend fun yield(value: T) { nextValue = value state = State.Ready return suspendCoroutineUninterceptedOrReturn { c -> nextStep = c COROUTINE_SUSPENDED } } } val fib = sequence { print("Start ") yield(1) // Label 1 var cur = 1 var next = 1 while (true) { print("Next ") yield(next) // Label 2 val tmp = cur + next cur = next next = tmp } }
  • 17. Continuation Passing Style T | COROUTINE_SUSPENDED suspend fun yield(value: T): Unit source code fun yield(value: T, cont: Continuation<Unit>): Any? compiled code
  • 18. Continuation Passing Style override suspend fun yield(value: T) { nextValue = value state = State.Ready return suspendCoroutineUninterceptedOrReturn { cont -> nextStep = cont COROUTINE_SUSPENDED } } override suspend fun yield(value: T, cont: Continuation<Unit>): Any? { nextValue = value state = State.Ready nextStep = cont return COROUTINE_SUSPENDED }
  • 19.
  • 21. Deeply recursive functions fun depth(t: Tree?): Int = if (t ?= null) 0 else maxOf(depth(t.left), depth(t.right)) + 1 println(depth(deepTree)) // StackOverflowError class Tree(val left: Tree? = null, val right: Tree? = null) val deepTree = generateSequence(Tree()) { Tree(left = it) }.take(100_000).last() val depth = DeepRecursiveFunction<Tree?, Int> { t -> if (t ?= null) 0 else maxOf( callRecursive(t.left), callRecursive(t.right) ) + 1 } println(depth(deepTree)) // Ok
  • 22. Deeply recursive functions sealed class DeepRecursiveScope<T, R> { abstract suspend fun callRecursive(value: T): R } override suspend fun callRecursive(value: T): R { return suspendCoroutineUninterceptedOrReturn { c -> this.cont = c as Continuation<Any?> this.value = value COROUTINE_SUSPENDED } } fun runCallLoop(): R { while (true) { val result = this.result val cont = this.cont ?: return result.getOrThrow() if (UNDEFINED_RESULT ?= result) { val r = try { function(this, value, cont) } catch (e: Throwable) { cont.resumeWithException(e) continue } if (r ??= COROUTINE_SUSPENDED) cont.resume(r as R) } else { this.result = UNDEFINED_RESULT cont.resumeWith(result) } } }
  • 23. Deeply recursive functions sealed class DeepRecursiveScope<T, R> { abstract suspend fun callRecursive(value: T): R } override suspend fun callRecursive(value: T): R { return suspendCoroutineUninterceptedOrReturn { c -> this.cont = c as Continuation<Any?> this.value = value COROUTINE_SUSPENDED } } fun runCallLoop(): R { while (true) { val result = this.result val cont = this.cont ?: return result.getOrThrow() if (UNDEFINED_RESULT ?= result) { val r = try { function(this, value, cont) } catch (e: Throwable) { cont.resumeWithException(e) continue } if (r ??= COROUTINE_SUSPENDED) cont.resume(r as R) } else { this.result = UNDEFINED_RESULT cont.resumeWith(result) } } }
  • 24.
  • 26. Parsing expressions sealed class Expr { object TRUE : Expr() object FALSE : Expr() data class Var(val name: String) : Expr() data class Not(val body: Expr) : Expr() data class And(val left: Expr, val right: Expr) : Expr() data class Or(val left: Expr, val right: Expr) : Expr() data class Impl(val left: Expr, val right: Expr) : Expr() } val expr = "a & (b1 ?> c1) | a1 & !b | !(a1 ?> a2) ?> a"
  • 27. object BooleanGrammar : Grammar<Expr>() { init { register(regexToken("s+", ignored = true)) } val tru by literalToken("true") val fal by literalToken("false") val id by regexToken("w+") val lpar by literalToken("(") val rpar by literalToken(")") val not by literalToken("!") val and by literalToken("&") val or by literalToken("|") val impl by literalToken("?>") val negation by parser { -not * term() } map { Not(it) } val braced by parser { -lpar * expr() * -rpar } val term: Parser<Expr> by (tru map TRUE) or (fal map FALSE) or (id map { Var(it.text) }) or negation or braced val andChain by parser { leftAssociative(term, and) { a, _, b -> And(a, b) } } val orChain by parser { leftAssociative(andChain, or) { a, _, b -> Or(a, b) } } val implChain by parser { rightAssociative(orChain, impl) { a, _, b -> Impl(a, b) } } val expr by implChain override val root by expr } "a & (b1 ?> c1) | a1 & !b | !(a1 ?> a2) ?> a"
  • 28. object BooleanGrammar : Grammar<Expr>() { init { register(regexToken("s+", ignored = true)) } val tru by literalToken("true") val fal by literalToken("false") val id by regexToken("w+") val lpar by literalToken("(") val rpar by literalToken(")") val not by literalToken("!") val and by literalToken("&") val or by literalToken("|") val impl by literalToken("?>") val negation by parser { -not * term() } map { Not(it) } val braced by parser { -lpar * expr() * -rpar } val term: Parser<Expr> by (tru map TRUE) or (fal map FALSE) or (id map { Var(it.text) }) or negation or braced val andChain by parser { leftAssociative(term, and) { a, _, b -> And(a, b) } } val orChain by parser { leftAssociative(andChain, or) { a, _, b -> Or(a, b) } } val implChain by parser { rightAssociative(orChain, impl) { a, _, b -> Impl(a, b) } } val expr by implChain override val root by expr }
  • 29. suspend fun <T : Any, S : Any> ParsingScope.leftAssociative( term: Parser<T>, operator: Parser<S>, transform: (T, S, T) ?> T ): T { var l: T = term() while (true) { val (o, r) = maybe(parser { operator() to term() }) ?: break l = transform(l, o, r) } return l } val input = "K | o | t | l | i | n | i | s | a | w | e | s | o | m | e" parser { leftAssociative(id, "|") { l, _, r -> "$l$r" } }
  • 32. Awesome! How to learn more?
  • 36. Than you! Twitter @alllexist — GitHub @alllex