Algebraic Effects on the JVM Jonathan Immanuel Brachthuser - - PowerPoint PPT Presentation

algebraic effects on the jvm
SMART_READER_LITE
LIVE PREVIEW

Algebraic Effects on the JVM Jonathan Immanuel Brachthuser - - PowerPoint PPT Presentation

Effekt Algebraic Effects on the JVM Jonathan Immanuel Brachthuser Dagstuhl Seminar 18172 University of Tbingen, Germany Algebraic Effect Handlers go Mainstream github.com/b-studios/scala-effekt Effekt We developed algebraic


slide-1
SLIDE 1

Ξ Effekt

Algebraic Effects

  • n the JVM

Jonathan Immanuel Brachthäuser University of Tübingen, Germany

github.com/b-studios/scala-effekt

Dagstuhl Seminar 18172 Algebraic Effect Handlers go Mainstream

slide-2
SLIDE 2

Ξ Effekt

b-studios.de/scala-effekt

2

We developed algebraic effect libraries for

Ξ Scala Effekt Ξ JVM Effekt

slide-3
SLIDE 3

Ξ Effekt

b-studios.de/scala-effekt

00 3

Part I Effect Handlers as a Library for Scala

slide-4
SLIDE 4

Ξ Effekt

b-studios.de/scala-effekt

Key Specs: Scala Effekt

  • shallow embedding vs. deep embedding of handlers
  • "capability passing style"
  • shallow handlers vs. deep handlers
  • user defined effects ✔
  • dynamic effect instances ✔
  • modular and extensible effect signatures and handlers ✔
  • safety (capabiliKes can leak) ✘
  • user programs are wriMen in direct style ✘
  • performance: sKll (orders of magnitute) slower than primiKve effects ✘

4

slide-5
SLIDE 5

Ξ Effekt

b-studios.de/scala-effekt

00 5

How to Scala EffektUSE

slide-6
SLIDE 6

Ξ Effekt

b-studios.de/scala-effekt

00 6

val drunkFlip: String using Amb and Exc = for { caught ← flip() heads ← if (caught) flip() else raise("too drunk") } yield if (heads) "heads" else "tails"

Example: Drunk Coin Flipping

slide-7
SLIDE 7

Ξ Effekt

b-studios.de/scala-effekt val drunkFlip: String using Amb and Exc = for { caught ← flip() heads ← if (caught) flip() else raise("too drunk") } yield if (heads) "heads" else "tails"

00 7

flip() flip() raise("too drunk")

Effect OperaKons

SemanKcs of the operaKons is leP open

slide-8
SLIDE 8

Ξ Effekt

b-studios.de/scala-effekt val drunkFlip: String using Amb and Exc = for { caught ← flip() heads ← if (caught) flip() else raise("too drunk") } yield if (heads) "heads" else "tails"

00 7

flip() flip() raise("too drunk")

Effect OperaKons

SemanKcs of the operaKons is leP open

Amb Exc

Effect Signatures

Group effect operaKons in one type

slide-9
SLIDE 9

Ξ Effekt

b-studios.de/scala-effekt

8

val drunkFlip: String using Amb and Exc = for { caught ← flip() heads ← if (caught) flip() else raise("too drunk") } yield if (heads) "heads" else "tails" AmbList { ExcOption { drunkFlip } }
slide-10
SLIDE 10

Ξ Effekt

b-studios.de/scala-effekt

8

val drunkFlip: String using Amb and Exc = for { caught ← flip() heads ← if (caught) flip() else raise("too drunk") } yield if (heads) "heads" else "tails" AmbList { ExcOption { drunkFlip } }

Effect Handlers

Provide semanKcs to effect operaKons

slide-11
SLIDE 11

Ξ Effekt

b-studios.de/scala-effekt

9

val drunkFlip: String using Amb and Exc = for { caught ← flip() heads ← if (caught) flip() else raise("too drunk") } yield if (heads) "heads" else "tails" AmbList { ExcOption { drunkFlip } }
slide-12
SLIDE 12

Ξ Effekt

b-studios.de/scala-effekt > List(Some("heads"), Some("tails"), None)

9

val drunkFlip: String using Amb and Exc = for { caught ← flip() heads ← if (caught) flip() else raise("too drunk") } yield if (heads) "heads" else "tails" AmbList { ExcOption { drunkFlip } }
slide-13
SLIDE 13

Ξ Effekt

b-studios.de/scala-effekt > List(Some("heads"), Some("tails"), None)

9

val drunkFlip: String using Amb and Exc = for { caught ← flip() heads ← if (caught) flip() else raise("too drunk") } yield if (heads) "heads" else "tails" AmbList { ExcOption { drunkFlip } } ExcOption { AmbList { drunkFlip } }
slide-14
SLIDE 14

Ξ Effekt

b-studios.de/scala-effekt > List(Some("heads"), Some("tails"), None)

9

val drunkFlip: String using Amb and Exc = for { caught ← flip() heads ← if (caught) flip() else raise("too drunk") } yield if (heads) "heads" else "tails" AmbList { ExcOption { drunkFlip } } ExcOption { AmbList { drunkFlip } } > None
slide-15
SLIDE 15

Ξ Effekt

b-studios.de/scala-effekt

00 10

The role of

implicit

slide-16
SLIDE 16

Ξ Effekt

b-studios.de/scala-effekt

