Page 1

Page 2

# Why implement a functional language in a functional language?

• The fact that we can do it in one lecture shows the power of functional languages.
• It's an exercise that combines several of the things we have seen earlier in the course.
• It could give some insights into how functional languages work.
Page 3

# Symbolic Expressions

## Remember this from last week?

• ```data Expr = Num Integer
| Var Name
| Mul Expr Expr

type Name = String```
• `eval :: [(Name,Integer)] -> Expr -> Integer`
• Can we extend it with support for more types of values? And functions?
• Live demo: SmallFunctionalLanguage.hs
Page 4

• ```data Expr = Num Integer
| Var Name
| Mul Expr Expr
| Equal Expr Expr     -- new
```
• Adding support for boolean values:
• `data Value = N Integer | B Bool`
• `eval :: [(Name,Value)] -> Expr -> Value`
• Also need to extend the parser and show functions.
Page 5

• `data Value = N Integer | B Bool | E String`
• `eval :: [(Name,Value)] -> Expr -> Value`
• Note: we are creating a dynamically typed language.
• We will not write a type checker.
• Type errors (and other errors) will be reported dynamically (by the
`eval`
function).
• Another possibility:
`eval :: Env -> Expr -> Maybe Value`
• But it would make our small language strict (eager)…
Page 6

## The λ-calculus (lambda calculus)

• This is the core of functional programming languages.
• expr ::= name | expr expr | λ name . expr
• It's a very simple language that only has
• Variables
• Function application
• Lambda abstraction (anonymous functions,
`\ x -> e`
• Example:
`(\f -> \x -> f (f x)) (\n -> 2*n) 1`
• Numbers, booleans and other data types can be encoded in the lambda calculus, no extensions are needed. (Church encoding)
Page 7

# Adding functions to our small language

```data Expr = Num Integer
| Var Name
| Mul Expr Expr
| Equal Expr Expr
| App Expr Expr      -- new
| Lambda Name Expr   -- new
```
Page 8

# Adding functions to our Value types?

## How do we represent the value of an anonymous function?

• Numbers in our language are represented by Haskell type
`Integer`
.
• Booleans in our language are represented by the Haskell type
`Bool`
.
• So functions in our language are represented by…?
Page 9

# Adding functions to our Value types

• Functions in our language are represented by the Haskell type for functions!
• `data Value = N Integer | B Bool | F (Value->Value) | E String`
Page 10

# Computing with functions

```eval env (App fun arg)   = apply (eval env fun) (eval env arg)
eval env (Lambda x body) = F (\ v -> eval ((x:v):env) body)

apply :: Value -> Value -> Value
apply (F f) v = f v
apply _     _ = E "non-function applied to an argument"```
Page 11

# Testing our small functional language

• Welcome to the small functional language! > `twice = \ f -> \ x -> f (f x)` > `double = \ x -> 2*x` > `twice double x` 4
• It works!
• Including higher order functions!
Page 12

# Adding some predefined values in our environment

```initial_env = [("false",B False),
("true",B True),
("if",(...)),
("pred",(...))]
```
Page 13

# Recursive functions

• ```fac n = if n==0 then 1 else n*fac (n-1)
```
• A fix-point operator
• ```fix f = f (fix f)
```
• A non-recursive definition of `fac`
• ```fac = fix (\f -> if n==0 then 1 else n*f (n-1))
```
• A non-recursive definition of `fix`?
Page 14

# Testing recursive functions

• Welcome to the small functional language! > `fix = \f -> (\x->f (x x)) (\x->f (x x))` > `fac = fix (\f->\n->if (n==0) 1 (f (pred n)))` > `fac 5` 120
• It works!
Page 15

# Possible improvements

• Nicer syntax
• We can add some syntactic sugar to make our language nicer

Multiple arguments: Function definitions:  Local definitions: `\x y -> e` ⟹ `\x -> \y -> e` `f x y z = e` ⟹ `f = \ x y z -> e` `let x = e1 in e2` ⟹ `(\x->e2) e1`
• Changes in the parser (and perhaps the show functions)
• The
`Expr`
type and the
`eval`
functions are unchanged.
`readEvalPrintLoop`