continuation passing style for effect handlers - formal ... ·...

53
This work is supported by

Upload: others

Post on 08-Oct-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

This work is supported by

Page 2: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Continuation Passing Style for Effect HandlersFormal Structures for Computation and Deduction

Daniel Hillerström 1 Sam Lindley 1

Robert Atkey 2 KC Sivaramakrishnan 3

1The University of Edinburgh, UK

2University of Strathclyde, UK

3University of Cambridge, UK

September 5, 2017

Page 3: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Algebraic effects by example: a drunk coin toss

Consider two effects: nondeterminism and exceptions

drunkToss : Toss ! {Choose : Bool;Fail : Zero}drunkToss = if do Choose then

if do Choose then Heads else Tailselse absurd do Fail

Drunk toss computation tree

Page 4: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Algebraic effects by example: a drunk coin toss

Consider two effects: nondeterminism and exceptions

drunkToss : Toss ! {Choose : Bool;Fail : Zero}drunkToss = if do Choose then

if do Choose then Heads else Tailselse absurd do Fail

Drunk toss computation treeChoose

Choose

Heads

true

Tails

false

true

Fail

false

Page 5: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Effect handlers by example: modular interpretations

Choose handler

allChoices : α ! {Choose : Bool; ρ} ⇒ List α ! {ρ}allChoices = return x 7→ [x ]

Choose r 7→ r true ++ r false

Fail handler

fail : α ! {Fail : Zero; ρ} ⇒ List α ! {ρ}fail = return x 7→ [x ]

Fail r 7→ []

Two possible interpretations:

Page 6: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Effect handlers by example: modular interpretations

Choose handler

allChoices : α ! {Choose : Bool; ρ} ⇒ List α ! {ρ}allChoices = return x 7→ [x ]

Choose r 7→ r true ++ r false

Fail handler

fail : α ! {Fail : Zero; ρ} ⇒ List α ! {ρ}fail = return x 7→ [x ]

Fail r 7→ []

Two possible interpretations:

handle (handle drunkToss with fail) with allChoices⇒ [[Heads], [Tails], []]

handle (handle drunkToss with allChoices) with fail⇒ []

Page 7: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Effect handlers by example: modular interpretations

Choose handler

allChoices : α ! {Choose : Bool; ρ} ⇒ List α ! {ρ}allChoices = return x 7→ [x ]

Choose r 7→ r true ++ r false

Fail handler

fail : α ! {Fail : Zero; ρ} ⇒ List α ! {ρ}fail = return x 7→ [x ]

Fail r 7→ []

Two possible interpretations:

handle (handle with fail) with allChoicesChoose

Choose

Heads

true

Tails

false

true

Fail

false

Page 8: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Effect handlers by example: modular interpretations

Choose handler

allChoices : α ! {Choose : Bool; ρ} ⇒ List α ! {ρ}allChoices = return x 7→ [x ]

Choose r 7→ r true ++ r false

Fail handler

fail : α ! {Fail : Zero; ρ} ⇒ List α ! {ρ}fail = return x 7→ [x ]

Fail r 7→ []

Two possible interpretations:

handle (handle with fail) with allChoicesChoose

Choose

Heads

true

Tails

false

true

Fail

false

Page 9: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Effect handlers by example: modular interpretations

Choose handler

allChoices : α ! {Choose : Bool; ρ} ⇒ List α ! {ρ}allChoices = return x 7→ [x ]

Choose r 7→ r true ++ r false

Fail handler

fail : α ! {Fail : Zero; ρ} ⇒ List α ! {ρ}fail = return x 7→ [x ]

Fail r 7→ []

Two possible interpretations:

handle (handle with fail) with allChoicesChoose

Choose

[[Heads]]

true

Tails

false

true

Fail

false

Page 10: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Effect handlers by example: modular interpretations

Choose handler

allChoices : α ! {Choose : Bool; ρ} ⇒ List α ! {ρ}allChoices = return x 7→ [x ]

Choose r 7→ r true ++ r false

Fail handler

fail : α ! {Fail : Zero; ρ} ⇒ List α ! {ρ}fail = return x 7→ [x ]

Fail r 7→ []

Two possible interpretations:

handle (handle with fail) with allChoicesChoose

Choose

[[Heads]]

true

[[Tails]]

false

true

Fail

false

Page 11: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Effect handlers by example: modular interpretations

Choose handler

allChoices : α ! {Choose : Bool; ρ} ⇒ List α ! {ρ}allChoices = return x 7→ [x ]

Choose r 7→ r true ++ r false

Fail handler

fail : α ! {Fail : Zero; ρ} ⇒ List α ! {ρ}fail = return x 7→ [x ]

Fail r 7→ []

Two possible interpretations:

handle (handle with fail) with allChoicesChoose

[[Heads], [Tails]]

true

Fail

false

Page 12: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Effect handlers by example: modular interpretations

Choose handler

allChoices : α ! {Choose : Bool; ρ} ⇒ List α ! {ρ}allChoices = return x 7→ [x ]

Choose r 7→ r true ++ r false

Fail handler

fail : α ! {Fail : Zero; ρ} ⇒ List α ! {ρ}fail = return x 7→ [x ]

Fail r 7→ []

Two possible interpretations:

handle (handle with fail) with allChoicesChoose

[[Heads], [Tails]]

true

Fail

false

Page 13: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Effect handlers by example: modular interpretations

Choose handler

allChoices : α ! {Choose : Bool; ρ} ⇒ List α ! {ρ}allChoices = return x 7→ [x ]

Choose r 7→ r true ++ r false

Fail handler

fail : α ! {Fail : Zero; ρ} ⇒ List α ! {ρ}fail = return x 7→ [x ]

