SlideShare a Scribd company logo
1 of 115
Download to read offline
TO B E CO N T I N U E D
K O T L I N C O U R O U T I N E S & P R O J E C T L O O M
A R T U R S KO W R O Ń S K I  
A N Y B O D Y K O T L I N ?
B Y J E T B R A I N S
2 0 1 1
K O T L I N 1 . 3
1 0 . 2 0 1 8
K O T L I N 1 . 3
1 0 . 2 0 1 8
COROUTINES
W I L L T E A C H Y O U H O W C O R O U T I N E S W O R K S
W O N ’ T T E A C H Y O U H O W - T O - C O R O U T I N E
SYNCHRONOUS
fun main(args : Array<String>) {
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
fun getLocationNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours
}
fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
SYNCHRONOUS
fun main(args : Array<String>) {
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
fun getLocationNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours
}
fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
SYNCHRONOUS
fun main(args : Array<String>) {
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
fun getLocationNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours
}
fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
SYNCHRONOUS
fun main(args : Array<String>) {
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
fun getLocationNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours
}
fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
SYNCHRONOUS
fun main(args : Array<String>) {
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
fun getLocationNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours
}
fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
CALLBACKS
fun main(args: Array<String>) {
getLocationsNearCoordinates("SW8 5YY, UK")
.success {location ->
val category = location.classification.category
if (category == "Store") {
getStoreDetails(location.id)
.success { locationWrapper ->
val openingHours = locationWrapper
.openingHours
.first()
.standardOpeningHours
println("Store Opening Hours: $openingHours")
}
}
if (category == "Office") {
payOfficeRent(location.id)
.success {
println("Invoice paid")
}
}
}
}
CALLBACKS
fun main(args: Array<String>) {
getLocationsNearCoordinates("SW8 5YY, UK")
.success {location ->
val category = location.classification.category
if (category == "Store") {
getStoreDetails(location.id)
.success { locationWrapper ->
val openingHours = locationWrapper
.openingHours
.first()
.standardOpeningHours
println("Store Opening Hours: $openingHours")
}
}
if (category == "Office") {
payOfficeRent(location.id)
.success {
println("Invoice paid")
}
}
}
}
CALLBACKS
fun main(args: Array<String>) {
getLocationsNearCoordinates("SW8 5YY, UK")
.success {location ->
val category = location.classification.category
if (category == "Store") {
getStoreDetails(location.id)
.success { locationWrapper ->
val openingHours = locationWrapper
.openingHours
.first()
.standardOpeningHours
println("Store Opening Hours: $openingHours")
}
}
if (category == "Office") {
payOfficeRent(location.id)
.success {
println("Invoice paid")
}
}
}
}
CALLBACKS
fun main(args: Array<String>) {
getLocationsNearCoordinates("SW8 5YY, UK")
.success {location ->
val category = location.classification.category
if (category == "Store") {
getStoreDetails(location.id)
.success { locationWrapper ->
val openingHours = locationWrapper
.openingHours
.first()
.standardOpeningHours
println("Store Opening Hours: $openingHours")
}
}
if (category == "Office") {
payOfficeRent(location.id)
.success {
println("Invoice paid")
}
}
}
}
CALLBACKS
fun main(args: Array<String>) {
getLocationsNearCoordinates("SW8 5YY, UK")
.success {location ->
val category = location.classification.category
if (category == "Store") {
getStoreDetails(location.id)
.success { locationWrapper ->
val openingHours = locationWrapper
.openingHours
.first()
.standardOpeningHours
println("Store Opening Hours: $openingHours")
}
}
if (category == "Office") {
payOfficeRent(location.id)
.success {
println("Invoice paid")
}
}
}
}
CALLBACKS
fun main(args: Array<String>) {
getLocationsNearCoordinates("SW8 5YY, UK")
.success {location ->
val category = location.classification.category
if (category == "Store") {
getStoreDetails(location.id)
.success { locationWrapper ->
val openingHours = locationWrapper
.openingHours
.first()
.standardOpeningHours
println("Store Opening Hours: $openingHours")
}
}
if (category == "Office") {
payOfficeRent(location.id)
.success {
println("Invoice paid")
}
}
}
}
A LT E R N AT I V E S
COMPUTABLE FUTURES
fun combineAsync(name1: String, name2: String): CompletableFuture<Image>{
val future1 = CompletableFuture.supplyAsync(name1-> ...)
val future2 = CompletableFuture.supplyAsync(name2-> ...)
return future1.thenCombine(future2){i1,i2 -> ...}
}
REACTIVE EXTENSIONS
Observable<String> getTitle() {
return Observable.from(titleList);
}
Observable.just("book1", "book2")
.flatMap(s -> getTitle())
.subscribe(l -> result += l);
assertTrue(result.equals("titletitle"));
C O M P L E X I T Y
E X C E P T I O N H A N D L I N G I S H A R D
O V E R A L L I T ’ S H A R D
IMPERATIVE CODE
fun main(args : Array<String>) {
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
fun getLocationNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours
}
fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
C O R O U T I N E S
1 9 5 8
1 9 6 3
NATIVE SUPPORT
NATIVE?
Roman Elizarov
IMPERATIVE CODE
fun main(args : Array<String>) {
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
fun getLocationNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours
}
fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
COROUTINE CODE
fun main() {
GlobalScope.launch {
val location = getLocationsNearKnownPostcode().first()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
runBlocking {
delay(2000L)
}
}
suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK")
}
suspend fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours.first().standardOpeningHours
}
suspend fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
COROUTINE CODE
fun main() {
GlobalScope.launch {
val location = getLocationsNearKnownPostcode().first()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
runBlocking {
delay(2000L)
}
}
suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK")
}
suspend fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours.first().standardOpeningHours
}
suspend fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
COROUTINE CODE
fun main() {
GlobalScope.launch {
val location = getLocationsNearKnownPostcode().first()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
runBlocking {
delay(2000L)
}
}
suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK")
}
suspend fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours.first().standardOpeningHours
}
suspend fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
COROUTINE CODE
fun main() {
GlobalScope.launch {
val location = getLocationsNearKnownPostcode().first()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
runBlocking {
delay(2000L)
}
}
suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK")
}
suspend fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours.first().standardOpeningHours
}
suspend fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
COROUTINE CODE
fun main() {
GlobalScope.launch {
val location = getLocationsNearKnownPostcode().first()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
runBlocking {
delay(2000L)
}
}
suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK")
}
suspend fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours.first().standardOpeningHours
}
suspend fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
BLOCKING
THREAD
Function 1
Function 2
SUSPEND
Suspension Point
THREAD
Function 1
Function 2
SUSPEND
THREAD
Coroutine 1
Function 2
getLocationsNearKnownPostcode getOpeningHours
Function 3
C O N T I N U AT I O N S
C O N T I N U AT I O N S
DIRECT STYLE CODE
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
ActionResult
Continuation
ACTION + RESULT & CONTINUATION
CONTINUATION PASSING STYLE
getLocationsNearKnownPostcode()
.success {location ->
val category = location.classification.category
}
Action
Result
CONTINUATION PASSING STYLE
getLocationsNearKnownPostcode()
.success {location ->
val category = location.classification.category
}
Action
Result
FANCY NAME FOR CALLBACKS
FROM KOTLIN FILE
suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK")
}
suspend fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours.first().standardOpeningHours
}
suspend fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
JVM BYTECODE
public final static getLocationsNearKnownPostcode(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@Lorg/jetbrains/annotations/Nullable;() // invisible
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
L0
LINENUMBER 33 L0
LDC "SW8 5YY, UK"
INVOKESTATIC TescoLocationAPIKt.getLocationsNearCoordinates (Ljava/lang/String;)Ljava/util/List;
ARETURN
L1
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x19
// signature (Ljava/lang/String;Lkotlin/coroutines/Continuation<Ljava/lang/Object;>;)Ljava/lang/Object;
// declaration: getOpeningHours(java.lang.String, kotlin.coroutines.Continuation<java.lang.Object>)
public final static getOpeningHours(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@Lorg/jetbrains/annotations/Nullable;() // invisible
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1
L0
LINENUMBER 37 L0
ALOAD 0
INVOKESTATIC TescoLocationAPIKt.getStoreDetails (Ljava/lang/String;)LLocationWrapper;
INVOKEVIRTUAL LocationWrapper.getOpeningHours ()[LLocationOpeningHours;
INVOKESTATIC kotlin/collections/ArraysKt.first ([Ljava/lang/Object;)Ljava/lang/Object;
CHECKCAST LocationOpeningHours
INVOKEVIRTUAL LocationOpeningHours.getStandardOpeningHours ()Ljava/util/HashMap;
ARETURN
L1
LOCALVARIABLE id Ljava/lang/String; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 2
// access flags 0x19
// signature (Ljava/lang/String;Lkotlin/coroutines/Continuation<Ljava/lang/Object;>;)Ljava/lang/Object;
// declaration: payInvoice(java.lang.String, kotlin.coroutines.Continuation<java.lang.Object>)
public final static payInvoice(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@Lorg/jetbrains/annotations/Nullable;() // invisible
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1
L0
LINENUMBER 41 L0
ALOAD 0
INVOKESTATIC TescoLocationAPIKt.payOfficeRent (Ljava/lang/String;)LLocationResult;
ARETURN
L1
LOCALVARIABLE id Ljava/lang/String; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 2
TAKE A LOOK
public final static payInvoice(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@Lorg/jetbrains/annotations/Nullable;() // invisible
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1
L0
LINENUMBER 41 L0
ALOAD 0
INVOKESTATIC TescoLocationAPIKt.payOfficeRent (Ljava/lang/String;)LLocationResult;
ARETURN
L1
LOCALVARIABLE id Ljava/lang/String; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 2
TAKE A LOOK
public final static payInvoice(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@Lorg/jetbrains/annotations/Nullable;() // invisible
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1
L0
LINENUMBER 41 L0
ALOAD 0
INVOKESTATIC TescoLocationAPIKt.payOfficeRent (Ljava/lang/String;)LLocationResult;
ARETURN
L1
LOCALVARIABLE id Ljava/lang/String; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 2
suspend fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
TAKE A LOOK
public final static payInvoice(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@Lorg/jetbrains/annotations/Nullable;() // invisible
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1
L0
LINENUMBER 41 L0
ALOAD 0
INVOKESTATIC TescoLocationAPIKt.payOfficeRent (Ljava/lang/String;)LLocationResult;
ARETURN
L1
LOCALVARIABLE id Ljava/lang/String; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 2
suspend fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
CONTINUATION INTERFACE
public interface Continuation<in T> {
public val context: CoroutineContext
public fun resumeWith(result: Result<T>)
}
TAKE A LOOK
public final static main()V
L0
LINENUMBER 13 L0
GETSTATIC kotlinx/coroutines/GlobalScope.INSTANCE : Lkotlinx/coroutines/GlobalScope;
CHECKCAST kotlinx/coroutines/CoroutineScope
ACONST_NULL
ACONST_NULL
NEW kotlinx/coroutines/guide/compose01/CoroutineCodeKt$main$1
DUP
ACONST_NULL
INVOKESPECIAL kotlinx/coroutines/guide/compose01/CoroutineCodeKt$main$1.<init> (Lkotlin/coroutines/Continuation;)V
CHECKCAST kotlin/jvm/functions/Function2
ICONST_3
ACONST_NULL
INVOKESTATIC kotlinx/coroutines/BuildersKt.launch$default (Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/
CoroutineStart;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
POP
L1
TAKE A LOOK
Coroutine
Stack
Operation 1
Operation 2
Operation 3
SUSPEND FUNCTION
Operation 1
Operation 2
Operation 3
Operation 4
Operation 5
SUSPEND FUNCTION
Operation 4
Operation 5
State
Operation 1
Operation 2
Operation 3
P R O J E C T L O O M
O P E R AT I N G S Y S T E M S 1 0 1
KERNEL SPACE THREADS
P R O C E S S E S
K E R N E L T H R E A D S
OS
PROCESS
PROCESS
THREAD
THREAD
THREAD
THREAD
KERNEL SPACE THREADS
C P U S C H E D U L E R
THREAD
Instruction 1
Instruction 2
Instruction 3
Instruction 4
THREAD
Continuation
OS
C P U S H E D U L E R
THREAD
THREAD
Instruction 1
Instruction 2
Instruction 3
Instruction 4
USER/KERNEL SPACE BORDER
CPU SHEDULER JVM
CONTEXT SWITCH
P R O J E C T M E T R O P O L I S
P R O J E C T VA L H A L L A
P R O J E C T PA N A M A
P R O J E C T A M B E R
P R O J E C T L O O M
USER/KERNEL SPACE BORDER
CPU SCHEDULER JVM
FORKJOINSCHEDULER
THREAD
THREAD
THREAD
USER/KERNEL SPACE BORDER
CPU SCHEDULER JVM
FORKJOINSCHEDULER
THREAD
Instruction 1
Instruction 2
Instruction 3
Instruction 4
Coroutines
CONTINUATION INTERFACE
public class Continuation implements Runnable {
public Continuation(ContinuationScope s, Runnable r)
public final void run()
public static void yield(ContinuationScope s)
public boolean isDone()
}
CONTINUATIONS
public static void main(String[] args){
ContinuationScope scope = new ContinuationScope("scope")
Continuation continuation = new Continuation(scope, () ->{
var location = getLocationsNearKnownPostcode()
var category = location.classification.category
if (category.equals(”Store”)) {
var openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category.equals(“Office")) {
payInvoice(location.id)
println("Invoice paid")
}
})
while (!continuation.isDone()) {
continuation.run();
}
}
public List<LocationWrapper> getLocationNearKnownPostcode() {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
public OpeningHours getOpeningHours(id: String) {
return getStoreDetails(id).openingHours
}
public void payInvoice(id: String) {
return payOfficeRent(id)
}
CONTINUATIONS
public static void main(String[] args){
ContinuationScope scope = new ContinuationScope("scope")
Continuation continuation = new Continuation(scope, () ->{
var location = getLocationsNearKnownPostcode()
var category = location.classification.category
if (category.equals(”Store”)) {
var openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category.equals(“Office")) {
payInvoice(location.id)
println("Invoice paid")
}
})
while (!continuation.isDone()) {
continuation.run();
}
}
public List<LocationWrapper> getLocationNearKnownPostcode() {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
public OpeningHours getOpeningHours(id: String) {
return getStoreDetails(id).openingHours
}
public void payInvoice(id: String) {
return payOfficeRent(id)
}
CONTINUATIONS
public static void main(String[] args){
ContinuationScope scope = new ContinuationScope("scope")
Continuation continuation = new Continuation(scope, () ->{
var location = getLocationsNearKnownPostcode()
var category = location.classification.category
if (category.equals(”Store”)) {
var openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category.equals(“Office")) {
payInvoice(location.id)
println("Invoice paid")
}
})
while (!continuation.isDone()) {
continuation.run();
}
}
public List<LocationWrapper> getLocationNearKnownPostcode() {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
public OpeningHours getOpeningHours(id: String) {
return getStoreDetails(id).openingHours
}
public void payInvoice(id: String) {
return payOfficeRent(id)
}
CONTINUATIONS
public static void main(String[] args){
ContinuationScope scope = new ContinuationScope("scope")
Continuation continuation = new Continuation(scope, () ->{
var location = getLocationsNearKnownPostcode()
var category = location.classification.category
if (category.equals(”Store”)) {
var openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category.equals(“Office")) {
payInvoice(location.id)
println("Invoice paid")
}
})
while (!continuation.isDone()) {
continuation.run();
}
}
public List<LocationWrapper> getLocationNearKnownPostcode() {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
public OpeningHours getOpeningHours(id: String) {
return getStoreDetails(id).openingHours
}
public void payInvoice(id: String) {
return payOfficeRent(id)
}
CONTINUATIONS
public static void main(String[] args){
ContinuationScope scope = new ContinuationScope("scope")
Continuation continuation = new Continuation(scope, () ->{
var location = getLocationsNearKnownPostcode()
var category = location.classification.category
if (category.equals(”Store”)) {
var openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category.equals(“Office")) {
payInvoice(location.id)
println("Invoice paid")
}
})
while (!continuation.isDone()) {
continuation.run();
}
}
public List<LocationWrapper> getLocationNearKnownPostcode() {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
public OpeningHours getOpeningHours(id: String) {
return getStoreDetails(id).openingHours
}
public void payInvoice(id: String) {
return payOfficeRent(id)
}
CONTINUATIONS
public static void main(String[] args){
ContinuationScope scope = new ContinuationScope("scope")
Continuation continuation = new Continuation(scope, () ->{
var location = getLocationsNearKnownPostcode()
var category = location.classification.category
if (category.equals(”Store”)) {
var openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category.equals(“Office")) {
payInvoice(location.id)
println("Invoice paid")
}
})
while (!continuation.isDone()) {
continuation.run();
}
}
public List<LocationWrapper> getLocationNearKnownPostcode() {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
public OpeningHours getOpeningHours(id: String) {
return getStoreDetails(id).openingHours
}
public void payInvoice(id: String) {
return payOfficeRent(id)
}
G E N E R AT O R S
ORIGINAL IDEA
SCHEDULER + CONTINUATION
Thread Fiber
Strand
NEW APPROACH
COPY AS MANY API AS POSSIBLE
Thread Fiber
G A I N S
T H R E A D S - ~ 1 M B
F I B E R - ~ 1 K B
N O M O R E T H R E A D P O O L S
L A C K O F C O M M O N A B S T R A C T I O N
D R A W B A C K S
C U R R E N T T H R E A D P R O B L E M
L A C K O F J N I S U P P O R T
C A N N O T S U S P E N D U N D E R L O C K
T H R E A D L O C A L
P R O C E S S O R / S C O P E L O C A L S
INITIAL INTERFACE
Fiber.schedule(Executor executor, Callable callable)
OBSOLETE
Fiber.schedule(Executor executor, Callable callable)
NEW INTERFACE
try (var scope = FiberScope.open()) {
var fiber1 = scope.schedule(task);
var fiber2 = scope.schedule(task);
}
S T R U C T U R E D C O N C U R R E N C Y
SYNCHRONOUS
fun main(args : Array<String>) {
val location = getLocationsNearKnownPostcode()
val category = location.classification.category
if (category == "Store") {
val openingHours = getOpeningHours(location.id)
println("Store Opening Hours: $openingHours")
}
if (category == "Office") {
payInvoice(location.id)
println("Invoice paid")
}
}
fun getLocationNearKnownPostcode(): List<LocationWrapper> {
return getLocationsNearCoordinates("SW8 5YY, UK”).first()
}
fun getOpeningHours(id: String): Any {
return getStoreDetails(id).openingHours
}
fun payInvoice(id: String): Any {
return payOfficeRent(id)
}
STRUCTURED CONCURRENCY
try (var scope = FiberScope.open(Option.PROPAGTE_CANCEL)) {
var fiber1 = scope.schedule(task);
var fiber2 = scope.schedule(task);
}
STRUCTURED CONCURRENCY
var deadline = Instant.now().plusSeconds(10);
try (var scope = FiberScope.open(deadline)) {
var fiber1 = scope.schedule(task);
var fiber2 = scope.schedule(task);
}
STRUCTURED CONCURRENCY
var deadline = Instant.now().plusSeconds(10);
try (var scope = FiberScope.open(deadline)) {
try (var scope2 = FiberScope.open()) {
scope2.schedule(() -> task());
}
}
STRUCTURED CONCURRENCY
var deadline = Instant.now().plusSeconds(10);
try (var scope = FiberScope.open(deadline)) {
try (var scope2 = FiberScope.open()) {
scope2.schedule(() -> task());
}
}
OBSOLETE (28.10.2019)
var deadline = Instant.now().plusSeconds(10);
try (var scope = FiberScope.open(deadline)) {
try (var scope2 = FiberScope.open()) {
scope2.schedule(() -> task());
}
}
D O N E W H E N I T ’ S D O N E
INSTALLATION STEPS
ONLY FOR JAVA => 11
hg clone https://github.com/openjdk/loom
cd loom
hg update -r fibers
sh configure
make images
OBSOLETE (23.08.2019)
hg clone https://github.com/openjdk/loom
cd loom
hg update -r fibers
sh configure
make images
P R O J E C T L O O M O N G I T
EARLY ACCESS BUILDS
2019/7/25
hg clone https://github.com/openjdk/loom
cd loom
hg update -r fibers
sh configure
make images
EARLY ACCESS BUILDS
2019/7/25
D AY B E F O R E M E E T U P
S O U R C E S
http://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html
https://www.youtube.com/watch?v=YrrUCSi72E8
KOTLINCONF 2017 - DEEP DIVE INTO COROUTINES ON JVM BY ROMAN ELIZAROV
https://www.youtube.com/watch?v=vbGbXUjlRyQ
PROJECT LOOM: FIBERS AND CONTINUATIONS FOR JAVA BY ALAN BATEMAN
PROJECT LOOM: FIBERS AND CONTINUATIONS FOR THE JAVA VIRTUAL MACHINE
GQ U E S T I O N S ?

More Related Content

What's hot

The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189Mahmoud Samir Fayed
 
Tablas, Codigos Base De Datos Excelsa
Tablas, Codigos Base De Datos ExcelsaTablas, Codigos Base De Datos Excelsa
Tablas, Codigos Base De Datos ExcelsaHéctor
 
Postgres rules
Postgres rulesPostgres rules
Postgres rulesgisborne
 
Erlang Introduction Bcberlin3
Erlang Introduction Bcberlin3Erlang Introduction Bcberlin3
Erlang Introduction Bcberlin3guesta3202
 
The Ring programming language version 1.2 book - Part 32 of 84
The Ring programming language version 1.2 book - Part 32 of 84The Ring programming language version 1.2 book - Part 32 of 84
The Ring programming language version 1.2 book - Part 32 of 84Mahmoud Samir Fayed
 
PHP cart
PHP cartPHP cart
PHP carttumetr1
 
redis überall
redis überallredis überall
redis überallzucaritask
 
Syntactic sugar in postgre sql
Syntactic sugar in postgre sqlSyntactic sugar in postgre sql
Syntactic sugar in postgre sqlAntony Abramchenko
 
Beautiful python - PyLadies
Beautiful python - PyLadiesBeautiful python - PyLadies
Beautiful python - PyLadiesAlicia Pérez
 
Syntactic sugar in Postgre SQL
Syntactic sugar in Postgre SQLSyntactic sugar in Postgre SQL
Syntactic sugar in Postgre SQLAntony Abramchenko
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresiMasters
 
PofEAA and SQLAlchemy
PofEAA and SQLAlchemyPofEAA and SQLAlchemy
PofEAA and SQLAlchemyInada Naoki
 
Anna Karenina (leon tolstoi)
Anna Karenina (leon tolstoi)Anna Karenina (leon tolstoi)
Anna Karenina (leon tolstoi)Rita Dinis
 
Revision c odesagain
Revision c odesagainRevision c odesagain
Revision c odesagainrex0721
 
Programa simulacion de ventas de aeropuerto
Programa simulacion de ventas de aeropuertoPrograma simulacion de ventas de aeropuerto
Programa simulacion de ventas de aeropuertoAnel Sosa
 
Introduccion administracion
Introduccion administracionIntroduccion administracion
Introduccion administracionMARSHY LABK
 

What's hot (17)

The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189
 
Tablas, Codigos Base De Datos Excelsa
Tablas, Codigos Base De Datos ExcelsaTablas, Codigos Base De Datos Excelsa
Tablas, Codigos Base De Datos Excelsa
 
Postgres rules
Postgres rulesPostgres rules
Postgres rules
 
Erlang Introduction Bcberlin3
Erlang Introduction Bcberlin3Erlang Introduction Bcberlin3
Erlang Introduction Bcberlin3
 
The Ring programming language version 1.2 book - Part 32 of 84
The Ring programming language version 1.2 book - Part 32 of 84The Ring programming language version 1.2 book - Part 32 of 84
The Ring programming language version 1.2 book - Part 32 of 84
 
PHP cart
PHP cartPHP cart
PHP cart
 
redis überall
redis überallredis überall
redis überall
 
Syntactic sugar in postgre sql
Syntactic sugar in postgre sqlSyntactic sugar in postgre sql
Syntactic sugar in postgre sql
 
Zadania z rozwiazaniami - powtórzenie funkcji kwadratowej na poziomie podstaw...
Zadania z rozwiazaniami - powtórzenie funkcji kwadratowej na poziomie podstaw...Zadania z rozwiazaniami - powtórzenie funkcji kwadratowej na poziomie podstaw...
Zadania z rozwiazaniami - powtórzenie funkcji kwadratowej na poziomie podstaw...
 
Beautiful python - PyLadies
Beautiful python - PyLadiesBeautiful python - PyLadies
Beautiful python - PyLadies
 
Syntactic sugar in Postgre SQL
Syntactic sugar in Postgre SQLSyntactic sugar in Postgre SQL
Syntactic sugar in Postgre SQL
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan Soares
 
PofEAA and SQLAlchemy
PofEAA and SQLAlchemyPofEAA and SQLAlchemy
PofEAA and SQLAlchemy
 
Anna Karenina (leon tolstoi)
Anna Karenina (leon tolstoi)Anna Karenina (leon tolstoi)
Anna Karenina (leon tolstoi)
 
Revision c odesagain
Revision c odesagainRevision c odesagain
Revision c odesagain
 
Programa simulacion de ventas de aeropuerto
Programa simulacion de ventas de aeropuertoPrograma simulacion de ventas de aeropuerto
Programa simulacion de ventas de aeropuerto
 
Introduccion administracion
Introduccion administracionIntroduccion administracion
Introduccion administracion
 

Similar to Ciąg dalszy nastąpi - o wielowątkowości, Projekcie Loom i kotlinowych Korutynach

[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...Mateusz Zalewski
 
ES6 patterns in the wild
ES6 patterns in the wildES6 patterns in the wild
ES6 patterns in the wildJoe Morgan
 
Empathic Programming - How to write comprehensible code
Empathic Programming - How to write comprehensible codeEmpathic Programming - How to write comprehensible code
Empathic Programming - How to write comprehensible codeMario Gleichmann
 
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze..."Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...Mateusz Zalewski
 
Less ismorewithcoffeescript webdirectionsfeb2012
Less ismorewithcoffeescript webdirectionsfeb2012Less ismorewithcoffeescript webdirectionsfeb2012
Less ismorewithcoffeescript webdirectionsfeb2012Jo Cranford
 
A swift introduction to Swift
A swift introduction to SwiftA swift introduction to Swift
A swift introduction to SwiftGiordano Scalzo
 
Simple design/programming nuggets
Simple design/programming nuggetsSimple design/programming nuggets
Simple design/programming nuggetsVivek Singh
 
Hitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional ProgrammingHitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional ProgrammingSergey Shishkin
 
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기Suyeol Jeon
 
Classic Games Development with Drools
Classic Games Development with DroolsClassic Games Development with Drools
Classic Games Development with DroolsMark Proctor
 
Tips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET ApplicationTips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET ApplicationJoni
 
06 Map Reduce
06 Map Reduce06 Map Reduce
06 Map Reducecrgwbr
 
Tactical DDD patterns in Go
Tactical DDD patterns in GoTactical DDD patterns in Go
Tactical DDD patterns in GoRobert Laszczak
 

Similar to Ciąg dalszy nastąpi - o wielowątkowości, Projekcie Loom i kotlinowych Korutynach (20)

[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
 
ES6 patterns in the wild
ES6 patterns in the wildES6 patterns in the wild
ES6 patterns in the wild
 
Benefits of Kotlin
Benefits of KotlinBenefits of Kotlin
Benefits of Kotlin
 
Empathic Programming - How to write comprehensible code
Empathic Programming - How to write comprehensible codeEmpathic Programming - How to write comprehensible code
Empathic Programming - How to write comprehensible code
 
Swift Study #2
Swift Study #2Swift Study #2
Swift Study #2
 
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze..."Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
 
Less ismorewithcoffeescript webdirectionsfeb2012
Less ismorewithcoffeescript webdirectionsfeb2012Less ismorewithcoffeescript webdirectionsfeb2012
Less ismorewithcoffeescript webdirectionsfeb2012
 
Perl6 grammars
Perl6 grammarsPerl6 grammars
Perl6 grammars
 
Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015
 
A swift introduction to Swift
A swift introduction to SwiftA swift introduction to Swift
A swift introduction to Swift
 
Miracle of std lib
Miracle of std libMiracle of std lib
Miracle of std lib
 
Simple design/programming nuggets
Simple design/programming nuggetsSimple design/programming nuggets
Simple design/programming nuggets
 
Neo4 J
Neo4 J Neo4 J
Neo4 J
 
Hitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional ProgrammingHitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional Programming
 
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
 
Classic Games Development with Drools
Classic Games Development with DroolsClassic Games Development with Drools
Classic Games Development with Drools
 
Tips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET ApplicationTips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET Application
 
Elegant objects
Elegant objectsElegant objects
Elegant objects
 
06 Map Reduce
06 Map Reduce06 Map Reduce
06 Map Reduce
 
Tactical DDD patterns in Go
Tactical DDD patterns in GoTactical DDD patterns in Go
Tactical DDD patterns in Go
 

More from Artur Skowroński

The State of the Green IT at the beginning of 2024
The State of the Green IT at the beginning of 2024The State of the Green IT at the beginning of 2024
The State of the Green IT at the beginning of 2024Artur Skowroński
 
My chcemy grać w Zielone! Czyli stan świata Green Technology końcówką 2023
My chcemy grać w Zielone! Czyli stan świata Green Technology końcówką 2023My chcemy grać w Zielone! Czyli stan świata Green Technology końcówką 2023
My chcemy grać w Zielone! Czyli stan świata Green Technology końcówką 2023Artur Skowroński
 
GraalVM, CRaC, Leyden and friends
GraalVM, CRaC, Leyden and friendsGraalVM, CRaC, Leyden and friends
GraalVM, CRaC, Leyden and friendsArtur Skowroński
 
Od Czarnoksiężnik z krainy Oz do modeli na produkcji
Od Czarnoksiężnik z krainy Oz do modeli na produkcjiOd Czarnoksiężnik z krainy Oz do modeli na produkcji
Od Czarnoksiężnik z krainy Oz do modeli na produkcjiArtur Skowroński
 
JVM Iceberg... we need to go deeper
JVM Iceberg... we need to go deeperJVM Iceberg... we need to go deeper
JVM Iceberg... we need to go deeperArtur Skowroński
 
JVM Iceberg... we need to go deeper
JVM Iceberg... we need to go deeperJVM Iceberg... we need to go deeper
JVM Iceberg... we need to go deeperArtur Skowroński
 
Panie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
Panie, kto tu Panu tak ... - czyli porozmawiajmy o LegacyPanie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
Panie, kto tu Panu tak ... - czyli porozmawiajmy o LegacyArtur Skowroński
 
Panie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
Panie, kto tu Panu tak ... - czyli porozmawiajmy o LegacyPanie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
Panie, kto tu Panu tak ... - czyli porozmawiajmy o LegacyArtur Skowroński
 
Artur Skowroński – Ten Typ tak ma - O systemach typów na przykładzie TypeScri...
Artur Skowroński – Ten Typ tak ma - O systemach typów na przykładzie TypeScri...Artur Skowroński – Ten Typ tak ma - O systemach typów na przykładzie TypeScri...
Artur Skowroński – Ten Typ tak ma - O systemach typów na przykładzie TypeScri...Artur Skowroński
 
Ten Typ tak ma - O systemach typów na przykładzie TypeScript’a
Ten Typ tak ma - O systemach typów na przykładzie TypeScript’aTen Typ tak ma - O systemach typów na przykładzie TypeScript’a
Ten Typ tak ma - O systemach typów na przykładzie TypeScript’aArtur Skowroński
 
Type Systems on the example of TypeScript
Type Systems on the example of TypeScriptType Systems on the example of TypeScript
Type Systems on the example of TypeScriptArtur Skowroński
 
Google Assistant po polsku - developerski punkt widzenia
Google Assistant po polsku - developerski punkt widzeniaGoogle Assistant po polsku - developerski punkt widzenia
Google Assistant po polsku - developerski punkt widzeniaArtur Skowroński
 
Google Assistant & Alexa - Asystenci głosowi: możliwości, podobieństwa, różnice
Google Assistant & Alexa - Asystenci głosowi: możliwości, podobieństwa, różniceGoogle Assistant & Alexa - Asystenci głosowi: możliwości, podobieństwa, różnice
Google Assistant & Alexa - Asystenci głosowi: możliwości, podobieństwa, różniceArtur Skowroński
 
Blockchain: Developer's Perspective (Java Edition)
Blockchain: Developer's Perspective (Java Edition)Blockchain: Developer's Perspective (Java Edition)
Blockchain: Developer's Perspective (Java Edition)Artur Skowroński
 
Blockchain: Developer Perspective
Blockchain: Developer PerspectiveBlockchain: Developer Perspective
Blockchain: Developer PerspectiveArtur Skowroński
 
Alexa, nice to meet(js) you!
Alexa, nice to meet(js) you!Alexa, nice to meet(js) you!
Alexa, nice to meet(js) you!Artur Skowroński
 
Change Detection Anno Domini 2016
Change Detection Anno Domini 2016Change Detection Anno Domini 2016
Change Detection Anno Domini 2016Artur Skowroński
 
Embracing change - how to introduce Clojure into your company technology stac...
Embracing change - how to introduce Clojure into your company technology stac...Embracing change - how to introduce Clojure into your company technology stac...
Embracing change - how to introduce Clojure into your company technology stac...Artur Skowroński
 
Scala.js - yet another what..?
Scala.js - yet another what..?Scala.js - yet another what..?
Scala.js - yet another what..?Artur Skowroński
 

More from Artur Skowroński (20)

The State of the Green IT at the beginning of 2024
The State of the Green IT at the beginning of 2024The State of the Green IT at the beginning of 2024
The State of the Green IT at the beginning of 2024
 
My chcemy grać w Zielone! Czyli stan świata Green Technology końcówką 2023
My chcemy grać w Zielone! Czyli stan świata Green Technology końcówką 2023My chcemy grać w Zielone! Czyli stan świata Green Technology końcówką 2023
My chcemy grać w Zielone! Czyli stan świata Green Technology końcówką 2023
 
GraalVM, CRaC, Leyden and friends
GraalVM, CRaC, Leyden and friendsGraalVM, CRaC, Leyden and friends
GraalVM, CRaC, Leyden and friends
 
Od Czarnoksiężnik z krainy Oz do modeli na produkcji
Od Czarnoksiężnik z krainy Oz do modeli na produkcjiOd Czarnoksiężnik z krainy Oz do modeli na produkcji
Od Czarnoksiężnik z krainy Oz do modeli na produkcji
 
JVM Iceberg... we need to go deeper
JVM Iceberg... we need to go deeperJVM Iceberg... we need to go deeper
JVM Iceberg... we need to go deeper
 
JVM Iceberg... we need to go deeper
JVM Iceberg... we need to go deeperJVM Iceberg... we need to go deeper
JVM Iceberg... we need to go deeper
 
Panie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
Panie, kto tu Panu tak ... - czyli porozmawiajmy o LegacyPanie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
Panie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
 
Panie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
Panie, kto tu Panu tak ... - czyli porozmawiajmy o LegacyPanie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
Panie, kto tu Panu tak ... - czyli porozmawiajmy o Legacy
 
Artur Skowroński – Ten Typ tak ma - O systemach typów na przykładzie TypeScri...
Artur Skowroński – Ten Typ tak ma - O systemach typów na przykładzie TypeScri...Artur Skowroński – Ten Typ tak ma - O systemach typów na przykładzie TypeScri...
Artur Skowroński – Ten Typ tak ma - O systemach typów na przykładzie TypeScri...
 
Ten Typ tak ma - O systemach typów na przykładzie TypeScript’a
Ten Typ tak ma - O systemach typów na przykładzie TypeScript’aTen Typ tak ma - O systemach typów na przykładzie TypeScript’a
Ten Typ tak ma - O systemach typów na przykładzie TypeScript’a
 
Type Systems on the example of TypeScript
Type Systems on the example of TypeScriptType Systems on the example of TypeScript
Type Systems on the example of TypeScript
 
Google Assistant po polsku - developerski punkt widzenia
Google Assistant po polsku - developerski punkt widzeniaGoogle Assistant po polsku - developerski punkt widzenia
Google Assistant po polsku - developerski punkt widzenia
 
Google Assistant & Alexa - Asystenci głosowi: możliwości, podobieństwa, różnice
Google Assistant & Alexa - Asystenci głosowi: możliwości, podobieństwa, różniceGoogle Assistant & Alexa - Asystenci głosowi: możliwości, podobieństwa, różnice
Google Assistant & Alexa - Asystenci głosowi: możliwości, podobieństwa, różnice
 
Blockchain: Developer's Perspective (Java Edition)
Blockchain: Developer's Perspective (Java Edition)Blockchain: Developer's Perspective (Java Edition)
Blockchain: Developer's Perspective (Java Edition)
 
Blockchain: Developer Perspective
Blockchain: Developer PerspectiveBlockchain: Developer Perspective
Blockchain: Developer Perspective
 
Alexa, nice to meet you!
Alexa, nice to meet you! Alexa, nice to meet you!
Alexa, nice to meet you!
 
Alexa, nice to meet(js) you!
Alexa, nice to meet(js) you!Alexa, nice to meet(js) you!
Alexa, nice to meet(js) you!
 
Change Detection Anno Domini 2016
Change Detection Anno Domini 2016Change Detection Anno Domini 2016
Change Detection Anno Domini 2016
 
Embracing change - how to introduce Clojure into your company technology stac...
Embracing change - how to introduce Clojure into your company technology stac...Embracing change - how to introduce Clojure into your company technology stac...
Embracing change - how to introduce Clojure into your company technology stac...
 
Scala.js - yet another what..?
Scala.js - yet another what..?Scala.js - yet another what..?
Scala.js - yet another what..?
 

Recently uploaded

A brief look at visionOS - How to develop app on Apple's Vision Pro
A brief look at visionOS - How to develop app on Apple's Vision ProA brief look at visionOS - How to develop app on Apple's Vision Pro
A brief look at visionOS - How to develop app on Apple's Vision ProRay Yuan Liu
 
Introduction to Artificial Intelligence: Intelligent Agents, State Space Sear...
Introduction to Artificial Intelligence: Intelligent Agents, State Space Sear...Introduction to Artificial Intelligence: Intelligent Agents, State Space Sear...
Introduction to Artificial Intelligence: Intelligent Agents, State Space Sear...shreenathji26
 
Javier_Fernandez_CARS_workshop_presentation.pptx
Javier_Fernandez_CARS_workshop_presentation.pptxJavier_Fernandez_CARS_workshop_presentation.pptx
Javier_Fernandez_CARS_workshop_presentation.pptxJavier Fernández Muñoz
 
Indian Tradition, Culture & Societies.pdf
Indian Tradition, Culture & Societies.pdfIndian Tradition, Culture & Societies.pdf
Indian Tradition, Culture & Societies.pdfalokitpathak01
 
Madani.store - Planning - Interview Questions
Madani.store - Planning - Interview QuestionsMadani.store - Planning - Interview Questions
Madani.store - Planning - Interview QuestionsKarim Gaber
 
Ece technical seminar topic for under graduate.pptx
Ece technical seminar topic for under graduate.pptxEce technical seminar topic for under graduate.pptx
Ece technical seminar topic for under graduate.pptxArjunPLinekaje
 
ADM100 Running Book for sap basis domain study
ADM100 Running Book for sap basis domain studyADM100 Running Book for sap basis domain study
ADM100 Running Book for sap basis domain studydhruvamdhruvil123
 
input buffering in lexical analysis in CD
input buffering in lexical analysis in CDinput buffering in lexical analysis in CD
input buffering in lexical analysis in CDHeadOfDepartmentComp1
 
Network Enhancements on BitVisor for BitVisor Summit 12
Network Enhancements on BitVisor for BitVisor Summit 12Network Enhancements on BitVisor for BitVisor Summit 12
Network Enhancements on BitVisor for BitVisor Summit 12cjchen22
 
AI Powered Ecover creator that creates everything that you want
AI Powered Ecover creator that creates everything that you wantAI Powered Ecover creator that creates everything that you want
AI Powered Ecover creator that creates everything that you wantsuja868966
 
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.elesangwon
 
FUNCTIONAL AND NON FUNCTIONAL REQUIREMENT
FUNCTIONAL AND NON FUNCTIONAL REQUIREMENTFUNCTIONAL AND NON FUNCTIONAL REQUIREMENT
FUNCTIONAL AND NON FUNCTIONAL REQUIREMENTSneha Padhiar
 
Analysis and Evaluation of Dal Lake Biomass for Conversion to Fuel/Green fert...
Analysis and Evaluation of Dal Lake Biomass for Conversion to Fuel/Green fert...Analysis and Evaluation of Dal Lake Biomass for Conversion to Fuel/Green fert...
Analysis and Evaluation of Dal Lake Biomass for Conversion to Fuel/Green fert...arifengg7
 
Introduction of Object Oriented Programming Language using Java. .pptx
Introduction of Object Oriented Programming Language using Java. .pptxIntroduction of Object Oriented Programming Language using Java. .pptx
Introduction of Object Oriented Programming Language using Java. .pptxPoonam60376
 
Guardians of E-Commerce: Harnessing NLP and Machine Learning Approaches for A...
Guardians of E-Commerce: Harnessing NLP and Machine Learning Approaches for A...Guardians of E-Commerce: Harnessing NLP and Machine Learning Approaches for A...
Guardians of E-Commerce: Harnessing NLP and Machine Learning Approaches for A...IJAEMSJORNAL
 
Plastifloor Park Deck Waterproofing System_Flyer
Plastifloor Park Deck Waterproofing System_FlyerPlastifloor Park Deck Waterproofing System_Flyer
Plastifloor Park Deck Waterproofing System_FlyerPlasti-Chemie GmbH
 
Cost estimation approach: FP to COCOMO scenario based question
Cost estimation approach: FP to COCOMO scenario based questionCost estimation approach: FP to COCOMO scenario based question
Cost estimation approach: FP to COCOMO scenario based questionSneha Padhiar
 
applications of diffrentiability in real life.pptx
applications of diffrentiability in real life.pptxapplications of diffrentiability in real life.pptx
applications of diffrentiability in real life.pptxananditam30
 
Design and Analysis of Algorithms Lecture Notes
Design and Analysis of Algorithms Lecture NotesDesign and Analysis of Algorithms Lecture Notes
Design and Analysis of Algorithms Lecture NotesSreedhar Chowdam
 

Recently uploaded (20)

A brief look at visionOS - How to develop app on Apple's Vision Pro
A brief look at visionOS - How to develop app on Apple's Vision ProA brief look at visionOS - How to develop app on Apple's Vision Pro
A brief look at visionOS - How to develop app on Apple's Vision Pro
 
Introduction to Artificial Intelligence: Intelligent Agents, State Space Sear...
Introduction to Artificial Intelligence: Intelligent Agents, State Space Sear...Introduction to Artificial Intelligence: Intelligent Agents, State Space Sear...
Introduction to Artificial Intelligence: Intelligent Agents, State Space Sear...
 
Javier_Fernandez_CARS_workshop_presentation.pptx
Javier_Fernandez_CARS_workshop_presentation.pptxJavier_Fernandez_CARS_workshop_presentation.pptx
Javier_Fernandez_CARS_workshop_presentation.pptx
 
Indian Tradition, Culture & Societies.pdf
Indian Tradition, Culture & Societies.pdfIndian Tradition, Culture & Societies.pdf
Indian Tradition, Culture & Societies.pdf
 
Madani.store - Planning - Interview Questions
Madani.store - Planning - Interview QuestionsMadani.store - Planning - Interview Questions
Madani.store - Planning - Interview Questions
 
Neometrix Optical Balloon Theodolite.pptx
Neometrix Optical Balloon Theodolite.pptxNeometrix Optical Balloon Theodolite.pptx
Neometrix Optical Balloon Theodolite.pptx
 
Ece technical seminar topic for under graduate.pptx
Ece technical seminar topic for under graduate.pptxEce technical seminar topic for under graduate.pptx
Ece technical seminar topic for under graduate.pptx
 
ADM100 Running Book for sap basis domain study
ADM100 Running Book for sap basis domain studyADM100 Running Book for sap basis domain study
ADM100 Running Book for sap basis domain study
 
input buffering in lexical analysis in CD
input buffering in lexical analysis in CDinput buffering in lexical analysis in CD
input buffering in lexical analysis in CD
 
Network Enhancements on BitVisor for BitVisor Summit 12
Network Enhancements on BitVisor for BitVisor Summit 12Network Enhancements on BitVisor for BitVisor Summit 12
Network Enhancements on BitVisor for BitVisor Summit 12
 
AI Powered Ecover creator that creates everything that you want
AI Powered Ecover creator that creates everything that you wantAI Powered Ecover creator that creates everything that you want
AI Powered Ecover creator that creates everything that you want
 
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.
 
FUNCTIONAL AND NON FUNCTIONAL REQUIREMENT
FUNCTIONAL AND NON FUNCTIONAL REQUIREMENTFUNCTIONAL AND NON FUNCTIONAL REQUIREMENT
FUNCTIONAL AND NON FUNCTIONAL REQUIREMENT
 
Analysis and Evaluation of Dal Lake Biomass for Conversion to Fuel/Green fert...
Analysis and Evaluation of Dal Lake Biomass for Conversion to Fuel/Green fert...Analysis and Evaluation of Dal Lake Biomass for Conversion to Fuel/Green fert...
Analysis and Evaluation of Dal Lake Biomass for Conversion to Fuel/Green fert...
 
Introduction of Object Oriented Programming Language using Java. .pptx
Introduction of Object Oriented Programming Language using Java. .pptxIntroduction of Object Oriented Programming Language using Java. .pptx
Introduction of Object Oriented Programming Language using Java. .pptx
 
Guardians of E-Commerce: Harnessing NLP and Machine Learning Approaches for A...
Guardians of E-Commerce: Harnessing NLP and Machine Learning Approaches for A...Guardians of E-Commerce: Harnessing NLP and Machine Learning Approaches for A...
Guardians of E-Commerce: Harnessing NLP and Machine Learning Approaches for A...
 
Plastifloor Park Deck Waterproofing System_Flyer
Plastifloor Park Deck Waterproofing System_FlyerPlastifloor Park Deck Waterproofing System_Flyer
Plastifloor Park Deck Waterproofing System_Flyer
 
Cost estimation approach: FP to COCOMO scenario based question
Cost estimation approach: FP to COCOMO scenario based questionCost estimation approach: FP to COCOMO scenario based question
Cost estimation approach: FP to COCOMO scenario based question
 
applications of diffrentiability in real life.pptx
applications of diffrentiability in real life.pptxapplications of diffrentiability in real life.pptx
applications of diffrentiability in real life.pptx
 
Design and Analysis of Algorithms Lecture Notes
Design and Analysis of Algorithms Lecture NotesDesign and Analysis of Algorithms Lecture Notes
Design and Analysis of Algorithms Lecture Notes
 

Ciąg dalszy nastąpi - o wielowątkowości, Projekcie Loom i kotlinowych Korutynach

  • 1. TO B E CO N T I N U E D K O T L I N C O U R O U T I N E S & P R O J E C T L O O M A R T U R S KO W R O Ń S K I  
  • 2.
  • 3.
  • 4. A N Y B O D Y K O T L I N ?
  • 5. B Y J E T B R A I N S 2 0 1 1
  • 6.
  • 7.
  • 8. K O T L I N 1 . 3 1 0 . 2 0 1 8
  • 9. K O T L I N 1 . 3 1 0 . 2 0 1 8 COROUTINES
  • 10. W I L L T E A C H Y O U H O W C O R O U T I N E S W O R K S
  • 11. W O N ’ T T E A C H Y O U H O W - T O - C O R O U T I N E
  • 12.
  • 13. SYNCHRONOUS fun main(args : Array<String>) { val location = getLocationsNearKnownPostcode() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } fun getLocationNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours } fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 14. SYNCHRONOUS fun main(args : Array<String>) { val location = getLocationsNearKnownPostcode() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } fun getLocationNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours } fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 15. SYNCHRONOUS fun main(args : Array<String>) { val location = getLocationsNearKnownPostcode() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } fun getLocationNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours } fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 16. SYNCHRONOUS fun main(args : Array<String>) { val location = getLocationsNearKnownPostcode() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } fun getLocationNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours } fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 17. SYNCHRONOUS fun main(args : Array<String>) { val location = getLocationsNearKnownPostcode() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } fun getLocationNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours } fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 18. CALLBACKS fun main(args: Array<String>) { getLocationsNearCoordinates("SW8 5YY, UK") .success {location -> val category = location.classification.category if (category == "Store") { getStoreDetails(location.id) .success { locationWrapper -> val openingHours = locationWrapper .openingHours .first() .standardOpeningHours println("Store Opening Hours: $openingHours") } } if (category == "Office") { payOfficeRent(location.id) .success { println("Invoice paid") } } } }
  • 19. CALLBACKS fun main(args: Array<String>) { getLocationsNearCoordinates("SW8 5YY, UK") .success {location -> val category = location.classification.category if (category == "Store") { getStoreDetails(location.id) .success { locationWrapper -> val openingHours = locationWrapper .openingHours .first() .standardOpeningHours println("Store Opening Hours: $openingHours") } } if (category == "Office") { payOfficeRent(location.id) .success { println("Invoice paid") } } } }
  • 20. CALLBACKS fun main(args: Array<String>) { getLocationsNearCoordinates("SW8 5YY, UK") .success {location -> val category = location.classification.category if (category == "Store") { getStoreDetails(location.id) .success { locationWrapper -> val openingHours = locationWrapper .openingHours .first() .standardOpeningHours println("Store Opening Hours: $openingHours") } } if (category == "Office") { payOfficeRent(location.id) .success { println("Invoice paid") } } } }
  • 21. CALLBACKS fun main(args: Array<String>) { getLocationsNearCoordinates("SW8 5YY, UK") .success {location -> val category = location.classification.category if (category == "Store") { getStoreDetails(location.id) .success { locationWrapper -> val openingHours = locationWrapper .openingHours .first() .standardOpeningHours println("Store Opening Hours: $openingHours") } } if (category == "Office") { payOfficeRent(location.id) .success { println("Invoice paid") } } } }
  • 22. CALLBACKS fun main(args: Array<String>) { getLocationsNearCoordinates("SW8 5YY, UK") .success {location -> val category = location.classification.category if (category == "Store") { getStoreDetails(location.id) .success { locationWrapper -> val openingHours = locationWrapper .openingHours .first() .standardOpeningHours println("Store Opening Hours: $openingHours") } } if (category == "Office") { payOfficeRent(location.id) .success { println("Invoice paid") } } } }
  • 23. CALLBACKS fun main(args: Array<String>) { getLocationsNearCoordinates("SW8 5YY, UK") .success {location -> val category = location.classification.category if (category == "Store") { getStoreDetails(location.id) .success { locationWrapper -> val openingHours = locationWrapper .openingHours .first() .standardOpeningHours println("Store Opening Hours: $openingHours") } } if (category == "Office") { payOfficeRent(location.id) .success { println("Invoice paid") } } } }
  • 24. A LT E R N AT I V E S
  • 25. COMPUTABLE FUTURES fun combineAsync(name1: String, name2: String): CompletableFuture<Image>{ val future1 = CompletableFuture.supplyAsync(name1-> ...) val future2 = CompletableFuture.supplyAsync(name2-> ...) return future1.thenCombine(future2){i1,i2 -> ...} }
  • 26. REACTIVE EXTENSIONS Observable<String> getTitle() { return Observable.from(titleList); } Observable.just("book1", "book2") .flatMap(s -> getTitle()) .subscribe(l -> result += l); assertTrue(result.equals("titletitle"));
  • 27. C O M P L E X I T Y
  • 28. E X C E P T I O N H A N D L I N G I S H A R D
  • 29. O V E R A L L I T ’ S H A R D
  • 30. IMPERATIVE CODE fun main(args : Array<String>) { val location = getLocationsNearKnownPostcode() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } fun getLocationNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours } fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 31. C O R O U T I N E S
  • 32. 1 9 5 8
  • 33.
  • 34. 1 9 6 3
  • 38. IMPERATIVE CODE fun main(args : Array<String>) { val location = getLocationsNearKnownPostcode() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } fun getLocationNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours } fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 39. COROUTINE CODE fun main() { GlobalScope.launch { val location = getLocationsNearKnownPostcode().first() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } runBlocking { delay(2000L) } } suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK") } suspend fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours.first().standardOpeningHours } suspend fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 40. COROUTINE CODE fun main() { GlobalScope.launch { val location = getLocationsNearKnownPostcode().first() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } runBlocking { delay(2000L) } } suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK") } suspend fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours.first().standardOpeningHours } suspend fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 41. COROUTINE CODE fun main() { GlobalScope.launch { val location = getLocationsNearKnownPostcode().first() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } runBlocking { delay(2000L) } } suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK") } suspend fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours.first().standardOpeningHours } suspend fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 42. COROUTINE CODE fun main() { GlobalScope.launch { val location = getLocationsNearKnownPostcode().first() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } runBlocking { delay(2000L) } } suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK") } suspend fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours.first().standardOpeningHours } suspend fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 43. COROUTINE CODE fun main() { GlobalScope.launch { val location = getLocationsNearKnownPostcode().first() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } runBlocking { delay(2000L) } } suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK") } suspend fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours.first().standardOpeningHours } suspend fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 47. C O N T I N U AT I O N S
  • 48. C O N T I N U AT I O N S
  • 49. DIRECT STYLE CODE val location = getLocationsNearKnownPostcode() val category = location.classification.category ActionResult Continuation ACTION + RESULT & CONTINUATION
  • 50. CONTINUATION PASSING STYLE getLocationsNearKnownPostcode() .success {location -> val category = location.classification.category } Action Result
  • 51. CONTINUATION PASSING STYLE getLocationsNearKnownPostcode() .success {location -> val category = location.classification.category } Action Result FANCY NAME FOR CALLBACKS
  • 52. FROM KOTLIN FILE suspend fun getLocationsNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK") } suspend fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours.first().standardOpeningHours } suspend fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 53. JVM BYTECODE public final static getLocationsNearKnownPostcode(Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @Lorg/jetbrains/annotations/Nullable;() // invisible @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 L0 LINENUMBER 33 L0 LDC "SW8 5YY, UK" INVOKESTATIC TescoLocationAPIKt.getLocationsNearCoordinates (Ljava/lang/String;)Ljava/util/List; ARETURN L1 MAXSTACK = 1 MAXLOCALS = 1 // access flags 0x19 // signature (Ljava/lang/String;Lkotlin/coroutines/Continuation<Ljava/lang/Object;>;)Ljava/lang/Object; // declaration: getOpeningHours(java.lang.String, kotlin.coroutines.Continuation<java.lang.Object>) public final static getOpeningHours(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @Lorg/jetbrains/annotations/Nullable;() // invisible @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1 L0 LINENUMBER 37 L0 ALOAD 0 INVOKESTATIC TescoLocationAPIKt.getStoreDetails (Ljava/lang/String;)LLocationWrapper; INVOKEVIRTUAL LocationWrapper.getOpeningHours ()[LLocationOpeningHours; INVOKESTATIC kotlin/collections/ArraysKt.first ([Ljava/lang/Object;)Ljava/lang/Object; CHECKCAST LocationOpeningHours INVOKEVIRTUAL LocationOpeningHours.getStandardOpeningHours ()Ljava/util/HashMap; ARETURN L1 LOCALVARIABLE id Ljava/lang/String; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 2 // access flags 0x19 // signature (Ljava/lang/String;Lkotlin/coroutines/Continuation<Ljava/lang/Object;>;)Ljava/lang/Object; // declaration: payInvoice(java.lang.String, kotlin.coroutines.Continuation<java.lang.Object>) public final static payInvoice(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @Lorg/jetbrains/annotations/Nullable;() // invisible @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1 L0 LINENUMBER 41 L0 ALOAD 0 INVOKESTATIC TescoLocationAPIKt.payOfficeRent (Ljava/lang/String;)LLocationResult; ARETURN L1 LOCALVARIABLE id Ljava/lang/String; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 2
  • 54. TAKE A LOOK public final static payInvoice(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @Lorg/jetbrains/annotations/Nullable;() // invisible @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1 L0 LINENUMBER 41 L0 ALOAD 0 INVOKESTATIC TescoLocationAPIKt.payOfficeRent (Ljava/lang/String;)LLocationResult; ARETURN L1 LOCALVARIABLE id Ljava/lang/String; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 2
  • 55. TAKE A LOOK public final static payInvoice(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @Lorg/jetbrains/annotations/Nullable;() // invisible @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1 L0 LINENUMBER 41 L0 ALOAD 0 INVOKESTATIC TescoLocationAPIKt.payOfficeRent (Ljava/lang/String;)LLocationResult; ARETURN L1 LOCALVARIABLE id Ljava/lang/String; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 2 suspend fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 56. TAKE A LOOK public final static payInvoice(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @Lorg/jetbrains/annotations/Nullable;() // invisible @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1 L0 LINENUMBER 41 L0 ALOAD 0 INVOKESTATIC TescoLocationAPIKt.payOfficeRent (Ljava/lang/String;)LLocationResult; ARETURN L1 LOCALVARIABLE id Ljava/lang/String; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 2 suspend fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 57. CONTINUATION INTERFACE public interface Continuation<in T> { public val context: CoroutineContext public fun resumeWith(result: Result<T>) }
  • 58. TAKE A LOOK public final static main()V L0 LINENUMBER 13 L0 GETSTATIC kotlinx/coroutines/GlobalScope.INSTANCE : Lkotlinx/coroutines/GlobalScope; CHECKCAST kotlinx/coroutines/CoroutineScope ACONST_NULL ACONST_NULL NEW kotlinx/coroutines/guide/compose01/CoroutineCodeKt$main$1 DUP ACONST_NULL INVOKESPECIAL kotlinx/coroutines/guide/compose01/CoroutineCodeKt$main$1.<init> (Lkotlin/coroutines/Continuation;)V CHECKCAST kotlin/jvm/functions/Function2 ICONST_3 ACONST_NULL INVOKESTATIC kotlinx/coroutines/BuildersKt.launch$default (Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/ CoroutineStart;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/Job; POP L1
  • 59. TAKE A LOOK Coroutine Stack Operation 1 Operation 2 Operation 3 SUSPEND FUNCTION Operation 1 Operation 2 Operation 3 Operation 4 Operation 5 SUSPEND FUNCTION Operation 4 Operation 5 State Operation 1 Operation 2 Operation 3
  • 60. P R O J E C T L O O M
  • 61. O P E R AT I N G S Y S T E M S 1 0 1
  • 62. KERNEL SPACE THREADS P R O C E S S E S K E R N E L T H R E A D S OS PROCESS PROCESS THREAD THREAD THREAD THREAD
  • 63. KERNEL SPACE THREADS C P U S C H E D U L E R THREAD Instruction 1 Instruction 2 Instruction 3 Instruction 4 THREAD Continuation
  • 64. OS C P U S H E D U L E R THREAD THREAD Instruction 1 Instruction 2 Instruction 3 Instruction 4
  • 65. USER/KERNEL SPACE BORDER CPU SHEDULER JVM CONTEXT SWITCH
  • 66. P R O J E C T M E T R O P O L I S
  • 67. P R O J E C T VA L H A L L A
  • 68. P R O J E C T PA N A M A
  • 69. P R O J E C T A M B E R
  • 70. P R O J E C T L O O M
  • 71. USER/KERNEL SPACE BORDER CPU SCHEDULER JVM FORKJOINSCHEDULER THREAD THREAD THREAD
  • 72. USER/KERNEL SPACE BORDER CPU SCHEDULER JVM FORKJOINSCHEDULER THREAD Instruction 1 Instruction 2 Instruction 3 Instruction 4 Coroutines
  • 73. CONTINUATION INTERFACE public class Continuation implements Runnable { public Continuation(ContinuationScope s, Runnable r) public final void run() public static void yield(ContinuationScope s) public boolean isDone() }
  • 74. CONTINUATIONS public static void main(String[] args){ ContinuationScope scope = new ContinuationScope("scope") Continuation continuation = new Continuation(scope, () ->{ var location = getLocationsNearKnownPostcode() var category = location.classification.category if (category.equals(”Store”)) { var openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category.equals(“Office")) { payInvoice(location.id) println("Invoice paid") } }) while (!continuation.isDone()) { continuation.run(); } } public List<LocationWrapper> getLocationNearKnownPostcode() { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } public OpeningHours getOpeningHours(id: String) { return getStoreDetails(id).openingHours } public void payInvoice(id: String) { return payOfficeRent(id) }
  • 75. CONTINUATIONS public static void main(String[] args){ ContinuationScope scope = new ContinuationScope("scope") Continuation continuation = new Continuation(scope, () ->{ var location = getLocationsNearKnownPostcode() var category = location.classification.category if (category.equals(”Store”)) { var openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category.equals(“Office")) { payInvoice(location.id) println("Invoice paid") } }) while (!continuation.isDone()) { continuation.run(); } } public List<LocationWrapper> getLocationNearKnownPostcode() { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } public OpeningHours getOpeningHours(id: String) { return getStoreDetails(id).openingHours } public void payInvoice(id: String) { return payOfficeRent(id) }
  • 76. CONTINUATIONS public static void main(String[] args){ ContinuationScope scope = new ContinuationScope("scope") Continuation continuation = new Continuation(scope, () ->{ var location = getLocationsNearKnownPostcode() var category = location.classification.category if (category.equals(”Store”)) { var openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category.equals(“Office")) { payInvoice(location.id) println("Invoice paid") } }) while (!continuation.isDone()) { continuation.run(); } } public List<LocationWrapper> getLocationNearKnownPostcode() { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } public OpeningHours getOpeningHours(id: String) { return getStoreDetails(id).openingHours } public void payInvoice(id: String) { return payOfficeRent(id) }
  • 77. CONTINUATIONS public static void main(String[] args){ ContinuationScope scope = new ContinuationScope("scope") Continuation continuation = new Continuation(scope, () ->{ var location = getLocationsNearKnownPostcode() var category = location.classification.category if (category.equals(”Store”)) { var openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category.equals(“Office")) { payInvoice(location.id) println("Invoice paid") } }) while (!continuation.isDone()) { continuation.run(); } } public List<LocationWrapper> getLocationNearKnownPostcode() { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } public OpeningHours getOpeningHours(id: String) { return getStoreDetails(id).openingHours } public void payInvoice(id: String) { return payOfficeRent(id) }
  • 78. CONTINUATIONS public static void main(String[] args){ ContinuationScope scope = new ContinuationScope("scope") Continuation continuation = new Continuation(scope, () ->{ var location = getLocationsNearKnownPostcode() var category = location.classification.category if (category.equals(”Store”)) { var openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category.equals(“Office")) { payInvoice(location.id) println("Invoice paid") } }) while (!continuation.isDone()) { continuation.run(); } } public List<LocationWrapper> getLocationNearKnownPostcode() { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } public OpeningHours getOpeningHours(id: String) { return getStoreDetails(id).openingHours } public void payInvoice(id: String) { return payOfficeRent(id) }
  • 79. CONTINUATIONS public static void main(String[] args){ ContinuationScope scope = new ContinuationScope("scope") Continuation continuation = new Continuation(scope, () ->{ var location = getLocationsNearKnownPostcode() var category = location.classification.category if (category.equals(”Store”)) { var openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category.equals(“Office")) { payInvoice(location.id) println("Invoice paid") } }) while (!continuation.isDone()) { continuation.run(); } } public List<LocationWrapper> getLocationNearKnownPostcode() { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } public OpeningHours getOpeningHours(id: String) { return getStoreDetails(id).openingHours } public void payInvoice(id: String) { return payOfficeRent(id) }
  • 80. G E N E R AT O R S
  • 81. ORIGINAL IDEA SCHEDULER + CONTINUATION Thread Fiber Strand
  • 82. NEW APPROACH COPY AS MANY API AS POSSIBLE Thread Fiber
  • 83. G A I N S
  • 84. T H R E A D S - ~ 1 M B
  • 85. F I B E R - ~ 1 K B
  • 86. N O M O R E T H R E A D P O O L S
  • 87. L A C K O F C O M M O N A B S T R A C T I O N
  • 88. D R A W B A C K S
  • 89. C U R R E N T T H R E A D P R O B L E M
  • 90. L A C K O F J N I S U P P O R T
  • 91. C A N N O T S U S P E N D U N D E R L O C K
  • 92. T H R E A D L O C A L
  • 93. P R O C E S S O R / S C O P E L O C A L S
  • 94.
  • 97. NEW INTERFACE try (var scope = FiberScope.open()) { var fiber1 = scope.schedule(task); var fiber2 = scope.schedule(task); }
  • 98. S T R U C T U R E D C O N C U R R E N C Y
  • 99. SYNCHRONOUS fun main(args : Array<String>) { val location = getLocationsNearKnownPostcode() val category = location.classification.category if (category == "Store") { val openingHours = getOpeningHours(location.id) println("Store Opening Hours: $openingHours") } if (category == "Office") { payInvoice(location.id) println("Invoice paid") } } fun getLocationNearKnownPostcode(): List<LocationWrapper> { return getLocationsNearCoordinates("SW8 5YY, UK”).first() } fun getOpeningHours(id: String): Any { return getStoreDetails(id).openingHours } fun payInvoice(id: String): Any { return payOfficeRent(id) }
  • 100. STRUCTURED CONCURRENCY try (var scope = FiberScope.open(Option.PROPAGTE_CANCEL)) { var fiber1 = scope.schedule(task); var fiber2 = scope.schedule(task); }
  • 101. STRUCTURED CONCURRENCY var deadline = Instant.now().plusSeconds(10); try (var scope = FiberScope.open(deadline)) { var fiber1 = scope.schedule(task); var fiber2 = scope.schedule(task); }
  • 102. STRUCTURED CONCURRENCY var deadline = Instant.now().plusSeconds(10); try (var scope = FiberScope.open(deadline)) { try (var scope2 = FiberScope.open()) { scope2.schedule(() -> task()); } }
  • 103. STRUCTURED CONCURRENCY var deadline = Instant.now().plusSeconds(10); try (var scope = FiberScope.open(deadline)) { try (var scope2 = FiberScope.open()) { scope2.schedule(() -> task()); } }
  • 104. OBSOLETE (28.10.2019) var deadline = Instant.now().plusSeconds(10); try (var scope = FiberScope.open(deadline)) { try (var scope2 = FiberScope.open()) { scope2.schedule(() -> task()); } }
  • 105. D O N E W H E N I T ’ S D O N E
  • 106. INSTALLATION STEPS ONLY FOR JAVA => 11 hg clone https://github.com/openjdk/loom cd loom hg update -r fibers sh configure make images
  • 107. OBSOLETE (23.08.2019) hg clone https://github.com/openjdk/loom cd loom hg update -r fibers sh configure make images
  • 108. P R O J E C T L O O M O N G I T
  • 109. EARLY ACCESS BUILDS 2019/7/25 hg clone https://github.com/openjdk/loom cd loom hg update -r fibers sh configure make images
  • 111. D AY B E F O R E M E E T U P
  • 112.
  • 113.
  • 114. S O U R C E S http://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html https://www.youtube.com/watch?v=YrrUCSi72E8 KOTLINCONF 2017 - DEEP DIVE INTO COROUTINES ON JVM BY ROMAN ELIZAROV https://www.youtube.com/watch?v=vbGbXUjlRyQ PROJECT LOOM: FIBERS AND CONTINUATIONS FOR JAVA BY ALAN BATEMAN PROJECT LOOM: FIBERS AND CONTINUATIONS FOR THE JAVA VIRTUAL MACHINE
  • 115. GQ U E S T I O N S ?