We were faced with the following three design quesKons:

Design Decisions - Scala Effekt

11

slide-17
SLIDE 17

Ξ Effekt

b-studios.de/scala-effekt

We were faced with the following three design quesKons:

  • 1. how to capture the context of effect operaKons? 


⟹ monadic implementaKon for mulK-prompt delimited conKnuaKons

Design Decisions - Scala Effekt

11

slide-18
SLIDE 18

Ξ Effekt

b-studios.de/scala-effekt

We were faced with the following three design quesKons:

  • 1. how to capture the context of effect operaKons? 


⟹ monadic implementaKon for mulK-prompt delimited conKnuaKons

Design Decisions - Scala Effekt

11

slide-19
SLIDE 19

Ξ Effekt

b-studios.de/scala-effekt

We were faced with the following three design quesKons:

  • 1. how to capture the context of effect operaKons? 


⟹ monadic implementaKon for mulK-prompt delimited conKnuaKons

  • 2. how should effect handlers provide semanOcs for effect operaKons?

⟹ shallow embedding of effect handlers

Design Decisions - Scala Effekt

11

slide-20
SLIDE 20

Ξ Effekt

b-studios.de/scala-effekt

We were faced with the following three design quesKons:

  • 1. how to capture the context of effect operaKons? 


⟹ monadic implementaKon for mulK-prompt delimited conKnuaKons

  • 2. how should effect handlers provide semanOcs for effect operaKons?

⟹ shallow embedding of effect handlers

  • 3. how to establish an effect typing discipline? 


⟹ capability passing style

Design Decisions - Scala Effekt

11

slide-21
SLIDE 21

Ξ Effekt

b-studios.de/scala-effekt

We were faced with the following three design quesKons:

  • 1. how to capture the context of effect operaKons? 


⟹ monadic implementaKon for mulK-prompt delimited conKnuaKons

  • 2. how should effect handlers provide semanOcs for effect operaKons?

⟹ shallow embedding of effect handlers

  • 3. how to establish an effect typing discipline? 


⟹ capability passing style For all three answers implicit funcOon types turned out to be a perfect fit!

Design Decisions - Scala Effekt

11

slide-22
SLIDE 22

Ξ Effekt

b-studios.de/scala-effekt

Implicit FuncOon Types

12

slide-23
SLIDE 23

Ξ Effekt

b-studios.de/scala-effekt def drunkFlip: String using Amb and Exc = for { caught ← flip() heads ← if (caught) flip() else raise("too drunk") } yield if (heads) "heads" else "tails"

Implicit FuncOon Types

12

slide-24
SLIDE 24

Ξ Effekt

b-studios.de/scala-effekt def drunkFlip: String using Amb and Exc = for { caught ← flip() heads ← if (caught) flip() else raise("too drunk") } yield if (heads) "heads" else "tails"

Implicit FuncOon Types

type using[A, E] = implicit Cap[E] ⟹ Control[A]

Library defined type aliases

12

slide-25
SLIDE 25

Ξ Effekt

b-studios.de/scala-effekt def drunkFlip: String using Amb and Exc = for { caught ← flip() heads ← if (caught) flip() else raise("too drunk") } yield if (heads) "heads" else "tails"

Implicit FuncOon Types

type and[A, E] = implicit Cap[E] ⟹ A type using[A, E] = implicit Cap[E] ⟹ Control[A]

Library defined type aliases

12

slide-26
SLIDE 26

Ξ Effekt

b-studios.de/scala-effekt

Making Capability Passing Explicit

def drunkFlip(amb: Cap[Amb], exc: Cap[Exc]): Control[String] = for { caught ← amb.handler.flip() heads ← if (caught) amb.handler.flip() 
 else exc.handler.raise("too drunk") } yield if (heads) "heads" else "tails"

Explicitly desugaring implicit funcKon types gives:

13

slide-27
SLIDE 27

Ξ Effekt

b-studios.de/scala-effekt

Making Capability Passing Explicit

def drunkFlip(amb: Cap[Amb], exc: Cap[Exc]): Control[String] = for { caught ← amb.handler.flip() heads ← if (caught) amb.handler.flip() 
 else exc.handler.raise("too drunk") } yield if (heads) "heads" else "tails"

Explicitly desugaring implicit funcKon types gives:

13

slide-28
SLIDE 28

Ξ Effekt

b-studios.de/scala-effekt

Making Capability Passing Explicit

AmbList { amb ⟹ ExcOption { exc ⟹ drunkFlip(amb, exc) } }

Handler create capabiliKes:

def drunkFlip(amb: Cap[Amb], exc: Cap[Exc]): Control[String] = for { caught ← amb.handler.flip() heads ← if (caught) amb.handler.flip() 
 else exc.handler.raise("too drunk") } yield if (heads) "heads" else "tails"

Explicitly desugaring implicit funcKon types gives:

13

slide-29
SLIDE 29

Ξ Effekt

b-studios.de/scala-effekt

CapabiliOes in Effekt

CapabiliKes Cap[E] encapsulate three different things:

14

slide-30
SLIDE 30

Ξ Effekt

b-studios.de/scala-effekt

CapabiliOes in Effekt

CapabiliKes Cap[E] encapsulate three different things:

  • 1. they contain a unique prompt marker that delimits the scope of the

conKnuaKon to be captured.

14