Fail r 7→ []

Two possible interpretations:

handle (handle with fail) with allChoicesChoose

[[Heads], [Tails]]

true

[[]]

false

Page 14: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Effect handlers by example: modular interpretations

Choose handler

allChoices : α ! {Choose : Bool; ρ} ⇒ List α ! {ρ}allChoices = return x 7→ [x ]

Choose r 7→ r true ++ r false

Fail handler

fail : α ! {Fail : Zero; ρ} ⇒ List α ! {ρ}fail = return x 7→ [x ]

Fail r 7→ []

Two possible interpretations:

[[Heads], [Tails], []]

Page 15: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Effect handlers by example: modular interpretations

Choose handler

allChoices : α ! {Choose : Bool; ρ} ⇒ List α ! {ρ}allChoices = return x 7→ [x ]

Choose r 7→ r true ++ r false

Fail handler

fail : α ! {Fail : Zero; ρ} ⇒ List α ! {ρ}fail = return x 7→ [x ]

Fail r 7→ []

Two possible interpretations:

handle (handle drunkToss with allChoices) with fail⇒ []

Page 16: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Effect handlers by example: modular interpretations

Choose handler

allChoices : α ! {Choose : Bool; ρ} ⇒ List α ! {ρ}allChoices = return x 7→ [x ]

Choose r 7→ r true ++ r false

Fail handler

fail : α ! {Fail : Zero; ρ} ⇒ List α ! {ρ}fail = return x 7→ [x ]

Fail r 7→ []

Two possible interpretations:

handle (handle with allChoices) with failChoose

Choose

[Heads]

true

[Tails]

false

true

Fail

false

Page 17: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Effect handlers by example: modular interpretations

Choose handler

allChoices : α ! {Choose : Bool; ρ} ⇒ List α ! {ρ}allChoices = return x 7→ [x ]

Choose r 7→ r true ++ r false

Fail handler

fail : α ! {Fail : Zero; ρ} ⇒ List α ! {ρ}fail = return x 7→ [x ]

Fail r 7→ []

Two possible interpretations:

handle (handle with allChoices) with failChoose

[Heads,Tails]

true

Fail

false

Page 18: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Effect handlers by example: modular interpretations

Choose handler

allChoices : α ! {Choose : Bool; ρ} ⇒ List α ! {ρ}allChoices = return x 7→ [x ]

Choose r 7→ r true ++ r false

Fail handler

fail : α ! {Fail : Zero; ρ} ⇒ List α ! {ρ}fail = return x 7→ [x ]

Fail r 7→ []

Two possible interpretations:

handle (handle with allChoices) with failChoose

[Heads,Tails]

true

Fail

false

Page 19: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Effect handlers by example: modular interpretations

Choose handler

allChoices : α ! {Choose : Bool; ρ} ⇒ List α ! {ρ}allChoices = return x 7→ [x ]

Choose r 7→ r true ++ r false

Fail handler

fail : α ! {Fail : Zero; ρ} ⇒ List α ! {ρ}fail = return x 7→ [x ]

Fail r 7→ []

Two possible interpretations:

[]

Page 20: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Operational semantics for effect handlers

The operational semantics for handlers is fairly simple

handle (return V ) with H N[V /x ],where Hret = {return x 7→ N}

handle E [do ` V ] with H N[V /p, λy . handle E [return y ] with H/r ],where ` /∈ BL(E) and H` = {` p r 7→ N}

The set of bound labels, BL, is defined inductively

BL([ ]) = ∅ BL(let x ← E in N) = BL(E) BL(handle E with H) = BL(E) ∪ dom(H)

Evaluation contexts, E , are standard

E ::= [] | let x ← E in N | handle E with H

Page 21: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Why continuation passing style?

So, effect handlers are great! Now, how do we compile them?

Why continuation passing style (CPS)?CPS is good for implementing control flowCPS is formulated on a restricted subset of λ-calculusThe Links compiler (Cooper, Lindley, Wadler, and Yallop 2006)

Server-side uses a CEK machineClient-side uses CPS

Page 22: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Source and target calculi

Our source calculus is λρeff (Hillerström and Lindley 2016).

Values V ,W ::= x | λx .M | 〈〉 | 〈` = V ;W 〉 | (`V )

Computations M,N ::= V W| let 〈` = x ; y〉 = V in N | case V {` x 7→ M; y 7→ N} | absurdV| return V | let x ← M in N| do ` V | handle M with H

Handlers H ::= {return x 7→ M} | {` p r 7→ M} ] H}

Our target is an untyped λ-calculus

Values V ,W ::= x | λx .M | 〈〉 | 〈` = V ;W 〉 | ` VComputations M,N ::= V | M W | let 〈` = x ; y〉 = V in N

| case V {` x 7→ M; y 7→ N} | absurdV

Page 23: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Source and target calculi

Our source calculus is λρeff (Hillerström and Lindley 2016).

Values V ,W ::= x | λx .M | 〈〉 | 〈` = V ;W 〉 | (`V )

Computations M,N ::= V W| let 〈` = x ; y〉 = V in N | case V {` x 7→ M; y 7→ N} | absurdV| return V | let x ← M in N| do ` V | handle M with H

Handlers H ::= {return x 7→ M} | {` p r 7→ M} ] H}

Our target is an untyped λ-calculus

Values V ,W ::= x | λx .M | 〈〉 | 〈` = V ;W 〉 | ` VComputations M,N ::= V | M W | let 〈` = x ; y〉 = V in N

| case V {` x 7→ M; y 7→ N} | absurdV

Page 24: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Source and target calculi

Our source calculus is λρeff (Hillerström and Lindley 2016).

Values V ,W ::= x | λx .M | 〈〉 | 〈` = V ;W 〉 | (`V )

