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
 
Coroutines in Kotlin
Coroutines in KotlinCoroutines in Kotlin
Coroutines in KotlinAlexey Soshin
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Chris Richardson
 
Kotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKirill Rozov
 
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代Shengyou Fan
 
Kotlin coroutine - behind the scenes
Kotlin coroutine - behind the scenesKotlin coroutine - behind the scenes
Kotlin coroutine - behind the scenesAnh Vu
 
Java 8 - interfaces
Java 8 - interfacesJava 8 - interfaces
Java 8 - interfacesFranck SIMON
 
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用Shengyou Fan
 
Add an interactive command line to your C++ application
Add an interactive command line to your C++ applicationAdd an interactive command line to your C++ application
Add an interactive command line to your C++ applicationDaniele Pallastrelli
 
Improving app performance with Kotlin Coroutines
Improving app performance with Kotlin CoroutinesImproving app performance with Kotlin Coroutines
Improving app performance with Kotlin CoroutinesHassan Abid
 
Coroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in PractiseCoroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in PractiseChristian Melchior
 
How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023Shengyou Fan
 
[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園Shengyou Fan
 
PHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object CalisthenicsPHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object CalisthenicsGuilherme Blanco
 
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin CoroutinesThreading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin CoroutinesLauren Yew
 
USENIX ATC 2017: Visualizing Performance with Flame Graphs
USENIX ATC 2017: Visualizing Performance with Flame GraphsUSENIX ATC 2017: Visualizing Performance with Flame Graphs
USENIX ATC 2017: Visualizing Performance with Flame GraphsBrendan Gregg
 
Qt multi threads
Qt multi threadsQt multi threads
Qt multi threadsYnon Perek
 
In-Depth Model/View with QML
In-Depth Model/View with QMLIn-Depth Model/View with QML
In-Depth Model/View with QMLICS
 

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
 
Coroutines in Kotlin
Coroutines in KotlinCoroutines in Kotlin
Coroutines in Kotlin
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
 
Kotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is coming
 
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
 
Kotlin coroutine - behind the scenes
Kotlin coroutine - behind the scenesKotlin coroutine - behind the scenes
Kotlin coroutine - behind the scenes
 
Java 8 - interfaces
Java 8 - interfacesJava 8 - interfaces
Java 8 - interfaces
 
Kotlin
KotlinKotlin
Kotlin
 
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
 
Add an interactive command line to your C++ application
Add an interactive command line to your C++ applicationAdd an interactive command line to your C++ application
Add an interactive command line to your C++ application
 
Improving app performance with Kotlin Coroutines
Improving app performance with Kotlin CoroutinesImproving app performance with Kotlin Coroutines
Improving app performance with Kotlin Coroutines
 
Coroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in PractiseCoroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in Practise
 
How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023
 
[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園
 
PHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object CalisthenicsPHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object Calisthenics
 
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin CoroutinesThreading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
 
USENIX ATC 2017: Visualizing Performance with Flame Graphs
USENIX ATC 2017: Visualizing Performance with Flame GraphsUSENIX ATC 2017: Visualizing Performance with Flame Graphs
USENIX ATC 2017: Visualizing Performance with Flame Graphs
 
Qt multi threads
Qt multi threadsQt multi threads
Qt multi threads
 
Kernel Debugging & Profiling
Kernel Debugging & ProfilingKernel Debugging & Profiling
Kernel Debugging & Profiling
 
In-Depth Model/View with QML
In-Depth Model/View with QMLIn-Depth Model/View with QML
In-Depth Model/View with QML
 

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
 
Introduction to Kotlin.pptx
Introduction to Kotlin.pptxIntroduction to Kotlin.pptx
Introduction to Kotlin.pptxAzharFauzan9
 
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
 
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
 
Introduction to Kotlin.pptx
Introduction to Kotlin.pptxIntroduction to Kotlin.pptx
Introduction to Kotlin.pptx
 
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
 
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

"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 

Recently uploaded (20)

"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 

Kotlin Coroutines Reloaded Presented at JVM Language Summit 2017