States `s: k |> e, k <| v
State transition function ` s |—> s’ Stacks ` k ::= empty | k ; f Frames ` f ::= … (depends on the language)
Example: IfLang
e ::= (e1 + e2) | num n | bool b | if e e1 e2
f ::= (_ + e2) | (n + _) | (if _ e1 e2)
So far, we have been using these as a meta-level tool for implementing operational semantics. Why?
Internalizing meta-language features is a common thing to do in PL design when it comes to enriching expressiveness, enabling well-principled and expressive programming idioms. When we internalize a feature, sometimes we call that making the feature “first-class” (as opposed to a notion that is separate from expressions in the language). We will now explore this concept for the meta-language feature of stacks by introducing first-class continuations.
New type: `` tau ::= … | Cont tau
New expressions: `` e ::= … | cont(k) | throw e1 => e2 | letcc x. e
New frames: `` f ::= … | throw _ => e2 | throw v => _
Operational semantics (state transition rules):
k |> cont(k') |-----> k <| cont(k')
k |> letcc x.e |-----> k |> [cont(k)/x] e
k |> throw e1 => e2 |-----> k; throw _ => e2 |> e1
k; throw _ => e2 <| v |---> k; throw v => _ |> e2
k; throw v => _ <| cont(k') |---> k' <| v