Computations M,N ::= V W| let 〈` = x ; y〉 = V in N | case V {` x 7→ M; y 7→ N} | absurdV| return V | let x ← M in N| do ` V | handle M with H

Handlers H ::= {return x 7→ M} | {` p r 7→ M} ] H}

Our target is an untyped λ-calculus

Values V ,W ::= x | λx .M | 〈〉 | 〈` = V ;W 〉 | ` VComputations M,N ::= V | M W | let 〈` = x ; y〉 = V in N

| case V {` x 7→ M; y 7→ N} | absurdV

Page 25: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Source and target calculi

Our source calculus is λρeff (Hillerström and Lindley 2016).

Values V ,W ::= x | λx .M | 〈〉 | 〈` = V ;W 〉 | (`V )

Computations M,N ::= V W| let 〈` = x ; y〉 = V in N | case V {` x 7→ M; y 7→ N} | absurdV| return V | let x ← M in N| do ` V | handle M with H

Handlers H ::= {return x 7→ M} | {` p r 7→ M} ] H}

Our target is an untyped λ-calculus

Values V ,W ::= x | λx .M | 〈〉 | 〈` = V ;W 〉 | ` VComputations M,N ::= V | M W | let 〈` = x ; y〉 = V in N

| case V {` x 7→ M; y 7→ N} | absurdV

Page 26: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Curried CPS translation for fine-grain call-by-value

The continuation represents the execution context.

Computations

JV W K = JV K JW KJlet 〈` = x ; y〉 = V in NK = let 〈` = x ; y〉 = JV K in JNK

Jcase V {` x 7→ M; y 7→ N}K = case JV K {` x 7→ JMK; y 7→ JNK}Jabsurd V K = absurd JV KJreturn V K = λk.k JV K

Jlet x ← M in NK = λk.JMK(λx .JNKk)

ValuesJxK = x

Jλx .MK = λx .JMKJ〈〉K = 〈〉

J〈` = V ;W 〉K = 〈` = JV K; JW K〉J` V K = ` JV K

Page 27: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Curried CPS for handlers

With handlers there are two contexts: a pure and an effect context.Idea: implicit stack of alternating pure and effect continuations.

Jdo ` V K = λk.λh.h (` 〈JV K, λx .k x h〉)Jhandle M with HK = JMK JHretK JHopsKJ{return x 7→ N}K = λx .λh.JNK

J{` p r 7→ N`}`∈LK = λz .case z {(` 〈p, r〉 7→ JN`K)`∈L; y 7→ Mforward}Mforward = λk ′.λh′.vmap (λ〈p, r〉 k.k 〈p, λx .r x k ′ h′〉) y h′

>JMK = JMK (λx .λh.x) (λz .absurd z)

Problem: J−K yields administrative redexes and is not properly tail-recursive!

>Jreturn 〈〉K = (λk.k 〈〉) (λx .λh.x) (λz .absurd z)

((λx .λh.x) 〈〉) (λz .absurd z) (λh.〈〉) (λz .absurd z) 〈〉

Page 28: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Curried CPS for handlers

With handlers there are two contexts: a pure and an effect context.Idea: implicit stack of alternating pure and effect continuations.

Jdo ` V K = λk.λh.h (` 〈JV K, λx .k x h〉)Jhandle M with HK = JMK JHretK JHopsKJ{return x 7→ N}K = λx .λh.JNK

J{` p r 7→ N`}`∈LK = λz .case z {(` 〈p, r〉 7→ JN`K)`∈L; y 7→ Mforward}Mforward = λk ′.λh′.vmap (λ〈p, r〉 k.k 〈p, λx .r x k ′ h′〉) y h′

>JMK = JMK (λx .λh.x) (λz .absurd z)

Problem: J−K yields administrative redexes and is not properly tail-recursive!

>Jreturn 〈〉K = (λk.k 〈〉) (λx .λh.x) (λz .absurd z)

((λx .λh.x) 〈〉) (λz .absurd z) (λh.〈〉) (λz .absurd z) 〈〉

Page 29: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Curried CPS for handlers

With handlers there are two contexts: a pure and an effect context.Idea: implicit stack of alternating pure and effect continuations.

Jdo ` V K = λk.λh.h (` 〈JV K, λx .k x h〉)Jhandle M with HK = JMK JHretK JHopsKJ{return x 7→ N}K = λx .λh.JNK

J{` p r 7→ N`}`∈LK = λz .case z {(` 〈p, r〉 7→ JN`K)`∈L; y 7→ Mforward}Mforward = λk ′.λh′.vmap (λ〈p, r〉 k.k 〈p, λx .r x k ′ h′〉) y h′

>JMK = JMK (λx .λh.x) (λz .absurd z)

Problem: J−K yields administrative redexes and is not properly tail-recursive!

>Jreturn 〈〉K = (λk.k 〈〉) (λx .λh.x) (λz .absurd z)

((λx .λh.x) 〈〉) (λz .absurd z) (λh.〈〉) (λz .absurd z) 〈〉

Page 30: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Curried CPS for handlers

With handlers there are two contexts: a pure and an effect context.Idea: implicit stack of alternating pure and effect continuations.

Jdo ` V K = λk.λh.h (` 〈JV K, λx .k x h〉)Jhandle M with HK = JMK JHretK JHopsKJ{return x 7→ N}K = λx .λh.JNK

J{` p r 7→ N`}`∈LK = λz .case z {(` 〈p, r〉 7→ JN`K)`∈L; y 7→ Mforward}Mforward = λk ′.λh′.vmap (λ〈p, r〉 k.k 〈p, λx .r x k ′ h′〉) y h′

