Now let's look at an application that uses all three
of these extensions to describe a kind of effects
analysis/inference for a language with region based
allocation of global heap. In this simple example,
we will assume that there are just three primitives:
We will also assume that these primitives are set up for
use in a monadic framework. (It would be easy to handle
languages where the underlying monad is implicit using
a simple syntax-directed translation prior to this stage.)
Notice that we define a separate class for each one of these
functions, each one associating a region "r" with a monad "m"
in which the computation happened, and with a particular
action in that context: an Alloc, a Read, or a Write.
Note that "Ref" cells are also tagged with an "r" parameter
to indicate the region in which they were allocated, as well
as the type of the value that they hold.
- a "new" operator to allocate a new reference cell in
some region of memory.
- a "get" operator to fetch the contents of a reference
- a "set" operator to store a value in a reference cell.