Continuations, first blood
You've got some experience under your belt now implementing programming languages. You've done a Lisp-like language with simple syntax but some complicated function action. You've done a turtle graphics imperative language. Basically you are a total rock star.
But there are still many more cool features you want to implement in your languages. To take your game up to the next level we need to cover continuations.
Continuations will let us:
- write programs in the target language that can handle any level of recursion
- implement more complex control flow such as
catchblocks with exceptions
- implement cool features like coroutines, threads, and distributed computation
In these exercises we'll start to play around with continuations.
Making things data structures
So far we've been building interpreters
evalScheem that pass around an explicit environment and recursively
call themselves as needed. This environment that is getting passed
around is an abstraction around the general idea of variable bindings.
By keeping the target
language environment as a data structure we keep the way the environment
works very explicit. When we
evaluate an expression like
(+ (f 2) (f 3)) we end up evaluating the
same body of
f in two different environments. Having the environment
as a parameter to the evaluation function makes it clear what is going
on and keeps things organized.
Continuations are a way to convert control flow in the evaluation function into an explicit data structure. Just like the environment turned variable bindings into a data structure, continuations turn control flow into a data structure. Once the control flow is encoded in a data structure we can do all kinds of fun things with it.