>JMK = JMK (λx .λh.x) (λz .absurd z)

Problem: J−K yields administrative redexes and is not properly tail-recursive!

>Jreturn 〈〉K = (λk.k 〈〉) (λx .λh.x) (λz .absurd z)

((λx .λh.x) 〈〉) (λz .absurd z) (λh.〈〉) (λz .absurd z) 〈〉

Page 31: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Curried CPS for handlers

With handlers there are two contexts: a pure and an effect context.Idea: implicit stack of alternating pure and effect continuations.

Jdo ` V K = λk.λh.h (` 〈JV K, λx .k x h〉)Jhandle M with HK = JMK JHretK JHopsKJ{return x 7→ N}K = λx .λh.JNK

J{` p r 7→ N`}`∈LK = λz .case z {(` 〈p, r〉 7→ JN`K)`∈L; y 7→ Mforward}Mforward = λk ′.λh′.vmap (λ〈p, r〉 k.k 〈p, λx .r x k ′ h′〉) y h′

>JMK = JMK (λx .λh.x) (λz .absurd z)

Problem: J−K yields administrative redexes and is not properly tail-recursive!

>Jreturn 〈〉K = (λk.k 〈〉) (λx .λh.x) (λz .absurd z)

((λx .λh.x) 〈〉) (λz .absurd z) (λh.〈〉) (λz .absurd z) 〈〉

Page 32: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Curried CPS for handlers

With handlers there are two contexts: a pure and an effect context.Idea: implicit stack of alternating pure and effect continuations.

Jdo ` V K = λk.λh.h (` 〈JV K, λx .k x h〉)Jhandle M with HK = JMK JHretK JHopsKJ{return x 7→ N}K = λx .λh.JNK

J{` p r 7→ N`}`∈LK = λz .case z {(` 〈p, r〉 7→ JN`K)`∈L; y 7→ Mforward}Mforward = λk ′.λh′.vmap (λ〈p, r〉 k.k 〈p, λx .r x k ′ h′〉) y h′

>JMK = JMK (λx .λh.x) (λz .absurd z)

Problem: J−K yields administrative redexes and is not properly tail-recursive!

>Jreturn 〈〉K = (λk.k 〈〉) (λx .λh.x) (λz .absurd z) ((λx .λh.x) 〈〉) (λz .absurd z)

(λh.〈〉) (λz .absurd z) 〈〉

Page 33: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Curried CPS for handlers

With handlers there are two contexts: a pure and an effect context.Idea: implicit stack of alternating pure and effect continuations.

Jdo ` V K = λk.λh.h (` 〈JV K, λx .k x h〉)Jhandle M with HK = JMK JHretK JHopsKJ{return x 7→ N}K = λx .λh.JNK

J{` p r 7→ N`}`∈LK = λz .case z {(` 〈p, r〉 7→ JN`K)`∈L; y 7→ Mforward}Mforward = λk ′.λh′.vmap (λ〈p, r〉 k.k 〈p, λx .r x k ′ h′〉) y h′

>JMK = JMK (λx .λh.x) (λz .absurd z)

Problem: J−K yields administrative redexes and is not properly tail-recursive!

>Jreturn 〈〉K = (λk.k 〈〉) (λx .λh.x) (λz .absurd z) ((λx .λh.x) 〈〉) (λz .absurd z) (λh.〈〉) (λz .absurd z)

〈〉

Page 34: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Curried CPS for handlers

With handlers there are two contexts: a pure and an effect context.Idea: implicit stack of alternating pure and effect continuations.

Jdo ` V K = λk.λh.h (` 〈JV K, λx .k x h〉)Jhandle M with HK = JMK JHretK JHopsKJ{return x 7→ N}K = λx .λh.JNK

J{` p r 7→ N`}`∈LK = λz .case z {(` 〈p, r〉 7→ JN`K)`∈L; y 7→ Mforward}Mforward = λk ′.λh′.vmap (λ〈p, r〉 k.k 〈p, λx .r x k ′ h′〉) y h′

>JMK = JMK (λx .λh.x) (λz .absurd z)

Problem: J−K yields administrative redexes and is not properly tail-recursive!

>Jreturn 〈〉K = (λk.k 〈〉) (λx .λh.x) (λz .absurd z) ((λx .λh.x) 〈〉) (λz .absurd z) (λh.〈〉) (λz .absurd z) 〈〉

Page 35: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Uncurried CPS for handlers

Idea: make the continuation stack explicit (Materzok and Biernacki 2012).

Jreturn V K = λ(k :: ks).k JV K ksJlet x ← M in NK = λ(k :: ks).JMK((λx ks.JNK(k :: ks)) :: ks)

Jdo ` V K = λ(k :: h :: ks).h (` 〈JV K, h :: k :: []〉) ksJhandle M with HK = λks.JMK(JHretK :: JHopsK :: ks)J{return x 7→ N}K = λx ks.let (h :: ks ′) = ks in JNK ks

J{(` p r 7→ N`)`∈L}K = λz ks.case z {(` 〈p, s〉 7→ let r = fun s in JN`K ks)`∈L;y 7→ Mforward}

Mforward = let (k ′ :: h′ :: ks ′) = ks invmap (λ〈p, r〉 (k :: ks).k 〈p, h′ :: k ′ :: r〉 ks) y ks ′

>JMK = JMK ((λx ks.x) :: (λz ks.absurd z) :: [])

But J−K still yields the administrative redexes

>Jreturn 〈〉K = (λ(k :: ks).k 〈〉 ks) ((λx ks.x) :: (λz .absurd z) :: [])

(λx ks.x) 〈〉 [(λz .absurd z)] + 〈〉

Page 36: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Uncurried CPS for handlers

