If expressions can have more than one type, how does this change our “little programming language” implementation?

Need a type to represent *values* in the program, e.g. `5`

, `true`

Representing programs:

```
type expr = <arith> | <bool> | <compare> | <let> | <if>
type expType = IntT | BoolT
type result = IntR | BoolR
```

What about supporting imperative programs?

Assignment | `Set of string * expr (* variable, value *)` |

Loops | `While of expr * expr (* condition, body *)` |

Sequences | `Seq of expr list (* exprs to execute *)` |

Lexical *environment* becomes a *store* that is part of the result of each operation:

The store is then given as an argument to the next operation:

`While`

```
let rec eval exp state = match exp with ...
| While(cond,body) -> evalWhile cond body st
...
and evalWhile cond body st =
let (cond_res,st') = eval cond st in let (BoolR b) = cond_res in
if (not b) then (UnitR, st')
else let (_,st'') = eval body st' in
evalWhile cond body st''
(* tail recursion again *)
```

What should the “result” of a `while`

loop be?

Consider eg. `While (BoolC false, <anything>)`

…

Type checking…

While:

`c : BoolT`

`b : τ`

`While (c, b) : UnitT`

Set:

`(n : τ) ⊦ (v : τ)`

`Set (n, v) : Unit`

Seq:

`Seq []: UnitT`

`e : τ ⇒ Seq([e]) : τ`

`h : τ ∧ Seq(t) : τ₁ ⇒ Seq (h::t) : τ₁`

Examples:

```
let p2 = Let("x", IntC 1,
While (BoolC true,
Seq[
Set("x", Add(Name "x", IntC 1));
Set("x", Mul(Name "x", Name "x"))
]))
```

Note: Because type (and name) analysis is *static*, type checking halts even though the program does not…

`cs2041.org`