---
tags: programming languages
---
# A Calculator: The Interpreter
To continue from the previous lecture, the task is to give a formal definition of abstract syntax and then write an intepreter.
Recall our example. Instead of writing
```
5*((4+3)*2+1)
```
in concrete syntax, we will write the same in abstract syntax as
```haskell
Times (Num 5) (Plus (Times (Plus (Num 4) (Num 3)) (Num 2)) (Num 1))
```
In Haskell, we can define a data type for abstract syntax that comprises exactly all arithmetic expressions built from numbers, plus and times as follows.
```haskell
data Exp = Plus Exp Exp | Times Exp Exp | Num Integer
```
Now this is a bit tricky. We have seen recursive definitions of functions. But this is a recursive definition of a data type, a so-called **algebraic data type**. To understand the definition we need to know the following.
- `data` is a key word, indicating a user-defined data type.
- `Exp` is the name of the user-defined data type.
- `|` can be read as an "or". It shows us that there are three different cases that can be used to build an element of type `Exp`.
- `Plus`, `Times`, `Num` are user defined names. They are called *constructors*, but really are just labels that allow the pattern matching algorithm of Haskell to distinguish the three cases.
- `Integer` is a predefined Haskell data type for aribtrary-precision integers.
**Activity:** Can you start listing all elements of type `Exp`?
Now it is easy to write an interpreter. We just need to define a recursive function that evaluates the three cases. Since Haskell already knows about Integers, plus and times we rely on this.
```haskell
eval :: Exp -> Integer
eval (Num n) = n
eval (Plus n m) = (eval n) + (eval m)
eval (Times n m) = (eval n) * (eval m)
```
**Remark:** Why is this so simple?
- Haskell allows us to write elegant algorithms that work by recursion over algebraic data types.
- Using abstract syntax, we were able to separate evaluation from two difficult tasks (parsing and arithmetic). In particular, Haskell already knows how to do arithmetic (`+` and `*` in the example).
## <font color=red>Homework</font>
To see how to put everything together have a look at [replit](https://replit.com/@alexhkurz/calculator-interpreter#main.hs). If you want to change the code you need to fork it or to copy it on your local machine.
- Run your own test cases of the interpreter.
- Extend the calculator/interpreter so that it can handle subtraction and division.
- (Optional) Instead of using built-in lists, we can define lists as our own algebraic data type as follows.
data List a = Nil | Cons a List
`a` is a type variable, denoting the type of the elements in the list. `Nil` plays the same role as `[]`. And `Cons` plays the same role as `:`, just that here we do not write it in infix but in prefix notation.
The exercise is now to rewrite some of the programs from the [previous session](https://hackmd.io/@alexhkurz/H1jUka4Gv) that worked by recursion over lists with this new definition of lists.