Idea: make the continuation stack explicit (Materzok and Biernacki 2012).

Jreturn V K = λ(k :: ks).k JV K ksJlet x ← M in NK = λ(k :: ks).JMK((λx ks.JNK(k :: ks)) :: ks)

Jdo ` V K = λ(k :: h :: ks).h (` 〈JV K, h :: k :: []〉) ksJhandle M with HK = λks.JMK(JHretK :: JHopsK :: ks)J{return x 7→ N}K = λx ks.let (h :: ks ′) = ks in JNK ks

J{(` p r 7→ N`)`∈L}K = λz ks.case z {(` 〈p, s〉 7→ let r = fun s in JN`K ks)`∈L;y 7→ Mforward}

Mforward = let (k ′ :: h′ :: ks ′) = ks invmap (λ〈p, r〉 (k :: ks).k 〈p, h′ :: k ′ :: r〉 ks) y ks ′

>JMK = JMK ((λx ks.x) :: (λz ks.absurd z) :: [])

But J−K still yields the administrative redexes

>Jreturn 〈〉K = (λ(k :: ks).k 〈〉 ks) ((λx ks.x) :: (λz .absurd z) :: [])

(λx ks.x) 〈〉 [(λz .absurd z)] + 〈〉

Page 37: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Uncurried CPS for handlers

Idea: make the continuation stack explicit (Materzok and Biernacki 2012).

Jreturn V K = λ(k :: ks).k JV K ksJlet x ← M in NK = λ(k :: ks).JMK((λx ks.JNK(k :: ks)) :: ks)

Jdo ` V K = λ(k :: h :: ks).h (` 〈JV K, h :: k :: []〉) ksJhandle M with HK = λks.JMK(JHretK :: JHopsK :: ks)J{return x 7→ N}K = λx ks.let (h :: ks ′) = ks in JNK ks

J{(` p r 7→ N`)`∈L}K = λz ks.case z {(` 〈p, s〉 7→ let r = fun s in JN`K ks)`∈L;y 7→ Mforward}

Mforward = let (k ′ :: h′ :: ks ′) = ks invmap (λ〈p, r〉 (k :: ks).k 〈p, h′ :: k ′ :: r〉 ks) y ks ′

>JMK = JMK ((λx ks.x) :: (λz ks.absurd z) :: [])

But J−K still yields the administrative redexes

>Jreturn 〈〉K = (λ(k :: ks).k 〈〉 ks) ((λx ks.x) :: (λz .absurd z) :: [])

(λx ks.x) 〈〉 [(λz .absurd z)] + 〈〉

Page 38: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Uncurried CPS for handlers

Idea: make the continuation stack explicit (Materzok and Biernacki 2012).

Jreturn V K = λ(k :: ks).k JV K ksJlet x ← M in NK = λ(k :: ks).JMK((λx ks.JNK(k :: ks)) :: ks)

Jdo ` V K = λ(k :: h :: ks).h (` 〈JV K, h :: k :: []〉) ksJhandle M with HK = λks.JMK(JHretK :: JHopsK :: ks)J{return x 7→ N}K = λx ks.let (h :: ks ′) = ks in JNK ks

J{(` p r 7→ N`)`∈L}K = λz ks.case z {(` 〈p, s〉 7→ let r = fun s in JN`K ks)`∈L;y 7→ Mforward}

Mforward = let (k ′ :: h′ :: ks ′) = ks invmap (λ〈p, r〉 (k :: ks).k 〈p, h′ :: k ′ :: r〉 ks) y ks ′

>JMK = JMK ((λx ks.x) :: (λz ks.absurd z) :: [])

But J−K still yields the administrative redexes

>Jreturn 〈〉K = (λ(k :: ks).k 〈〉 ks) ((λx ks.x) :: (λz .absurd z) :: [])

(λx ks.x) 〈〉 [(λz .absurd z)] + 〈〉

Page 39: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Uncurried CPS for handlers

Idea: make the continuation stack explicit (Materzok and Biernacki 2012).

Jreturn V K = λ(k :: ks).k JV K ksJlet x ← M in NK = λ(k :: ks).JMK((λx ks.JNK(k :: ks)) :: ks)

Jdo ` V K = λ(k :: h :: ks).h (` 〈JV K, h :: k :: []〉) ksJhandle M with HK = λks.JMK(JHretK :: JHopsK :: ks)J{return x 7→ N}K = λx ks.let (h :: ks ′) = ks in JNK ks

J{(` p r 7→ N`)`∈L}K = λz ks.case z {(` 〈p, s〉 7→ let r = fun s in JN`K ks)`∈L;y 7→ Mforward}

Mforward = let (k ′ :: h′ :: ks ′) = ks invmap (λ〈p, r〉 (k :: ks).k 〈p, h′ :: k ′ :: r〉 ks) y ks ′

>JMK = JMK ((λx ks.x) :: (λz ks.absurd z) :: [])

But J−K still yields the administrative redexes

>Jreturn 〈〉K = (λ(k :: ks).k 〈〉 ks) ((λx ks.x) :: (λz .absurd z) :: [])

(λx ks.x) 〈〉 [(λz .absurd z)] + 〈〉

Page 40: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Uncurried CPS for handlers

Idea: make the continuation stack explicit (Materzok and Biernacki 2012).

Jreturn V K = λ(k :: ks).k JV K ksJlet x ← M in NK = λ(k :: ks).JMK((λx ks.JNK(k :: ks)) :: ks)

Jdo ` V K = λ(k :: h :: ks).h (` 〈JV K, h :: k :: []〉) ksJhandle M with HK = λks.JMK(JHretK :: JHopsK :: ks)J{return x 7→ N}K = λx ks.let (h :: ks ′) = ks in JNK ks