slide-31
SLIDE 31

Ξ Effekt

b-studios.de/scala-effekt

CapabiliOes in Effekt

CapabiliKes Cap[E] encapsulate three different things:

  • 1. they contain a unique prompt marker that delimits the scope of the

conKnuaKon to be captured.

  • 2. they contain the effect handler implementaOon to be passed down

(shallow embedding of handlers).

14

slide-32
SLIDE 32

Ξ Effekt

b-studios.de/scala-effekt

CapabiliOes in Effekt

CapabiliKes Cap[E] encapsulate three different things:

  • 1. they contain a unique prompt marker that delimits the scope of the

conKnuaKon to be captured.

  • 2. they contain the effect handler implementaOon to be passed down

(shallow embedding of handlers).

  • 3. they enKtle the holder of the capability to invoke effecQul operaOons


specified in effect signature E (effect typing discipline).

14

slide-33
SLIDE 33

Ξ Effekt

b-studios.de/scala-effekt

00 15

  • f effect handlers

shallow embedding

slide-34
SLIDE 34

Ξ Effekt

b-studios.de/scala-effekt

Calling an Effect OperaOon

16

slide-35
SLIDE 35

Ξ Effekt

b-studios.de/scala-effekt

Calling an Effect OperaOon

We can think of effect operaKons as uninterpreted constructors of an effect-language. An effec[ul program then could be represented as a tree of operaKons:

Op1(args…, res1 ⟹ Op2(args…, res2 ⟹ … Pure(value)))

16

slide-36
SLIDE 36

Ξ Effekt

b-studios.de/scala-effekt

Calling an Effect OperaOon

We can think of effect operaKons as uninterpreted constructors of an effect-language. An effec[ul program then could be represented as a tree of operaKons:

Op1(args…, res1 ⟹ Op2(args…, res2 ⟹ … Pure(value)))

16

we can write a recursive, paMern matching recursive interpreter to provide semanKcs to effec[ul operaKons. In PL terms: a deep embedding of effect operaKons.

slide-37
SLIDE 37

Ξ Effekt

b-studios.de/scala-effekt

Shallow Embedding of Effect Handlers

In Scala Effekt, effect operaKons are immediately called on effect handlers. Schema1cally:

handler.op1(args…, res1 ⟹ handler.op2(args…, res2 ⟹ …))

17

slide-38
SLIDE 38

Ξ Effekt

b-studios.de/scala-effekt

Shallow Embedding of Effect Handlers

In Scala Effekt, effect operaKons are immediately called on effect handlers. Schema1cally:

handler.op1(args…, res1 ⟹ handler.op2(args…, res2 ⟹ …))

17

Technical Insights

slide-39
SLIDE 39

Ξ Effekt

b-studios.de/scala-effekt

Shallow Embedding of Effect Handlers

In Scala Effekt, effect operaKons are immediately called on effect handlers. Schema1cally:

handler.op1(args…, res1 ⟹ handler.op2(args…, res2 ⟹ …))

17

Technical Insights (a) Shallow embedding of effect handlers simplifies typing –
 no GADTs are necessary!

slide-40
SLIDE 40

Ξ Effekt

b-studios.de/scala-effekt

Shallow Embedding of Effect Handlers

In Scala Effekt, effect operaKons are immediately called on effect handlers. Schema1cally:

handler.op1(args…, res1 ⟹ handler.op2(args…, res2 ⟹ …))

17

Technical Insights (a) Shallow embedding of effect handlers simplifies typing –
 no GADTs are necessary! (b) PaMern matching is replaced by dynamic dispatch – 
 benefits performance on the JVM.

slide-41
SLIDE 41

Ξ Effekt

b-studios.de/scala-effekt

Shallow Embedding of Effect Handlers

In Scala Effekt, effect operaKons are immediately called on effect handlers. Schema1cally:

handler.op1(args…, res1 ⟹ handler.op2(args…, res2 ⟹ …))

17

Technical Insights (a) Shallow embedding of effect handlers simplifies typing –
 no GADTs are necessary! (b) PaMern matching is replaced by dynamic dispatch – 
 benefits performance on the JVM. (c) Direct call to corresponding handler – no need to lookup handler.

slide-42
SLIDE 42

Ξ Effekt

b-studios.de/scala-effekt

18

Part II Algebraic Effects as Libraries for Java / JVM

slide-43
SLIDE 43

Ξ Effekt

b-studios.de/scala-effekt

Key Specs: JVM / Java Effekt

  • shallow embedding vs. deep embedding of handlers
  • "handler passing style"
  • shallow handlers vs. deep handlers
  • user defined effects ✔
  • dynamic effect instances ✔
  • modular and extensible effect signatures and handlers (✔)
  • safety (capabiliKes can leak) ✘
  • user programs are wriMen in direct style ✔
  • performance: compeKKve with JVM conKnuaKon libraries ✔

19

slide-44
SLIDE 44

Ξ Effekt

b-studios.de/scala-effekt

Key Specs: JVM / Java Effekt

  • shallow embedding vs. deep embedding of handlers
  • "handler passing style"
  • shallow handlers vs. deep handlers
  • user defined effects ✔
  • dynamic effect instances ✔
  • modular and extensible effect signatures and handlers (✔)
  • safety (capabiliKes can leak) ✘
  • user programs are wriMen in direct style ✔
  • performance: compeKKve with JVM conKnuaKon libraries ✔

19

slide-45
SLIDE 45

Ξ Effekt

b-studios.de/scala-effekt

Overview of JVM Effekt

  • Programs are wriMen in direct style, but CPS translated via bytecode transformaOon
  • Translated programs use a separate Stack interface for effec[ul frames
  • Delimited control is implemented as a library, implemenKng the Stack interface
  • We redesigned the algebraic effects library to only require simple generics
  • RestricOon: We only transform the terms, not types / signatures

20

slide-46
SLIDE 46

Ξ Effekt

b-studios.de/scala-effekt

21

For effec1ul methods, we maintain our own custom stack, which allows us to manipulate it (searching, slicing, copying).

Example.plain:27 Example.effectOp2:13 Example.plain:38 Example.effectOp1:5 Example.plain:29 Example.main:55 .plain:27 Effekt.run:13 .main:55

JVM Stack JVM Stack

.effectOp2:13 .effectOp1:5

Effekt Stack

Replacing the JVM Stack

slide-47
SLIDE 47

Ξ Effekt

b-studios.de/scala-effekt

00 22

String drunkFlip(Amb amb, Exc exc) throws Effects { if (amb.flip()) { return exc.raise("too drunk"); } else { return amb.flip() ? "heads" : "tails"; } }

Example: Drunk Coin Flipping

slide-48
SLIDE 48

Ξ Effekt

b-studios.de/scala-effekt

00 22

String drunkFlip(Amb amb, Exc exc) throws Effects { if (amb.flip()) { return exc.raise("too drunk"); } else { return amb.flip() ? "heads" : "tails"; } }

Example: Drunk Coin Flipping

interface Amb { boolean flip() throws Effects; } interface Exc { <A> A raise(String msg) throws Effects; }
slide-49
SLIDE 49

Ξ Effekt

b-studios.de/scala-effekt

00 23

Handling Effects

class AmbList<R> extends Handler<R, List<R>> implements Amb { List<R> pure(R r) { return Lists.singleton(r); } boolean flip() throws Effects { return use(k -> Lists.concat(k.resume(true), k.resume(false))); } } handle(new AmbList<Optional<String>>(), amb -> handle(new Maybe<String>(), exc -> drunkFlip(amb, exc))) > [Optional["heads"], Optional["tails"], Optional.empty]
slide-50
SLIDE 50

Ξ Effekt

b-studios.de/scala-effekt

00 24

Stateful / Parametrized Handlers

interface Reader<In> { In read() throws Effects; } class StringReader<R> extends Handler<R, R> implements Reader<Char> { final String input; int pos = 0; Char read() throws Effects { return input.charAt(pos++) } }
slide-51
SLIDE 51

Ξ Effekt

b-studios.de/scala-effekt

00 25

Stateful / Parametrized Handlers

interface Reader<In> { In read() throws Effects; } class StringReader<R> extends Handler<R, R> implements Reader<Char>, Stateful<Integer> { final String input; int pos = 0; Char read() throws Effects { return input.charAt(pos++) } Integer exportState() { return pos; } void importState(Integer n) { pos = n; } }
slide-52
SLIDE 52

Ξ Effekt

b-studios.de/scala-effekt

Design Decisions

  • EffecQul methods are marked with a special, checked excepKon Effects
  • Effect signatures are interfaces that contain effec[ul methods
  • Effect handlers are implementaKons of those interfaces.
  • Users need to manually follow the capability passing style.
  • Effect handlers can extend the library class Handler to capture the

conOnuaOon (but don't need to).

  • We use the handler instances as prompt markers.

26

slide-53
SLIDE 53

Ξ Effekt

b-studios.de/scala-effekt

Bytecode TransformaOon Example (CPS)

27

String drunkFlip(Amb amb, Exc exc) throws Effects { Effekt.push(() -> drunkFlip1(amb, exc)); amb.flip(); return null; }
slide-54
SLIDE 54

Ξ Effekt

b-studios.de/scala-effekt

Bytecode TransformaOon Example (CPS)

27

String drunkFlip(Amb amb, Exc exc) throws Effects { Effekt.push(() -> drunkFlip1(amb, exc)); amb.flip(); return null; } void drunkFlip1(Amb amb, Exc exc) throws Effects { boolean caught = Effekt.result(); if (Effekt.result()) { exc.raise("too drunk"); } else { Effekt.push(() -> drunkFlip2(amb, exc, caught)); amb.flip(); } }
slide-55
SLIDE 55

Ξ Effekt

b-studios.de/scala-effekt

Bytecode TransformaOon Example (CPS)

27

String drunkFlip(Amb amb, Exc exc) throws Effects { Effekt.push(() -> drunkFlip1(amb, exc)); amb.flip(); return null; } void drunkFlip1(Amb amb, Exc exc) throws Effects { boolean caught = Effekt.result(); if (Effekt.result()) { exc.raise("too drunk"); } else { Effekt.push(() -> drunkFlip2(amb, exc, caught)); amb.flip(); } } void drunkFlip2(Amb amb, Exc exc, boolean caught) throws Effects { Effekt.returnWith(Effekt.result() ? "heads" : "tails"); }
slide-56
SLIDE 56

Ξ Effekt

b-studios.de/scala-effekt

AlternaOve TransformaOons

28

CPS

Effekt.push(() -> drunkFlip1(amb, exc)); amb.flip(); return DUMMY;
slide-57
SLIDE 57

Ξ Effekt

b-studios.de/scala-effekt

AlternaOve TransformaOons

28

CPS

Effekt.push(() -> drunkFlip1(amb, exc)); amb.flip(); return DUMMY;
  • Gen. Stack InspecOon / Bubble Sem.
Effekt.beforeCall(); amb.flip(); if (Effekt.isImpure()) { Effekt.push(() -> drunkFlip1(amb, exc)); return DUMMY; }
slide-58
SLIDE 58

Ξ Effekt

b-studios.de/scala-effekt

AlternaOve TransformaOons

28

CPS

Effekt.push(() -> drunkFlip1(amb, exc)); amb.flip(); return DUMMY;
  • Gen. Stack InspecOon / Bubble Sem.
Effekt.beforeCall(); amb.flip(); if (Effekt.isImpure()) { Effekt.push(() -> drunkFlip1(amb, exc)); return DUMMY; }
  • all effect calls are tail calls
  • cont. is constructed eagerly and

immediately available

  • unnecessary push/pop/enter cycles
  • full reificaKon of the stack
slide-59
SLIDE 59

Ξ Effekt

b-studios.de/scala-effekt

AlternaOve TransformaOons

28

CPS

Effekt.push(() -> drunkFlip1(amb, exc)); amb.flip(); return DUMMY;
  • Gen. Stack InspecOon / Bubble Sem.
Effekt.beforeCall(); amb.flip(); if (Effekt.isImpure()) { Effekt.push(() -> drunkFlip1(amb, exc)); return DUMMY; }
  • all effect calls are tail calls
  • cont. is constructed eagerly and

immediately available

  • unnecessary push/pop/enter cycles
  • full reificaKon of the stack
  • two ways to leave a method,

disKnguished by a flag

  • cont. is constructed on demand
  • reduced overhead for pure code
  • prompt markers are trampolines
slide-60
SLIDE 60

Ξ Effekt

b-studios.de/scala-effekt

AlternaOve TransformaOons (Performance)

29

slide-61
SLIDE 61

Ξ Effekt

b-studios.de/scala-effekt

AlternaOve TransformaOons (Performance)

29

slide-62
SLIDE 62

Ξ Effekt

b-studios.de/scala-effekt

AlternaOve TransformaOons (Performance)

29

  • CorouKnes (hMps://github.com/ocynull/corouKnes)
  • Quasar (hMp://docs.paralleluniverse.co/quasar)
  • Javaflow (hMps://github.com/vsilaev/tascalate-javaflow)
  • Eff (hMps://github.com/atnos-org/eff)
slide-63
SLIDE 63

Ξ Effekt

b-studios.de/scala-effekt

Part III Even More Extensible Effects

30

slide-64
SLIDE 64

Ξ Effekt

b-studios.de/scala-effekt

The (Effect) Expression Problem

31

Variant of a Datatype vs. vs. (Recursive) OperaKon Handler ImplementaKon Effect OperaKon Effect Expression Problem Original Expression Problem

slide-65
SLIDE 65

Ξ Effekt

b-studios.de/scala-effekt

The (Effect) Expression Problem

We rephrase the expression problem in context of algebraic effects as: Modularly being able to a) implement new handlers for an effect signature. b) add new effect opera2ons to an exis1ng effect signature

31

Variant of a Datatype vs. vs. (Recursive) OperaKon Handler ImplementaKon Effect OperaKon Effect Expression Problem Original Expression Problem

slide-66
SLIDE 66

Ξ Effekt

b-studios.de/scala-effekt

Extensibility supported by Effekt

32

slide-67
SLIDE 67

Ξ Effekt

b-studios.de/scala-effekt

Extensibility supported by Effekt

32

a) implement new handlers for an effect signature.

trait ExcOption[R] extends Exc with Handler[R, Option[R]] { … } trait ExcEither[R] extends Exc with Handler[R, Either[String, R]] { … }
slide-68
SLIDE 68

Ξ Effekt

b-studios.de/scala-effekt

Extensibility supported by Effekt

32

a) implement new handlers for an effect signature.

trait ExcOption[R] extends Exc with Handler[R, Option[R]] { … } trait ExcEither[R] extends Exc with Handler[R, Either[String, R]] { … }

b) add new effect opera2ons … … by adding a new signature (like Amb and Exc) … by adding operaKons to a signature

slide-69
SLIDE 69

Ξ Effekt

b-studios.de/scala-effekt

Extensibility supported by Effekt

32

a) implement new handlers for an effect signature.

trait ExcOption[R] extends Exc with Handler[R, Option[R]] { … } trait ExcEither[R] extends Exc with Handler[R, Either[String, R]] { … }

b) add new effect opera2ons … … by adding a new signature (like Amb and Exc) … by adding operaKons to a signature

trait AmbChoose extends Amb { def choose[A](choices: List[A]): Op[A] } trait AmbChooseList[R] extends AmbChoose with AmbList[R] { def choose[A](choices: List[A]): Op[A] = … }
slide-70
SLIDE 70

Ξ Effekt

b-studios.de/scala-effekt

Extensibility supported by Effekt (2)

33

Handling two effects with one handler:

trait ExcList[R] extends Exc with Handler[R, List[R]] { def raise[A](msg: String): Op[A] = resume ⟹ pure(List.empty) } trait ExcAmbList[R] extends ExcList[R] with AmbList[R] {} > List("heads", "tails") ExcAmbList { drunkFlip }
slide-71
SLIDE 71

Ξ Effekt

b-studios.de/scala-effekt

Extensibility supported by Effekt (2)

33

Handling two effects with one handler:

trait ExcList[R] extends Exc with Handler[R, List[R]] { def raise[A](msg: String): Op[A] = resume ⟹ pure(List.empty) } trait ExcAmbList[R] extends ExcList[R] with AmbList[R] {} > List("heads", "tails") ExcAmbList { drunkFlip } ExcAmbList { both ⟹ drunkFlip(both, both) }

Desugares to:

slide-72
SLIDE 72

Ξ Effekt

b-studios.de/scala-effekt

00 34

Part IV Effect Typing and OO: A Problem Statement

slide-73
SLIDE 73

Ξ Effekt

b-studios.de/scala-effekt

35

Object Oriented Programming

The mantra of OOP:

  • subtyping and Liskov's subsKtuKon principle
  • hiding implementaOon details behind interfaces
  • implementaKon is existenOally hidden
  • InformaKon hiding happens on the granularity of single objects
slide-74
SLIDE 74

Ξ Effekt

b-studios.de/scala-effekt

36

trait Person { def greet(): Unit }

Subtyping & InformaOon Hiding

trait IOPerson extends Person { def greet(): Unit using Console } trait AlertPerson extends Person { def greet(): Unit using GUI }
slide-75
SLIDE 75

Ξ Effekt

b-studios.de/scala-effekt trait IOPerson extends Person { def greet(): Unit using Console } trait AlertPerson extends Person { def greet(): Unit using GUI }

37

trait Person { def greet(): Unit }

Subtyping & InformaOon Hiding

Not a subtype!

slide-76
SLIDE 76

Ξ Effekt

b-studios.de/scala-effekt

38

trait Person[E] { def greet(): Unit using E }

SoluOon A_empt 1

trait IOPerson extends Person[Console] trait AlertPerson extends Person[GUI]

Users of Person now also need to be effect polymorphic!

def user[E](p: Person[E]): Int using E
slide-77
SLIDE 77

Ξ Effekt

b-studios.de/scala-effekt

39

trait Person { type E def greet(): Unit using E }

SoluOon A_empt 1

trait IOPerson extends Person { type E = Console } trait AlertPerson extends Person { type E = GUI }

Effect types are now path dependent:

def user(p: Person): Int using p.E

Only works for stable values!

slide-78
SLIDE 78

Ξ Effekt

b-studios.de/scala-effekt

40

trait Person { def greet(): Control[Unit] }

SoluOon A_empt 2

trait IOPerson extends Person { implicit val console: Cap[Console] } trait AlertPerson extends Person { implicit val gui: Cap[GUI] }

The effect now is truly hidden

def user(p: Person): Control[Int]
slide-79
SLIDE 79

Ξ Effekt

b-studios.de/scala-effekt

Capability Safety

def leaking(implicit amb: Cap[Amb]): Control[String] = { pure("hello world") }

41

slide-80
SLIDE 80

Ξ Effekt

b-studios.de/scala-effekt

Capability Safety

var c: Cap[Amb] = null def leaking(implicit amb: Cap[Amb]): Control[String] = { c = amb; pure("hello world") }

42

slide-81
SLIDE 81

Ξ Effekt

b-studios.de/scala-effekt

Capability Safety

var c: Cap[Amb] = null def leaking(implicit amb: Cap[Amb]): Control[String] = { c = amb; pure("hello world") } AmbList { leaking }.run()

42

slide-82
SLIDE 82

Ξ Effekt

b-studios.de/scala-effekt

Capability Safety

var c: Cap[Amb] = null def leaking(implicit amb: Cap[Amb]): Control[String] = { c = amb; pure("hello world") } { flip()(c) }.run() AmbList { leaking }.run()

42

slide-83
SLIDE 83

Ξ Effekt

b-studios.de/scala-effekt

43

Capability Safety

var c: Cap[Amb] = null def leaking(implicit amb: Cap[Amb]): Control[String] = { c = amb; pure("hello world") } { flip()(c) }.run() AmbList { leaking }.run()
slide-84
SLIDE 84

Ξ Effekt

b-studios.de/scala-effekt

Possible SoluOon

44

Make (capability) objects second class again

slide-85
SLIDE 85

Ξ Effekt

b-studios.de/scala-effekt

Second Class Values in Scala Escape

var c: Cap[Amb] = null def leaking(implicit @local amb: Cap[Amb]): Control[String] = { c = amb; pure("hello world") }

45

slide-86
SLIDE 86

Ξ Effekt

b-studios.de/scala-effekt

Second Class Values in Scala Escape

var c: Cap[Amb] = null def leaking(implicit @local amb: Cap[Amb]): Control[String] = { c = amb; pure("hello world") }

Error: local value amb cannot be assigned to variable c since it would leave the scope of funcKon leaking.

45

slide-87
SLIDE 87

Ξ Effekt

b-studios.de/scala-effekt

Second Class Values in Scala Escape

var c: Cap[Amb] = null def leaking(implicit @local amb: Cap[Amb]): Control[String] = { c = amb; pure("hello world") }

Error: local value amb cannot be assigned to variable c since it would leave the scope of funcKon leaking. Restricts scope of capabiliKes so that they can be stack allocated.

45

slide-88
SLIDE 88

Ξ Effekt

b-studios.de/scala-effekt

Second Class Values in Scala Escape

var c: Cap[Amb] = null def leaking(implicit @local amb: Cap[Amb]): Control[String] = { c = amb; pure("hello world") }

Error: local value amb cannot be assigned to variable c since it would leave the scope of funcKon leaking. Restricts scope of capabiliKes so that they can be stack allocated. This perfectly fits algebraic effects.

45

slide-89
SLIDE 89

Ξ Effekt

b-studios.de/scala-effekt

46

trait Person { def greet(): Control[Unit] }

SoluOon A_empt 2

trait IOPerson extends Person { implicit val console: Cap[Console] } trait AlertPerson extends Person { implicit val gui: Cap[GUI] }
slide-90
SLIDE 90

Ξ Effekt

b-studios.de/scala-effekt

46

trait Person { def greet(): Control[Unit] }

SoluOon A_empt 2

trait IOPerson extends Person { implicit val console: Cap[Console] } trait AlertPerson extends Person { implicit val gui: Cap[GUI] }

Object lifetime < Capability lifetime

slide-91
SLIDE 91

Ξ Effekt

b-studios.de/scala-effekt

47

The Root of Evil

There is a simple connecKon:

  • Algebraic effects and delimited conKnuaKons are all about the stack
  • Object oriented programming is all about heap allocated objects

ConflicKng requirements:

  • capabiliKes should be stack allocated, objects don't
  • but object lifeKme should not be coupled to capability lifeKme
  • in parKcular, objects should be able to escape the handler scope 


losing the capabiliKes

slide-92
SLIDE 92

Ξ Effekt

b-studios.de/scala-effekt

00 48

Part V Effec[ul Syntax

slide-93
SLIDE 93 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

PL LinguisKcs Algebraic Effects

Jiří Maršík and Maxime Amblard, 2016

00 49

LinguisKc phenomena like anaphora, scoping, quanKficaKon, implicature, focus and more can be modeled uniformly using algebraic effects.

EffecQul Syntax

slide-94
SLIDE 94 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

PL LinguisKcs Algebraic Effects

Jiří Maršík and Maxime Amblard, 2016

EffecQul Syntax

This Talk

00 49

LinguisKc phenomena like anaphora, scoping, quanKficaKon, implicature, focus and more can be modeled uniformly using algebraic effects.

  • Support linguisOc phenomena in EDSLs using algebraic effects
  • Use (algebraic) effects for AST construcOon

EffecQul Syntax

slide-95
SLIDE 95 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

val s1: Sentence using Speaker = john said { mary loves me }

Example 1: The Speaker Effect

50

○ Kny.cc/effec[ul-syntax

slide-96
SLIDE 96 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

val s1: Sentence using Speaker = john said { mary loves me }

Example 1: The Speaker Effect

Effect Signature

Groups effect operaKons in a type

Effect OperaKons

SemanKcs of the operaKons is leP open

Speaker me

51

○ Kny.cc/effec[ul-syntax

slide-97
SLIDE 97 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

Example 1: The Speaker Effect

Effect Signature

Groups effect operaKons in a type

Effect OperaKons

SemanKcs of the operaKons is leP open

pete saidQuote { s1 } val s1: Sentence using Speaker = john said { mary loves me } Speaker me

52

○ Kny.cc/effec[ul-syntax

slide-98
SLIDE 98 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

Example 1: The Speaker Effect

Effect Signature

Groups effect operaKons in a type

Effect OperaKons

SemanKcs of the operaKons is leP open

pete saidQuote { s1 }

Effect Handlers

Provide semanKcs to effect operaKons

val s1: Sentence using Speaker = john said { mary loves me } Speaker me

52

○ Kny.cc/effec[ul-syntax

slide-99
SLIDE 99 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

Example 1: The Speaker Effect

Effect Signature

Groups effect operaKons in a type

Effect OperaKons

SemanKcs of the operaKons is leP open

pete saidQuote { s1 }

Effect Handlers

Provide semanKcs to effect operaKons

> Said(Pete, Said(John, Loves(Mary, Pete))) val s1: Sentence using Speaker = john said { mary loves me } Speaker me

52

○ Kny.cc/effec[ul-syntax

slide-100
SLIDE 100 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

val s2: Sentence using Scope = john saidQuote { every(woman) loves me }

Example 2: The Scope Effect

53

slide-101
SLIDE 101 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

val s2: Sentence using Scope = john saidQuote { every(woman) loves me }

Example 2: The Scope Effect

53

Effect OperaKons

SemanKcs of the operaKons is leP open

slide-102
SLIDE 102 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

val s2: Sentence using Scope = john saidQuote { every(woman) loves me }

Example 2: The Scope Effect

Effect Signature

Groups effect operaKons in a type 53

Effect OperaKons

SemanKcs of the operaKons is leP open

slide-103
SLIDE 103 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

val s2: Sentence using Scope = john saidQuote { every(woman) loves me }

Example 2: The Scope Effect

scoped { s2 }

Effect Signature

Groups effect operaKons in a type 53

Effect OperaKons

SemanKcs of the operaKons is leP open

slide-104
SLIDE 104 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

val s2: Sentence using Scope = john saidQuote { every(woman) loves me }

Example 2: The Scope Effect

scoped { s2 }

Effect Signature

Groups effect operaKons in a type 53

Effect OperaKons

SemanKcs of the operaKons is leP open

Effect Handlers

Provide semanKcs to effect operaKons

slide-105
SLIDE 105 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

val s2: Sentence using Scope = john saidQuote { every(woman) loves me }

Example 2: The Scope Effect

scoped { s2 } > Forall(x => Implies(Woman(x), Said(John, Loves(x, John))))

Effect Signature

Groups effect operaKons in a type 53

Effect OperaKons

SemanKcs of the operaKons is leP open

Effect Handlers

Provide semanKcs to effect operaKons

slide-106
SLIDE 106 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

val s3: Sentence using Speaker and Implicature = mary loves { john whoIs { _ bestFriendOf me } }

Example 3: The Implicature Effect

54

slide-107
SLIDE 107 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

val s3: Sentence using Speaker and Implicature = mary loves { john whoIs { _ bestFriendOf me } }

Example 3: The Implicature Effect

54

Effect OperaKons

SemanKcs of the operaKons is leP open

slide-108
SLIDE 108 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

val s3: Sentence using Speaker and Implicature = mary loves { john whoIs { _ bestFriendOf me } }

Example 3: The Implicature Effect

pete saidQuote { accommodate { s3 } }

54

slide-109
SLIDE 109 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

val s3: Sentence using Speaker and Implicature = mary loves { john whoIs { _ bestFriendOf me } }

Example 3: The Implicature Effect

pete saidQuote { accommodate { s3 } } > Said(Pete, And(BestFriendOf(John, Pete), Loves(Mary, John)))

54

slide-110
SLIDE 110 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

val s3: Sentence using Speaker and Implicature = mary loves { john whoIs { _ bestFriendOf me } }

Example 3: The Implicature Effect

pete saidQuote { accommodate { s3 } } > Said(Pete, And(BestFriendOf(John, Pete), Loves(Mary, John))) accommodate { pete saidQuote { s3 } }

54

slide-111
SLIDE 111 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

val s3: Sentence using Speaker and Implicature = mary loves { john whoIs { _ bestFriendOf me } }

Example 3: The Implicature Effect

pete saidQuote { accommodate { s3 } } > Said(Pete, And(BestFriendOf(John, Pete), Loves(Mary, John))) accommodate { pete saidQuote { s3 } } > And(Said(Pete, BestFriendOf(John, Pete)), Said(Pete, Loves(Mary, John)))

54

slide-112
SLIDE 112 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

Use (algebraic) effects for AST construcOon. More precisely, we propose to group syntax elements of DSLs into:

EffecQul Syntax

55

slide-113
SLIDE 113 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

Use (algebraic) effects for AST construcOon. More precisely, we propose to group syntax elements of DSLs into:

EffecQul Syntax

Pure Syntax

Plain constructors.

55

john mary loves woman
slide-114
SLIDE 114 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

Use (algebraic) effects for AST construcOon. More precisely, we propose to group syntax elements of DSLs into:

EffecQul Syntax

Pure Syntax

Plain constructors.

Effec[ul Syntax


Non local syntax that requires contextual handling.

55

john mary loves woman me whoIs every
slide-115
SLIDE 115 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

Use (algebraic) effects for AST construcOon. More precisely, we propose to group syntax elements of DSLs into:

EffecQul Syntax

Pure Syntax

Plain constructors.

Effec[ul Syntax


Non local syntax that requires contextual handling.

Handling Syntax

Handles effects by restructuring the AST, potenKally again using effects.

55

john mary loves woman me whoIs every scope saidQuote accommodate
slide-116
SLIDE 116 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

ProperOes

56

Effec[ul syntax based on algebraic effects is...

slide-117
SLIDE 117 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

ProperOes

56

Effec[ul syntax based on algebraic effects is... Modular LinguisKc phenomena can be encapsulated into reusable modules.

slide-118
SLIDE 118 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

ProperOes

56

Effec[ul syntax based on algebraic effects is... Modular LinguisKc phenomena can be encapsulated into reusable modules. Effec1ul Syntax Handling Syntax Effec1ul Syntax Handling Syntax Effec1ul Syntax Handling Syntax Pure Syntax

slide-119
SLIDE 119 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

ProperOes

56

Effec[ul syntax based on algebraic effects is... Modular LinguisKc phenomena can be encapsulated into reusable modules. Effec1ul Syntax Handling Syntax Effec1ul Syntax Handling Syntax Effec1ul Syntax Handling Syntax Pure Syntax Learnable SeparaKng linguisKc phenomena from

  • ther domain concepts

allows separate understanding

slide-120
SLIDE 120 b-studios.de/scala-effekt

Towards NaturalisCc EDSLs using Algebraic Effects

ProperOes

56

Effec[ul syntax based on algebraic effects is... Modular LinguisKc phenomena can be encapsulated into reusable modules. Effec1ul Syntax Handling Syntax Effec1ul Syntax Handling Syntax Effec1ul Syntax Handling Syntax Pure Syntax Learnable SeparaKng linguisKc phenomena from

  • ther domain concepts

allows separate understanding Maintainable Types precisely communicate usage of effec[ul syntax.