SlideShare a Scribd company logo
1 of 156
Download to read offline
Kotlin	Coroutines	Reloaded
Presented	at	JVM	Language	Summit,	2017
/Roman	Elizarov	@	JetBrains
Speaker:	Roman	Elizarov
• 16+	years	experience
• Previously	developed	high-perf	trading	software	
@	Devexperts
• Teach	concurrent	&	distributed	programming	
@	St.	Petersburg	ITMO	University
• Chief	judge	
@	Northeastern	European	Region	of	ACM	ICPC	
• Now	work	on	Kotlin	
@	JetBrains
Agenda
• Recap	of	Kotlin	coroutines	prototype
• Presented	@	JVMLS,	2016	by	Andrey	Breslav
• The	issues	in	the	prototype	design
• and	the	solutions	that	were	found
• Design	released	to	public	in	Kotlin	1.1
• Evolved	coroutines	support	libraries
• Challenges	&	future	directions
Recap	of	Kotlin	coroutines	
prototype
Presented	@	JVMLS,	2016	by	Andrey	Breslav
Async	the	C#	(JS,	TS,	Dart,	etc)	way
async Task<String> Work() { … }
async Task MoreWork()
{
Console.WriteLine("Work started");
var str = await Work();
Console.WriteLine($"Work completed {str}");
}
Async	the	C#	(JS,	TS,	Dart,	etc)	way
async Task<String> work() { … }
async Task MoreWork()
{
Console.WriteLine("Work started");
var str = await Work();
Console.WriteLine($"Work completed {str}");
}
Async	the	Kotlin	way	(prototype)
fun work(): CompletableFuture<String> { … }
fun moreWork() = async {
println("Work started")
val str = await(work())
println("Work completed: $str")
}
Async	the	Kotlin	way	(prototype)
fun work(): CompletableFuture<String> { … }
fun moreWork() = async {
println("Work started")
val str = await(work())
println("Work completed: $str")
}
Functions	vs	Keywords
Extensibility
Runs	on	stock	JVM	1.6+
Purely	local	-- no	global	
bytecode	transforms
Suspending	functions
A	grand	unification	between	async/await	and	generate/yield
Suspending	functions:	use
val str = await(work())
Suspending	functions:	use
val str = await(work())
CompletableFuture<String>
// String result
Suspending	functions:	declare	(prototype)
val str = await(work())
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Unit
CompletableFuture<String>
// String result
Suspending	functions:	declare	(prototype)
val str = await(work())
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Unit
CompletableFuture<String>
callback void
// String result
Magic	signature	transformation
Suspending	functions:	declare	(prototype)
val str = await(work())
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Unit
CompletableFuture<String>
callback void
// String result
Continuation	is	a	generic	callback	interface
interface Continuation<in T> {
fun resume(value: T)
fun resumeWithException(exception: Throwable)
}
Suspending	functions:	implement	(prototype)
val str = await(work())
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>) {
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
CompletableFuture<String>
// String result
Suspending	functions:	implement	(prototype)
val str = await(work())
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>) {
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
CompletableFuture<String>
// String result
Suspending	functions:	implement	(prototype)
val str = await(work())
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>) {
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
CompletableFuture<String>
// String result
Suspending	functions:	implement	(prototype)
val str = await(work())
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>) {
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
CompletableFuture<String>
// String result
Suspending	functions:	implement	(prototype)
val str = await(work())
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>) {
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
CompletableFuture<String>
// String result
Simple,	but	wrong!
A	problematic	example
Where	grand	vision	meets	reality
A	problematic	example
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>) {
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
fun problem() = async {
repeat(10_000) {
await(work())
}
}
A	problematic	example
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>) {
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
fun problem() = async {
repeat(10_000) {
await(work())
}
}
What	if	work()	always	returns	a	
future	that	is	already	complete?
A	problematic	example
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>) {
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
fun problem() = async {
repeat(10_000) {
await(work())
}
}
stack
problem$stateMachine
A	problematic	example
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>) {
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
fun problem() = async {
repeat(10_000) {
await(work())
}
}
stack
problem$stateMachine
await
A	problematic	example
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>) {
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
fun problem() = async {
repeat(10_000) {
await(work())
}
}
stack
problem$stateMachine
await
CompletableFuture.whenComplete
A	problematic	example
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>) {
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
fun problem() = async {
repeat(10_000) {
await(work())
}
}
stack
problem$stateMachine
await
CompletableFuture.whenComplete
await$lambda
A	problematic	example
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>) {
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
fun problem() = async {
repeat(10_000) {
await(work())
}
}
stack
problem$stateMachine
await
CompletableFuture.whenComplete
await$lambda
A	problematic	example
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>) {
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
fun problem() = async {
repeat(10_000) {
await(work())
}
}
stack
problem$stateMachine
await
CompletableFuture.whenComplete
await$lambda
ContinuationImpl.resume
A	problematic	example
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>) {
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
fun problem() = async {
repeat(10_000) {
await(work())
}
}
stack
problem$stateMachine
await
CompletableFuture.whenComplete
await$lambda
ContinuationImpl.resume
problem$stateMachine
A	problematic	example
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>) {
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
fun problem() = async {
repeat(10_000) {
await(work())
}
}
stack
problem$stateMachine
await
CompletableFuture.whenComplete
await$lambda
ContinuationImpl.resume
problem$stateMachine
await
A	problematic	example
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>) {
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
fun problem() = async {
repeat(10_000) {
await(work())
}
}
stack
problem$stateMachine
await
CompletableFuture.whenComplete
await$lambda
ContinuationImpl.resume
problem$stateMachine
await
…
StackOverflowError
A	solution
A	difference	between	knowing	the	path	&	walking	the	path.
A	solution
val str = await(work())
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Unit
CompletableFuture<String>
// String result
A	solution	(0):	stack	unwind	convention
val str = await(work())
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Any?
CompletableFuture<String>
// String result
A	solution	(0)
val str = await(work())
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Any?
CompletableFuture<String>
// String result
T | COROUTINE_SUSPENDED
A	solution	(0)
val str = await(work())
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Any?
CompletableFuture<String>
// String result
T | COROUTINE_SUSPENDED
Did	not	suspend	->	Returns	result
A	solution	(0)
val str = await(work())
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Any?
CompletableFuture<String>
// String result
T | COROUTINE_SUSPENDED
Did	not	suspend	->	Returns	result
Did	suspend	->	WILL	invoke	continuation
A	solution	(0)
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Any? {
…
}
A	solution?
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Any? {
val consensus = AtomicReference<Any?>(UNDECIDED)
f.whenComplete { value, exception ->
if (exception != null) {
if (!consensus.compareAndSet(UNDECIDED, Fail(exception)))
c.resumeWithException(exception)
} else {
if (!consensus.compareAndSet(UNDECIDED, value))
c.resume(value!!)
}
}
consensus.compareAndSet(UNDECIDED, COROUTINE_SUSPENDED)
val result = consensus.get()
if (result is Fail) throw result.exception
return result
}
A	solution?
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Any? {
val consensus = AtomicReference<Any?>(UNDECIDED)
f.whenComplete { value, exception ->
if (exception != null) {
if (!consensus.compareAndSet(UNDECIDED, Fail(exception)))
c.resumeWithException(exception)
} else {
if (!consensus.compareAndSet(UNDECIDED, value))
c.resume(value!!)
}
}
consensus.compareAndSet(UNDECIDED, COROUTINE_SUSPENDED)
val result = consensus.get()
if (result is Fail) throw result.exception
return result
}
Wat?
A	solution	(1):	Call/declaration	fidelity
A	solution	(1)
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Any?
A	solution	(1)
suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Any?
suspend fun <T> await(f: CompletableFuture<T>): T
natural	signature
A	solution	(1)
fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Any?
suspend fun <T> await(f: CompletableFuture<T>): T
Compiles	as	(on	JVM)
A	solution	(1)
fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Any?
suspend fun <T> await(f: CompletableFuture<T>): T
Compiles	as	(on	JVM)
CPS	Transformation
A	solution	(1)
fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Any?
suspend fun <T> await(f: CompletableFuture<T>)
suspend fun <T> await(f: CompletableFuture<T>): T =
suspendCoroutineOrReturn { c ->
…
}
Recover	continuation
A	solution	(1)
fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Any?
suspend fun <T> await(f: CompletableFuture<T>)
suspend fun <T> await(f: CompletableFuture<T>): T =
suspendCoroutineOrReturn { c ->
…
}
Inspired	by	call/cc	from	Scheme
Recover	continuation
A	solution	(1)
fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Any?
suspend fun <T> await(f: CompletableFuture<T>)
suspend fun <T> await(f: CompletableFuture<T>): T =
suspendCoroutineOrReturn { c ->
…
}
Works	as
Inspired	by	call/cc	from	Scheme
A	solution	(1)
suspend fun <T> await(f: CompletableFuture<T>): T =
suspendCoroutineOrReturn { c ->
…
}
A	solution	(1)
suspend fun <T> await(f: CompletableFuture<T>): T =
suspendCoroutineOrReturn { c ->
…
}
inline suspend fun <T> suspendCoroutineOrReturn(
crossinline block: (Continuation<T>) -> Any?): T
A	solution	(1)
suspend fun <T> await(f: CompletableFuture<T>): T =
suspendCoroutineOrReturn { c ->
…
}
inline suspend fun <T> suspendCoroutineOrReturn(
crossinline block: (Continuation<T>) -> Any?): T
T | COROUTINE_SUSPENDED
A	solution	(1)
suspend fun <T> await(f: CompletableFuture<T>): T =
suspendCoroutineOrReturn { c ->
…
}
inline suspend fun <T> suspendCoroutineOrReturn(
crossinline block: (Continuation<T>) -> Any?): T
Intrinsic
T | COROUTINE_SUSPENDED
A	solution	(1)
suspend fun <T> await(f: CompletableFuture<T>): T =
suspendCoroutineOrReturn { c ->
…
}
inline suspend fun <T> suspendCoroutineOrReturn(
crossinline block: (Continuation<T>) -> Any?): T
fun <T> suspendCoroutineOrReturn(
crossinline block: (Continuation<T>) -> Any?,
c: Continuation<T>): Any? =
block(c)
Compiles	as	(on	JVM)
Intrinsic
CPS	Transformation
A	solution	(1)
suspend fun <T> await(f: CompletableFuture<T>): T =
suspendCoroutineOrReturn { c ->
…
}
inline suspend fun <T> suspendCoroutineOrReturn(
crossinline block: (Continuation<T>) -> Any?): T
fun <T> suspendCoroutineOrReturn(
crossinline block: (Continuation<T>) -> Any?,
c: Continuation<T>): Any? =
block(c)
Compiles	as	(on	JVM)
Intrinsic
CPS	Transformation
A	solution	(2):	Tail	suspension
A	solution	(2)
suspend fun <T> await(f: CompletableFuture<T>): T =
suspendCoroutineOrReturn { c ->
…
}
Tail	suspend	invocation:
Continuation	pass-through
A	solution	(2)
suspend fun <T> await(f: CompletableFuture<T>): T =
suspendCoroutineOrReturn { c ->
…
}
fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Any? =
suspendCoroutineOrReturn(c) { c ->
…
}
Tail	suspend	invocation:
Continuation	pass-through
Compiles	as	(on	JVM)
CPS	Transformation
A	solution	(2)
suspend fun <T> await(f: CompletableFuture<T>): T =
suspendCoroutineOrReturn { c ->
…
}
fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Any? =
suspendCoroutineOrReturn(c) { c ->
…
}
Tail	suspend	invocation:
Continuation	pass-through
Compiles	as	(on	JVM)
CPS	Transformation
A	solution	(2)
suspend fun <T> await(f: CompletableFuture<T>): T =
suspendCoroutineOrReturn { c ->
…
}
fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Any? {
…
}
Tail	suspend	invocation:
Continuation	pass-through
Compiles	as	(on	JVM)
CPS	Transformation
A	solution	(3):	Abstraction
A	solution	(3)
public inline suspend fun <T> suspendCoroutine(
crossinline block: (Continuation<T>) -> Unit): T =
suspendCoroutineOrReturn { c: Continuation<T> ->
val safe = SafeContinuation(c)
block(safe)
safe.getResult()
}
A	solution	(3)
public inline suspend fun <T> suspendCoroutine(
crossinline block: (Continuation<T>) -> Unit): T =
suspendCoroutineOrReturn { c: Continuation<T> ->
val safe = SafeContinuation(c)
block(safe)
safe.getResult()
}
A	solution	(3)
public inline suspend fun <T> suspendCoroutine(
crossinline block: (Continuation<T>) -> Unit): T =
suspendCoroutineOrReturn { c: Continuation<T> ->
val safe = SafeContinuation(c)
block(safe)
safe.getResult()
}
Any?	Is	gone
A	solution	(3)
public inline suspend fun <T> suspendCoroutine(
crossinline block: (Continuation<T>) -> Unit): T =
suspendCoroutineOrReturn { c: Continuation<T> ->
val safe = SafeContinuation(c)
block(safe)
safe.getResult()
}
Encapsulates	result	
consensus	algorithm
A	solution	(4):	Putting	it	all	together
A	solution	(4)
suspend fun <T> await(f: CompletableFuture<T>): T =
suspendCoroutine { c ->
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
Looks	simple,	works	correctly!
Recap	steps	to	solution
• T	|	COROUTINE_SUSPENDED	(Any?)	to	allow	invocations	that	
do	not	suspend	and	thus	avoid	StackOverflowError
• Call/declaration	fidelity	via	CPS	transformation
• Introduce	call/cc	(suspendCoroutineOrReturn)	to	recover	
hidden	continuation
• Tail	call	invocation	support	to	recover	prototype	semantics
• Use	abstraction	(suspendCoroutine)	to	hide	implementation	
complexities	from	end-users
The	final	touch:	await	extension
suspend fun <T> await(f: CompletableFuture<T>): T =
suspendCoroutine { c ->
f.whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
The	final	touch:	await	extension
suspend fun <T> CompletableFuture<T>.await(): T =
suspendCoroutine { c ->
whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
The	final	touch:	await	extension
suspend fun <T> CompletableFuture<T>.await(): T =
suspendCoroutine { c ->
whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
fun moreWork() = async {
println("Work started")
val str = await(work())
println("Work completed: $str")
}
The	final	touch:	await	extension
suspend fun <T> CompletableFuture<T>.await(): T =
suspendCoroutine { c ->
whenComplete { value, exception ->
if (exception != null) c.resumeWithException(exception)
else c.resume(value!!)
}
}
fun moreWork() = async {
println("Work started")
val str = work().await()
println("Work completed: $str")
}
Reads	left-to-right	just	like	it	executes
Coroutine	builders
The	mystery	of	inception
Coroutine	builders	(prototype)
fun <T> async(
coroutine c: FutureController<T>.() -> Continuation<Unit>
): CompletableFuture<T> {
val controller = FutureController<T>()
c(controller).resume(Unit)
return controller.future
}
Coroutine	builders	(prototype)
fun <T> async(
coroutine c: FutureController<T>.() -> Continuation<Unit>
): CompletableFuture<T> {
val controller = FutureController<T>()
c(controller).resume(Unit)
return controller.future
}
A	special	modifier
Coroutine	builders	(prototype)
fun <T> async(
coroutine c: FutureController<T>.() -> Continuation<Unit>
): CompletableFuture<T> {
val controller = FutureController<T>()
c(controller).resume(Unit)
return controller.future
}
Magic	signature	transformation
Coroutine	builders	(prototype)
fun <T> async(
coroutine c: FutureController<T>.() -> Continuation<Unit>
): CompletableFuture<T> {
val controller = FutureController<T>()
c(controller).resume(Unit)
return controller.future
}
A	boilerplate	to	start	coroutine
Coroutine	builders	(prototype)
fun <T> async(
coroutine c: FutureController<T>.() -> Continuation<Unit>
): CompletableFuture<T> { … }
class FutureController<T> {
val future = CompletableFuture<T>()
operator fun handleResult(value: T, c: Continuation<Nothing>) {
future.complete(value)
}
operator fun handleException(exception: Throwable,
c: Continuation<Nothing>) {
future.completeExceptionally(exception)
}
}
Coroutine	builders	(prototype)
fun <T> async(
coroutine c: FutureController<T>.() -> Continuation<Unit>
): CompletableFuture<T> { … }
class FutureController<T> {
val future = CompletableFuture<T>()
operator fun handleResult(value: T, c: Continuation<Nothing>) {
future.complete(value)
}
operator fun handleException(exception: Throwable,
c: Continuation<Nothing>) {
future.completeExceptionally(exception)
}
}
Coroutine	builders	(prototype)
fun <T> async(
coroutine c: FutureController<T>.() -> Continuation<Unit>
): CompletableFuture<T> { … }
class FutureController<T> {
val future = CompletableFuture<T>()
operator fun handleResult(value: T, c: Continuation<Nothing>) {
future.complete(value)
}
operator fun handleException(exception: Throwable,
c: Continuation<Nothing>) {
future.completeExceptionally(exception)
}
}
was	never	used
Coroutine	builders	(prototype)
fun <T> async(
coroutine c: FutureController<T>.() -> Continuation<Unit>
): CompletableFuture<T> { … }
class FutureController<T> {
val future = CompletableFuture<T>()
operator fun handleResult(value: T) {
future.complete(value)
}
operator fun handleException(exception: Throwable) {
future.completeExceptionally(exception)
}
}
Coroutine	builders	(prototype)
fun <T> async(
coroutine c: FutureController<T>.() -> Continuation<Unit>
): CompletableFuture<T> { … }
class FutureController<T> {
val future = CompletableFuture<T>()
operator fun handleResult(value: T) {
future.complete(value)
}
operator fun handleException(exception: Throwable) {
future.completeExceptionally(exception)
}
}
Looks	like	Continuation<T>
Coroutine	builders	(prototype)
fun <T> async(
coroutine c: FutureController<T>.() -> Continuation<Unit>
): CompletableFuture<T> { … }
class FutureController<T> {
val future = CompletableFuture<T>()
operator fun handleResult(value: T) {
future.complete(value)
}
operator fun handleException(exception: Throwable) {
future.completeExceptionally(exception)
}
}
Something	that	takes	Continuation<T>
Coroutine	builders:	evolved
Coroutine	builders
fun <T> async(
c: suspend () -> T
): CompletableFuture<T> {
val controller = FutureController<T>()
c.startCoroutine(completion = controller)
return controller.future
}
Coroutine	builders
fun <T> async(
c: suspend () -> T
): CompletableFuture<T> {
val controller = FutureController<T>()
c.startCoroutine(completion = controller)
return controller.future
}
natural	signature
No	special	coroutine keyword
Coroutine	builders
fun <T> async(
c: suspend () -> T
): CompletableFuture<T> {
val controller = FutureController<T>()
c.startCoroutine(completion = controller)
return controller.future
}
Provided	by	standard	library
Coroutine	builders
fun <T> async(
c: suspend () -> T
): CompletableFuture<T> { … }
class FutureController<T> : Continuation<T> {
val future = CompletableFuture<T>()
override fun resume(value: T) {
future.complete(value)
}
override fun resumeWithException(exception: Throwable) {
future.completeExceptionally(exception)
}
}
Coroutine	builders
fun <T> async(
c: suspend () -> T
): CompletableFuture<T> { … }
class FutureController<T> : Continuation<T> {
val future = CompletableFuture<T>()
override fun resume(value: T) {
future.complete(value)
}
override fun resumeWithException(exception: Throwable) {
future.completeExceptionally(exception)
}
}
Serves	as	completion
continuation	for	coroutine
Bonus	features
Free	as	in	cheese
Arbitrary	suspending	calls
suspend fun <T> suspending(block: suspend () -> T): T =
suspendCoroutine { continuation ->
block.startCoroutine(completion = continuation)
}
Arbitrary	suspending	calls
suspend fun <T> suspending(block: suspend () -> T): T =
suspendCoroutine { continuation ->
block.startCoroutine(completion = continuation)
}
Arbitrary	suspending	calls
suspend fun <T> suspending(block: suspend () -> T): T =
suspendCoroutine { continuation ->
block.startCoroutine(completion = continuation)
}
Arbitrary	suspending	calls
suspend fun <T> suspending(block: suspend () -> T): T =
suspendCoroutine { continuation ->
block.startCoroutine(completion = continuation)
}
fun moreWork() = async {
println("Work started")
val str = work().await()
println("Work completed: $str")
}
Returns	CompletableFuture
Arbitrary	suspending	calls
suspend fun <T> suspending(block: suspend () -> T): T =
suspendCoroutine { continuation ->
block.startCoroutine(completion = continuation)
}
suspend fun moreWork(): T = suspending {
println("Work started")
val str = work().await()
println("Work completed: $str")
}
Arbitrary	suspending	calls
suspend fun <T> suspending(block: suspend () -> T): T =
suspendCoroutine { continuation ->
block.startCoroutine(completion = continuation)
}
suspend fun moreWork(): T = suspending {
println("Work started")
val str = work().await()
println("Work completed: $str")
}
Tail	suspend	invocation
Non-tail	(arbitrary)	suspend	invocation
Arbitrary	suspending	calls
suspend fun moreWork() {
println("Work started")
val str = work().await()
println("Work completed: $str")
}
Non-tail	(arbitrary)	suspend	invocation
Stackless vs	Stackful coroutines
The	crucial	distinction
Stackless vs	Stackful coroutines
Stackless Stackful
Restrictions Use	in	special ctx Use	anywhere
Implemented in C#,	Scala,	Kotlin, … Quasar, Javaflow,	…
Stackless vs	Stackful coroutines
Stackless Stackful
Restrictions Use	in	special ctx Use	anywhere
Implemented in C#,	Scala,	Kotlin, … Quasar, Javaflow,	…
Stackless vs	Stackful coroutines
Stackless Stackful
Restrictions Use	in	special ctx Use	anywhere
Implemented in C#,	Scala,	Kotlin, … Quasar, Javaflow,	…
Can suspend	in? suspend
functions
throws SuspendExecution /	
@Suspendable functions
Stackless vs	Stackful coroutines
Stackless Stackful
Restrictions Use	in	special ctx Use	anywhere
Implemented in C#,	Scala, … Kotlin,	Quasar, Javaflow,	…
Stackless vs	Stackful coroutines
Stackless Stackful
Restrictions Use	in	special ctx Use	anywhere
Implemented in C#,	Scala, Kotlin,	
Quasar, JavaFlow,	…
LISP,	Go,	…
Stackless vs	Stackful coroutines
Stackless Stackful
Restrictions Use	in	special ctx Use	anywhere
Implemented in C#,	Scala, … Kotlin,	Quasar, Javaflow,	…
False	
dichotomy
Async	vs	Suspending	functions
The	actual	difference
fun work() = async { … }
suspend fun work() { … }
fun work(): CompletableFuture<String> = async { … }
suspend fun work(): String { … }
In	Kotlin	you	have a	choice
fun workAsync(): CompletableFuture<String> = async { … }
suspend fun work(): String { … }
workAsync() VALID –>	produces	CompletableFuture<String>
workAsync().await() VALID –>	produces	String
concurrent	&	async	behavior
sequential	behavior
The	most	needed one,	yet	the	most	syntactically	
clumsy,	esp.	for	suspend-heavy	(CSP)	code	style	
The	problem	with	async
Kotlin	suspending	functions	
imitate	sequential behavior	
by	default	
Concurrency	is	hard
Concurrency	has	to	be	explicit
Composability
Making	those	legos click
Builders
fun <T> async(
c: suspend () -> T
): CompletableFuture<T> { … }
Builders
fun <T> async(
c: suspend () -> T
): ListenableFuture<T> { … }
Builders
fun <T> async(
c: suspend () -> T
): MyOwnFuture<T> { … }
Suspending	functions
fun <T> async(
c: suspend () -> T
): MyOwnFuture<T> { … }
suspend fun <T> CompletableFuture<T>.await(): T { … }
Suspending	functions
fun <T> async(
c: suspend () -> T
): MyOwnFuture<T> { … }
suspend fun <T> ListenableFuture<T>.await(): T { … }
Suspending	functions
fun <T> async(
c: suspend () -> T
): MyOwnFuture<T> { … }
suspend fun <T> MyOwnFuture<T>.await(): T { … }
Suspending	functions
fun <T> async(
c: suspend () -> T
): MyOwnFuture<T> { … }
suspend fun <T> MyOwnFuture<T>.await(): T { … }
fun moreWorkAsync() = async {
println("Work started")
val str = workAsync().await()
println("Work completed: $str")
}
All	combinations	need	to	compose
Composability:	evolved
• Kotlin	suspending	functions	are	composable by	default	
• Asynchronous use-case
• Define	asynchronous	suspending	functions	anywhere
• Use	them	inside	any	asynchronous	coroutine	builder
• Or	inside	other	suspending	functions
• generate/yield coroutines	are	synchronous
• Restricted	via	a	special	@RestrictsSuspension annotation
• Opt-in	to	define	synchronous	coroutines
Coroutine	context
The	last	piece	of	composability	puzzle
asyncUI (prototype)
asyncUI {
val image = await(loadImage(url))
myUI.updateImage(image)
}
Supposed	to	work	in	UI	thread
asyncUI (prototype)
asyncUI {
val image = await(loadImage(url))
myUI.updateImage(image)
}
A	special	coroutine	builder
asyncUI (prototype)
asyncUI {
val image = await(loadImage(url))
myUI.updateImage(image)
}
A	special	suspending	function in	its	scope
Composability	problem	
again!
asyncUI:	evolved
async(UI) {
val image = loadImageAsync(url).await()
myUI.updateImage(image)
}
asyncUI:	evolved
async(UI) {
val image = loadImageAsync(url).await()
myUI.updateImage(image)
}
Explicit	context	convention for	all	builders
Can	intercept continuation	to	
resume	in	the	appropriate	thread
The	actual	Continuation	interface
async(UI) {
val image = loadImageAsync(url).await()
myUI.updateImage(image)
}
interface Continuation<in T> {
val context: CoroutineContext
fun resume(value: T)
fun resumeWithException(exception: Throwable)
}
Is	used	to	transparently	lookup	an	
interceptor	for	resumes
The	actual	Continuation	interface
async(UI) {
val image = loadImageAsync(url).await()
myUI.updateImage(image)
}
interface Continuation<in T> {
val context: CoroutineContext
fun resume(value: T)
fun resumeWithException(exception: Throwable)
}
Does	not	have	to	be	aware	– receives	
intercepted	continuation	to	work	with
Thread-safety
A	million-dollar	quest	for	correctly-synchronized	(data-race	free)	code
A	need	for	happens-before	relation
fun moreWork() = async {
val list = ArrayList<String>()
val str = work().await()
list.add(str)
}
A	need	for	happens-before	relation
fun moreWork() = async {
val list = ArrayList<String>()
val str = work().await()
list.add(str)
}
One	thread
A	need	for	happens-before	relation
fun moreWork() = async {
val list = ArrayList<String>()
val str = work().await()
list.add(str)
}
One	thread
Suspends	/	resumes
A	need	for	happens-before	relation
fun moreWork() = async {
val list = ArrayList<String>()
val str = work().await()
list.add(str)
}
One	thread
Suspends	/	resumes
Another	thread
A	need	for	happens-before	relation
fun moreWork() = async {
val list = ArrayList<String>()
val str = work().await()
list.add(str)
}
One	thread
Suspends	/	resumes
Another	thread
Is	there	a	data	race?
Do	we	need	volatile	when	spilling	
locals	to	a	state	machine?
A	need	for	happens-before	relation
fun moreWork() = async {
val list = ArrayList<String>()
val str = work().await()
list.add(str)
}
There	is	no	data	race	here!	
await establishes	happens-before	relation
happens-before
Challenges
If	it	only	was	all	that	simple…
Thread	confinement	vs	coroutines
fun moreWork() = async {
synchronized(monitor) {
val str = work().await()
}
}
Thread	confinement	vs	coroutines
fun moreWork() = async {
synchronized(monitor) {
val str = work().await()
}
}
MONITORENTER in	one	thread
Suspends	/	resumes
MONITOREXIT in	another	thread
IllegalMonitorStateException
Thread	confinement	vs	coroutines
• Monitors
• Locks	(j.u.c.l.ReentrantLock)
• Thread-locals
• …
• Thread.currentThread()
A	CoroutineContext is	a	map	of	
coroutine-local	elements	as	replacement
Stack	traces	in	exceptions
Stack	traces	in	exceptions
suspend fun moreWork() {
work()
}
suspend fun work() {
someAsyncOp().await()
throw Exception()
}
stack
moreWork
Stack	traces	in	exceptions
suspend fun moreWork() {
work()
}
suspend fun work() {
someAsyncOp().await()
throw Exception()
}
stack
moreWork
work
Stack	traces	in	exceptions
suspend fun moreWork() {
work()
}
suspend fun work() {
someAsyncOp().await()
throw Exception()
}
stack
moreWork
work
await
Stack	traces	in	exceptions
suspend fun moreWork() {
work()
}
suspend fun work() {
someAsyncOp().await()
throw Exception()
}
stack
moreWork
work
Work$StateMachine :
Continuation
----------
fun resume(v)
Stack	traces	in	exceptions
suspend fun moreWork() {
work()
}
suspend fun work() {
someAsyncOp().await()
throw Exception()
}
stack
Work$StateMachine.resume
work
Stack	traces	in	exceptions
suspend fun moreWork() {
work()
}
suspend fun work() {
someAsyncOp().await()
throw Exception()
}
JVM	stack
Work$StateMachine.resume
work
Stack	traces	in	exceptions
suspend fun moreWork() {
work()
}
suspend fun work() {
someAsyncOp().await()
throw Exception()
}
JVM	stack
Work$StateMachine.resume
work
Coroutine	stack
moreWork
work
Stack	traces	in	exceptions
suspend fun moreWork() {
work()
}
suspend fun work() {
someAsyncOp().await()
throw Exception()
}
JVM	stack
Work$StateMachine.resume
work
Coroutine	stack
moreWork
work
Gets	thrown
Stack	traces	in	exceptions
suspend fun moreWork() {
work()
}
suspend fun work() {
someAsyncOp().await()
throw Exception()
}
JVM	stack
Work$StateMachine.resume
work
Coroutine	stack
moreWork
work
Gets	thrown User	wants
Library	evolution
Going	beyond	the	language	&	stdlib
Library	evolution:	already	there
• Communication	&	synchronization	primitives
• Job:	A	completable &	cancellable	entity	to	represent	a	coroutine
• Deferred:	A	future	with	suspend fun	await (and	no thread-blocking	methods)
• Mutex:	with	suspend fun	lock
• Channel:	SendChannel &	ReceiveChannel
• RendezvousChannel – synchronous	rendezvous
• ArrayChannel – fixed	size	buffer
• LinkedListChannel – unlimited	buffer
• ConflatedChannel – only	the	most	recent	sent	element	is	kept
• BroadcastChannel:	multiple	subscribes,	all	receive
Library	evolution:	already	there
• Coroutine	builders
• launch (fire	&	forget,	returns	a	Job)
• async (returns	Deferred)
• future	(integration	with	CompletableFuture &	ListenableFuture)
• runBlocking (to	explicitly	delimit	code	that	blocks	a	thread)
• actor	/ produce	(consume	&	produce	messages	over	channels)
• publish (integration	with	reactive	streams,	returns	Publisher)
• rxCompletable,	rxSingle,	rxObservable,	rxFlowable (RxJava 1/2)
Library	evolution:	already	there
• Top-level	functions	
• select expression	to	await	multiple	events	for	full	CSP-style	programming
• delay	for	time-based	logic	in	coroutines	
• Extensions
• await for	all	kinds	of	futures	(JDK,	Guava,	RxJava)
• aRead,	aWrite,	etc for	AsynchronousXxxChannel in	NIO
• Cancellation	&	job	(coroutine/actor)	hierarchies
• withTimeout for	a	composable way	for	any	suspend	function	run	w/timeout
Library	evolution:	WIP
• Serialization	/	migration	of	coroutines
• Migrating	libraries	to	Kotlin/JS	&	Kotlin/Native	(lang support	– done)
• Full	scope	of	pipelining	operators	on	channels	(filter,	map,	etc)
• Optimizations	for	single-producer	and/or	single-consumer	cases
• Allow	3rd party	primitives	to	participate	in	select (alternatives)
• ByteChannel for	suspendable IO	(http	client/server,	websocket,	etc)
• See	also	ktor.io
A	closing	note	on	terminology
• We	don’t	use	the	term	fiber/strand/green	threads/…
• The	term	coroutine works	just	as	well
• ”Fibers	describe	essentially	the	same	concept	as	coroutines”	©	Wikipedia
Kotlin	Coroutines	are	very light-weight	threads
Wrap	up
Let’s	call	it	a	day
Experimental	status	of	coroutines
• This	design	is	new and	unlike	mainstream
• For	some	very	good	reasons
• We	want	community	to	try	it	for	real
• So	we	released	it	as	an	experimental feature
• We	guarantee	backwards	compatibility
• Old	code	compiled	with	coroutines	continues	to	work
• We	reserve	the	right	to	break	forward	compatibility
• We	may	add	things	so	new	code	may	not	run	w/old	RT
• Design	will	be	finalized	at	a	later	point
• Old	code	will	continue	to	work	via	support	library
• Migration	aids	to	the	final	design	will	be	provided
opt-in	flag
Thank	you
Any	questions?
Slides	are	available	at	www.slideshare.net/elizarov
email	elizarov at	gmail
relizarov

More Related Content

What's hot

Coroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth reviewCoroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth reviewDmytro Zaitsev
 
Java 8 Lambda Built-in Functional Interfaces
Java 8 Lambda Built-in Functional InterfacesJava 8 Lambda Built-in Functional Interfaces
Java 8 Lambda Built-in Functional InterfacesGanesh Samarthyam
 
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹Johnny Sung
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous JavascriptGarrett Welson
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuerymanugoel2003
 
Designing with Capabilities
Designing with CapabilitiesDesigning with Capabilities
Designing with CapabilitiesScott Wlaschin
 
Kotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime PerformanceKotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime Performanceintelliyole
 
Coroutines in Kotlin
Coroutines in KotlinCoroutines in Kotlin
Coroutines in KotlinAlexey Soshin
 
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)Stephen Chin
 
ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaWiem Zine Elabidine
 
OAuth2 and Spring Security
OAuth2 and Spring SecurityOAuth2 and Spring Security
OAuth2 and Spring SecurityOrest Ivasiv
 
Spring security oauth2
Spring security oauth2Spring security oauth2
Spring security oauth2axykim00
 
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшe
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшeQA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшe
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшeQAFest
 

What's hot (20)

Coroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth reviewCoroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth review
 
Optional in Java 8
Optional in Java 8Optional in Java 8
Optional in Java 8
 
C# Basics
C# BasicsC# Basics
C# Basics
 
Java 8 Lambda Built-in Functional Interfaces
Java 8 Lambda Built-in Functional InterfacesJava 8 Lambda Built-in Functional Interfaces
Java 8 Lambda Built-in Functional Interfaces
 
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
 
C++
C++C++
C++
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuery
 
Rxjs ngvikings
Rxjs ngvikingsRxjs ngvikings
Rxjs ngvikings
 
JS Event Loop
JS Event LoopJS Event Loop
JS Event Loop
 
Designing with Capabilities
Designing with CapabilitiesDesigning with Capabilities
Designing with Capabilities
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
 
Kotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime PerformanceKotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime Performance
 
Coroutines in Kotlin
Coroutines in KotlinCoroutines in Kotlin
Coroutines in Kotlin
 
Introduction to kotlin
Introduction to kotlinIntroduction to kotlin
Introduction to kotlin
 
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
 
ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in Scala
 
OAuth2 and Spring Security
OAuth2 and Spring SecurityOAuth2 and Spring Security
OAuth2 and Spring Security
 
Spring security oauth2
Spring security oauth2Spring security oauth2
Spring security oauth2
 
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшe
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшeQA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшe
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшe
 

Similar to Kotlin Coroutines Reloaded Presented at JVM Language Summit 2017

JVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinJVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinAndrey Breslav
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.UA Mobile
 
NDC Sydney 2019 - Async Demystified -- Karel Zikmund
NDC Sydney 2019 - Async Demystified -- Karel ZikmundNDC Sydney 2019 - Async Demystified -- Karel Zikmund
NDC Sydney 2019 - Async Demystified -- Karel ZikmundKarel Zikmund
 
Concurrent Application Development using Scala
Concurrent Application Development using ScalaConcurrent Application Development using Scala
Concurrent Application Development using ScalaSiarhiej Siemianchuk
 
.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund
.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund
.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel ZikmundKarel Zikmund
 
Dip into Coroutines - KTUG Munich 202303
Dip into Coroutines - KTUG Munich 202303Dip into Coroutines - KTUG Munich 202303
Dip into Coroutines - KTUG Munich 202303Alex Semin
 
01 Introduction to Kotlin - Programming in Kotlin.pptx
01 Introduction to Kotlin - Programming in Kotlin.pptx01 Introduction to Kotlin - Programming in Kotlin.pptx
01 Introduction to Kotlin - Programming in Kotlin.pptxIvanZawPhyo
 
Introduction to Kotlin.pptx
Introduction to Kotlin.pptxIntroduction to Kotlin.pptx
Introduction to Kotlin.pptxAzharFauzan9
 
Kotlin coroutine - the next step for RxJava developer?
Kotlin coroutine - the next step for RxJava developer?Kotlin coroutine - the next step for RxJava developer?
Kotlin coroutine - the next step for RxJava developer?Artur Latoszewski
 
Kotlin - Coroutine
Kotlin - CoroutineKotlin - Coroutine
Kotlin - CoroutineSean Tsai
 
Asynchronní programování
Asynchronní programováníAsynchronní programování
Asynchronní programováníPeckaDesign.cz
 
Advanced patterns in asynchronous programming
Advanced patterns in asynchronous programmingAdvanced patterns in asynchronous programming
Advanced patterns in asynchronous programmingMichael Arenzon
 
yield and return (poor English ver)
yield and return (poor English ver)yield and return (poor English ver)
yield and return (poor English ver)bleis tift
 
Property based testing
Property based testingProperty based testing
Property based testingMSDEVMTL
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresiMasters
 
Python Coroutines, Present and Future
Python Coroutines, Present and FuturePython Coroutines, Present and Future
Python Coroutines, Present and Futureemptysquare
 
Kotlin boost yourproductivity
Kotlin boost yourproductivityKotlin boost yourproductivity
Kotlin boost yourproductivitynklmish
 
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.pdfrishteygallery
 

Similar to Kotlin Coroutines Reloaded Presented at JVM Language Summit 2017 (20)

JVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinJVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in Kotlin
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.
 
NDC Sydney 2019 - Async Demystified -- Karel Zikmund
NDC Sydney 2019 - Async Demystified -- Karel ZikmundNDC Sydney 2019 - Async Demystified -- Karel Zikmund
NDC Sydney 2019 - Async Demystified -- Karel Zikmund
 
Concurrent Application Development using Scala
Concurrent Application Development using ScalaConcurrent Application Development using Scala
Concurrent Application Development using Scala
 
.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund
.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund
.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund
 
Dip into Coroutines - KTUG Munich 202303
Dip into Coroutines - KTUG Munich 202303Dip into Coroutines - KTUG Munich 202303
Dip into Coroutines - KTUG Munich 202303
 
01 Introduction to Kotlin - Programming in Kotlin.pptx
01 Introduction to Kotlin - Programming in Kotlin.pptx01 Introduction to Kotlin - Programming in Kotlin.pptx
01 Introduction to Kotlin - Programming in Kotlin.pptx
 
Introduction to Kotlin.pptx
Introduction to Kotlin.pptxIntroduction to Kotlin.pptx
Introduction to Kotlin.pptx
 
Kotlin coroutine - the next step for RxJava developer?
Kotlin coroutine - the next step for RxJava developer?Kotlin coroutine - the next step for RxJava developer?
Kotlin coroutine - the next step for RxJava developer?
 
Kotlin - Coroutine
Kotlin - CoroutineKotlin - Coroutine
Kotlin - Coroutine
 
Asynchronní programování
Asynchronní programováníAsynchronní programování
Asynchronní programování
 
Advanced patterns in asynchronous programming
Advanced patterns in asynchronous programmingAdvanced patterns in asynchronous programming
Advanced patterns in asynchronous programming
 
yield and return (poor English ver)
yield and return (poor English ver)yield and return (poor English ver)
yield and return (poor English ver)
 
Current State of Coroutines
Current State of CoroutinesCurrent State of Coroutines
Current State of Coroutines
 
Property based testing
Property based testingProperty based testing
Property based testing
 
Namespaces
NamespacesNamespaces
Namespaces
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan Soares
 
Python Coroutines, Present and Future
Python Coroutines, Present and FuturePython Coroutines, Present and Future
Python Coroutines, Present and Future
 
Kotlin boost yourproductivity
Kotlin boost yourproductivityKotlin boost yourproductivity
Kotlin boost yourproductivity
 
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
 

More from Roman Elizarov

Fresh Async with Kotlin @ QConSF 2017
Fresh Async with Kotlin @ QConSF 2017Fresh Async with Kotlin @ QConSF 2017
Fresh Async with Kotlin @ QConSF 2017Roman Elizarov
 
Scale Up with Lock-Free Algorithms @ JavaOne
Scale Up with Lock-Free Algorithms @ JavaOneScale Up with Lock-Free Algorithms @ JavaOne
Scale Up with Lock-Free Algorithms @ JavaOneRoman Elizarov
 
Lock-free algorithms for Kotlin Coroutines
Lock-free algorithms for Kotlin CoroutinesLock-free algorithms for Kotlin Coroutines
Lock-free algorithms for Kotlin CoroutinesRoman Elizarov
 
Non blocking programming and waiting
Non blocking programming and waitingNon blocking programming and waiting
Non blocking programming and waitingRoman Elizarov
 
ACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems ReviewRoman Elizarov
 
Многопоточное Программирование - Теория и Практика
Многопоточное Программирование - Теория и ПрактикаМногопоточное Программирование - Теория и Практика
Многопоточное Программирование - Теория и ПрактикаRoman Elizarov
 
Wait for your fortune without Blocking!
Wait for your fortune without Blocking!Wait for your fortune without Blocking!
Wait for your fortune without Blocking!Roman Elizarov
 
ACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems ReviewRoman Elizarov
 
ACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems ReviewRoman Elizarov
 
Why GC is eating all my CPU?
Why GC is eating all my CPU?Why GC is eating all my CPU?
Why GC is eating all my CPU?Roman Elizarov
 
Многопоточные Алгоритмы (для BitByte 2014)
Многопоточные Алгоритмы (для BitByte 2014)Многопоточные Алгоритмы (для BitByte 2014)
Многопоточные Алгоритмы (для BitByte 2014)Roman Elizarov
 
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)Теоретический минимум для понимания Java Memory Model (для JPoint 2014)
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)Roman Elizarov
 
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems ReviewRoman Elizarov
 
Java Serialization Facts and Fallacies
Java Serialization Facts and FallaciesJava Serialization Facts and Fallacies
Java Serialization Facts and FallaciesRoman Elizarov
 
Millions quotes per second in pure java
Millions quotes per second in pure javaMillions quotes per second in pure java
Millions quotes per second in pure javaRoman Elizarov
 
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems ReviewRoman Elizarov
 
The theory of concurrent programming for a seasoned programmer
The theory of concurrent programming for a seasoned programmerThe theory of concurrent programming for a seasoned programmer
The theory of concurrent programming for a seasoned programmerRoman Elizarov
 
Пишем самый быстрый хеш для кэширования данных
Пишем самый быстрый хеш для кэширования данныхПишем самый быстрый хеш для кэширования данных
Пишем самый быстрый хеш для кэширования данныхRoman Elizarov
 

More from Roman Elizarov (19)

Fresh Async with Kotlin @ QConSF 2017
Fresh Async with Kotlin @ QConSF 2017Fresh Async with Kotlin @ QConSF 2017
Fresh Async with Kotlin @ QConSF 2017
 
Scale Up with Lock-Free Algorithms @ JavaOne
Scale Up with Lock-Free Algorithms @ JavaOneScale Up with Lock-Free Algorithms @ JavaOne
Scale Up with Lock-Free Algorithms @ JavaOne
 
Lock-free algorithms for Kotlin Coroutines
Lock-free algorithms for Kotlin CoroutinesLock-free algorithms for Kotlin Coroutines
Lock-free algorithms for Kotlin Coroutines
 
Non blocking programming and waiting
Non blocking programming and waitingNon blocking programming and waiting
Non blocking programming and waiting
 
ACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems Review
 
Многопоточное Программирование - Теория и Практика
Многопоточное Программирование - Теория и ПрактикаМногопоточное Программирование - Теория и Практика
Многопоточное Программирование - Теория и Практика
 
Wait for your fortune without Blocking!
Wait for your fortune without Blocking!Wait for your fortune without Blocking!
Wait for your fortune without Blocking!
 
ACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems Review
 
ACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems Review
 
Why GC is eating all my CPU?
Why GC is eating all my CPU?Why GC is eating all my CPU?
Why GC is eating all my CPU?
 
Многопоточные Алгоритмы (для BitByte 2014)
Многопоточные Алгоритмы (для BitByte 2014)Многопоточные Алгоритмы (для BitByte 2014)
Многопоточные Алгоритмы (для BitByte 2014)
 
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)Теоретический минимум для понимания Java Memory Model (для JPoint 2014)
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)
 
DIY Java Profiling
DIY Java ProfilingDIY Java Profiling
DIY Java Profiling
 
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems Review
 
Java Serialization Facts and Fallacies
Java Serialization Facts and FallaciesJava Serialization Facts and Fallacies
Java Serialization Facts and Fallacies
 
Millions quotes per second in pure java
Millions quotes per second in pure javaMillions quotes per second in pure java
Millions quotes per second in pure java
 
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems Review
 
The theory of concurrent programming for a seasoned programmer
The theory of concurrent programming for a seasoned programmerThe theory of concurrent programming for a seasoned programmer
The theory of concurrent programming for a seasoned programmer
 
Пишем самый быстрый хеш для кэширования данных
Пишем самый быстрый хеш для кэширования данныхПишем самый быстрый хеш для кэширования данных
Пишем самый быстрый хеш для кэширования данных
 

Recently uploaded

Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 

Recently uploaded (20)

Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 

Kotlin Coroutines Reloaded Presented at JVM Language Summit 2017