J{(` p r 7→ N`)`∈L}K = λz ks.case z {(` 〈p, s〉 7→ let r = fun s in JN`K ks)`∈L;y 7→ Mforward}

Mforward = let (k ′ :: h′ :: ks ′) = ks invmap (λ〈p, r〉 (k :: ks).k 〈p, h′ :: k ′ :: r〉 ks) y ks ′

>JMK = JMK ((λx ks.x) :: (λz ks.absurd z) :: [])

But J−K still yields the administrative redexes

>Jreturn 〈〉K = (λ(k :: ks).k 〈〉 ks) ((λx ks.x) :: (λz .absurd z) :: []) (λx ks.x) 〈〉 [(λz .absurd z)]

+ 〈〉

Page 41: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Uncurried CPS for handlers

Idea: make the continuation stack explicit (Materzok and Biernacki 2012).

Jreturn V K = λ(k :: ks).k JV K ksJlet x ← M in NK = λ(k :: ks).JMK((λx ks.JNK(k :: ks)) :: ks)

Jdo ` V K = λ(k :: h :: ks).h (` 〈JV K, h :: k :: []〉) ksJhandle M with HK = λks.JMK(JHretK :: JHopsK :: ks)J{return x 7→ N}K = λx ks.let (h :: ks ′) = ks in JNK ks

J{(` p r 7→ N`)`∈L}K = λz ks.case z {(` 〈p, s〉 7→ let r = fun s in JN`K ks)`∈L;y 7→ Mforward}

Mforward = let (k ′ :: h′ :: ks ′) = ks invmap (λ〈p, r〉 (k :: ks).k 〈p, h′ :: k ′ :: r〉 ks) y ks ′

>JMK = JMK ((λx ks.x) :: (λz ks.absurd z) :: [])

But J−K still yields the administrative redexes

>Jreturn 〈〉K = (λ(k :: ks).k 〈〉 ks) ((λx ks.x) :: (λz .absurd z) :: []) (λx ks.x) 〈〉 [(λz .absurd z)] + 〈〉

Page 42: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Higher-order CPS for handlers (I)

Idea: adopt a two level λ-calculus (Danvy and Filinski 1990; Danvy and Nielsen2003) with two kinds of continuations

Static continuations κDynamic continuations k

Correspondingly, two kinds of reductionsStatic reductions at translation timeDynamic reductions at run-time

Move between levels using reflection (↑) and reification (↓)

↓↑V = V↓(V :: VS) = V :: ↓VS

Page 43: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Higher-order CPS for handlers (II)

Two kinds of reductions: static and dynamic .

Jreturn V K = λκ :: κs.κ@ JV K @ ↓κsJlet x ← M in NK = λκ :: κs.JMK @ ((λx ks.JNK @ (κ :: ↑ks)) :: κs)

Jdo ` V K = λκ :: η :: κs.η @ (` 〈JV K, η :: κ :: []〉) @ ↓κsJhandle M with HK = λκs.JMK @ (JHretK :: JHopsK :: κs)

J{return x 7→ N}K = λx ks.let (h :: ks ′) = ks in JNK @ ↑ks ′J{(` p r 7→ N`)`∈L}K = λz ks.case z {(` 〈p, s〉 7→ let r = fun s in JN`K @ ↑ks)`∈L;

y 7→ Mforward}Mforward = let (k ′ :: h′ :: ks ′) = ks in

vmap (λ〈p, s〉 (k :: ks).k 〈p, h′ :: k ′ :: s〉 ks) y ks ′

>JMK = JMK @ ((λx ks.x) :: (λz ks.absurd z) :: ↑[])

J−K produces no statically eliminatable administrative redexes

>Jreturn 〈〉K = (λκ :: κs.κ@ 〈〉@ ↓κ) @ ((λx ks.x) :: (λz ks.absurd z) :: ↑[])

= (λx ks.x) @ 〈〉@ ↓((λz ks.absurd z) :: ↑[])= (λx ks.x) @ 〈〉@ ((λz ks.absurd z) :: []) + 〈〉

Page 44: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Higher-order CPS for handlers (II)

Two kinds of reductions: static and dynamic .

Jreturn V K = λκ :: κs.κ@ JV K @ ↓κsJlet x ← M in NK = λκ :: κs.JMK @ ((λx ks.JNK @ (κ :: ↑ks)) :: κs)

Jdo ` V K = λκ :: η :: κs.η @ (` 〈JV K, η :: κ :: []〉) @ ↓κsJhandle M with HK = λκs.JMK @ (JHretK :: JHopsK :: κs)

J{return x 7→ N}K = λx ks.let (h :: ks ′) = ks in JNK @ ↑ks ′J{(` p r 7→ N`)`∈L}K = λz ks.case z {(` 〈p, s〉 7→ let r = fun s in JN`K @ ↑ks)`∈L;

y 7→ Mforward}Mforward = let (k ′ :: h′ :: ks ′) = ks in

vmap (λ〈p, s〉 (k :: ks).k 〈p, h′ :: k ′ :: s〉 ks) y ks ′

>JMK = JMK @ ((λx ks.x) :: (λz ks.absurd z) :: ↑[])

J−K produces no statically eliminatable administrative redexes

>Jreturn 〈〉K = (λκ :: κs.κ@ 〈〉@ ↓κ) @ ((λx ks.x) :: (λz ks.absurd z) :: ↑[])

= (λx ks.x) @ 〈〉@ ↓((λz ks.absurd z) :: ↑[])= (λx ks.x) @ 〈〉@ ((λz ks.absurd z) :: []) + 〈〉

Page 45: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Higher-order CPS for handlers (II)

Two kinds of reductions: static and dynamic .

Jreturn V K = λκ :: κs.κ@ JV K @ ↓κsJlet x ← M in NK = λκ :: κs.JMK @ ((λx ks.JNK @ (κ :: ↑ks)) :: κs)

Jdo ` V K = λκ :: η :: κs.η @ (` 〈JV K, η :: κ :: []〉) @ ↓κsJhandle M with HK = λκs.JMK @ (JHretK :: JHopsK :: κs)

J{return x 7→ N}K = λx ks.let (h :: ks ′) = ks in JNK @ ↑ks ′J{(` p r 7→ N`)`∈L}K = λz ks.case z {(` 〈p, s〉 7→ let r = fun s in JN`K @ ↑ks)`∈L;

y 7→ Mforward}Mforward = let (k ′ :: h′ :: ks ′) = ks in

vmap (λ〈p, s〉 (k :: ks).k 〈p, h′ :: k ′ :: s〉 ks) y ks ′

>JMK = JMK @ ((λx ks.x) :: (λz ks.absurd z) :: ↑[])

J−K produces no statically eliminatable administrative redexes

>Jreturn 〈〉K = (λκ :: κs.κ@ 〈〉@ ↓κ) @ ((λx ks.x) :: (λz ks.absurd z) :: ↑[])

= (λx ks.x) @ 〈〉@ ↓((λz ks.absurd z) :: ↑[])= (λx ks.x) @ 〈〉@ ((λz ks.absurd z) :: []) + 〈〉

Page 46: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Higher-order CPS for handlers (II)

Two kinds of reductions: static and dynamic .

Jreturn V K = λκ :: κs.κ@ JV K @ ↓κsJlet x ← M in NK = λκ :: κs.JMK @ ((λx ks.JNK @ (κ :: ↑ks)) :: κs)

Jdo ` V K = λκ :: η :: κs.η @ (` 〈JV K, η :: κ :: []〉) @ ↓κsJhandle M with HK = λκs.JMK @ (JHretK :: JHopsK :: κs)

J{return x 7→ N}K = λx ks.let (h :: ks ′) = ks in JNK @ ↑ks ′J{(` p r 7→ N`)`∈L}K = λz ks.case z {(` 〈p, s〉 7→ let r = fun s in JN`K @ ↑ks)`∈L;

y 7→ Mforward}Mforward = let (k ′ :: h′ :: ks ′) = ks in

vmap (λ〈p, s〉 (k :: ks).k 〈p, h′ :: k ′ :: s〉 ks) y ks ′

>JMK = JMK @ ((λx ks.x) :: (λz ks.absurd z) :: ↑[])

J−K produces no statically eliminatable administrative redexes

>Jreturn 〈〉K = (λκ :: κs.κ@ 〈〉@ ↓κ) @ ((λx ks.x) :: (λz ks.absurd z) :: ↑[])

= (λx ks.x) @ 〈〉@ ↓((λz ks.absurd z) :: ↑[])= (λx ks.x) @ 〈〉@ ((λz ks.absurd z) :: []) + 〈〉

Page 47: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Higher-order CPS for handlers (II)

Two kinds of reductions: static and dynamic .

Jreturn V K = λκ :: κs.κ@ JV K @ ↓κsJlet x ← M in NK = λκ :: κs.JMK @ ((λx ks.JNK @ (κ :: ↑ks)) :: κs)

Jdo ` V K = λκ :: η :: κs.η @ (` 〈JV K, η :: κ :: []〉) @ ↓κsJhandle M with HK = λκs.JMK @ (JHretK :: JHopsK :: κs)

J{return x 7→ N}K = λx ks.let (h :: ks ′) = ks in JNK @ ↑ks ′J{(` p r 7→ N`)`∈L}K = λz ks.case z {(` 〈p, s〉 7→ let r = fun s in JN`K @ ↑ks)`∈L;

y 7→ Mforward}Mforward = let (k ′ :: h′ :: ks ′) = ks in

vmap (λ〈p, s〉 (k :: ks).k 〈p, h′ :: k ′ :: s〉 ks) y ks ′

>JMK = JMK @ ((λx ks.x) :: (λz ks.absurd z) :: ↑[])

J−K produces no statically eliminatable administrative redexes

>Jreturn 〈〉K = (λκ :: κs.κ@ 〈〉@ ↓κ) @ ((λx ks.x) :: (λz ks.absurd z) :: ↑[])

= (λx ks.x) @ 〈〉@ ↓((λz ks.absurd z) :: ↑[])= (λx ks.x) @ 〈〉@ ((λz ks.absurd z) :: []) + 〈〉

Page 48: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Higher-order CPS for handlers (II)

Two kinds of reductions: static and dynamic .

Jreturn V K = λκ :: κs.κ@ JV K @ ↓κsJlet x ← M in NK = λκ :: κs.JMK @ ((λx ks.JNK @ (κ :: ↑ks)) :: κs)

Jdo ` V K = λκ :: η :: κs.η @ (` 〈JV K, η :: κ :: []〉) @ ↓κsJhandle M with HK = λκs.JMK @ (JHretK :: JHopsK :: κs)

J{return x 7→ N}K = λx ks.let (h :: ks ′) = ks in JNK @ ↑ks ′J{(` p r 7→ N`)`∈L}K = λz ks.case z {(` 〈p, s〉 7→ let r = fun s in JN`K @ ↑ks)`∈L;

y 7→ Mforward}Mforward = let (k ′ :: h′ :: ks ′) = ks in

vmap (λ〈p, s〉 (k :: ks).k 〈p, h′ :: k ′ :: s〉 ks) y ks ′

>JMK = JMK @ ((λx ks.x) :: (λz ks.absurd z) :: ↑[])

J−K produces no statically eliminatable administrative redexes

>Jreturn 〈〉K = (λκ :: κs.κ@ 〈〉@ ↓κ) @ ((λx ks.x) :: (λz ks.absurd z) :: ↑[])= (λx ks.x) @ 〈〉@ ↓((λz ks.absurd z) :: ↑[])

= (λx ks.x) @ 〈〉@ ((λz ks.absurd z) :: []) + 〈〉

Page 49: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Higher-order CPS for handlers (II)

Two kinds of reductions: static and dynamic .

Jreturn V K = λκ :: κs.κ@ JV K @ ↓κsJlet x ← M in NK = λκ :: κs.JMK @ ((λx ks.JNK @ (κ :: ↑ks)) :: κs)

Jdo ` V K = λκ :: η :: κs.η @ (` 〈JV K, η :: κ :: []〉) @ ↓κsJhandle M with HK = λκs.JMK @ (JHretK :: JHopsK :: κs)

J{return x 7→ N}K = λx ks.let (h :: ks ′) = ks in JNK @ ↑ks ′J{(` p r 7→ N`)`∈L}K = λz ks.case z {(` 〈p, s〉 7→ let r = fun s in JN`K @ ↑ks)`∈L;

y 7→ Mforward}Mforward = let (k ′ :: h′ :: ks ′) = ks in

vmap (λ〈p, s〉 (k :: ks).k 〈p, h′ :: k ′ :: s〉 ks) y ks ′

>JMK = JMK @ ((λx ks.x) :: (λz ks.absurd z) :: ↑[])

J−K produces no statically eliminatable administrative redexes

>Jreturn 〈〉K = (λκ :: κs.κ@ 〈〉@ ↓κ) @ ((λx ks.x) :: (λz ks.absurd z) :: ↑[])= (λx ks.x) @ 〈〉@ ↓((λz ks.absurd z) :: ↑[])= (λx ks.x) @ 〈〉@ ((λz ks.absurd z) :: [])

+ 〈〉

Page 50: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Higher-order CPS for handlers (II)

Two kinds of reductions: static and dynamic .

Jreturn V K = λκ :: κs.κ@ JV K @ ↓κsJlet x ← M in NK = λκ :: κs.JMK @ ((λx ks.JNK @ (κ :: ↑ks)) :: κs)

Jdo ` V K = λκ :: η :: κs.η @ (` 〈JV K, η :: κ :: []〉) @ ↓κsJhandle M with HK = λκs.JMK @ (JHretK :: JHopsK :: κs)

J{return x 7→ N}K = λx ks.let (h :: ks ′) = ks in JNK @ ↑ks ′J{(` p r 7→ N`)`∈L}K = λz ks.case z {(` 〈p, s〉 7→ let r = fun s in JN`K @ ↑ks)`∈L;

y 7→ Mforward}Mforward = let (k ′ :: h′ :: ks ′) = ks in

vmap (λ〈p, s〉 (k :: ks).k 〈p, h′ :: k ′ :: s〉 ks) y ks ′

>JMK = JMK @ ((λx ks.x) :: (λz ks.absurd z) :: ↑[])

J−K produces no statically eliminatable administrative redexes

>Jreturn 〈〉K = (λκ :: κs.κ@ 〈〉@ ↓κ) @ ((λx ks.x) :: (λz ks.absurd z) :: ↑[])= (λx ks.x) @ 〈〉@ ↓((λz ks.absurd z) :: ↑[])= (λx ks.x) @ 〈〉@ ((λz ks.absurd z) :: []) + 〈〉

Page 51: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Correctness

Definition (Translation of evaluation contexts)

J[ ]K = λκs. κsJlet x ← E in NK = λκ :: κs. JEK @ ((λx ks.JNK @ (k :: ↑ks)) :: κs)

Jhandle E with HK = λκs. JEK @ (JHretK :: JHopsK :: κs)

Lemma (Decomposition)The characteristic property of the CPS translation on evaluation contexts

JE [M]K @ (V :: VS) = JMK @ (JEK @ (V :: VS))

Theorem (Simulation)If M N then >JMK + ∗

a >JNK.

Page 52: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

Conclusions

In summaryhandlers provide a modular abstraction for user-defined computational effects,first full CPS translations for handlers,the first-order curried CPS is neat, but inpractical,and the first-order uncurried CPS is naïve,refectified by a higher-order uncurried CPS.

Full details in the paper along witha discussion on the implementation of the higher-order CPS,a sketch of a typed higher-order CPS translation,an adaptation to accommodate shallow handlers,and a discussion on adapting the translation to a language like OCaml.

An implementation is available in Links

https://github.com/links-lang/links

Page 53: Continuation Passing Style for Effect Handlers - Formal ... · ContinuationPassingStyleforEffectHandlers FormalStructuresforComputationandDeduction Daniel Hillerström 1SamLindley

References

Danvy, Olivier and Andrzej Filinski (1990). “Abstracting Control”. In: LISP andFunctional Programming, pp. 151–160.

Danvy, Olivier and Lasse R. Nielsen (2003). “A first-order one-pass CPStransformation”. In: Theor. Comput. Sci. 308.1-3, pp. 239–257.

Cooper, Ezra et al. (2006). “Links: Web Programming Without Tiers”. In:FMCO. Vol. 4709. LNCS. Springer, pp. 266–296.

Materzok, Marek and Dariusz Biernacki (2012). “A Dynamic Interpretation of theCPS Hierarchy”. In: APLAS. Vol. 7705. LNCS. Springer, pp. 296–311.

Hillerström, Daniel and Sam Lindley (2016). “Liberating effects with rows andhandlers”. In: TyDe@ICFP. ACM, pp. 15–27.