- 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.

**data****Expr****=****Num****Integer****|****Var****Name****|****Add****Expr****Expr****|****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

**data****Expr****=****Num****Integer****|****Var****Name****|****Add****Expr****Expr****|****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.

**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 function).
`eval`

- Another possibility:
`eval`**::****Env****->****Expr****->****Maybe****Value**- But it would make our small language strict (eager)…

- 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, in Haskell)
**\**`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)

dataExpr=NumInteger|VarName|AddExprExpr|MulExprExpr|EqualExprExpr|AppExprExpr-- new|LambdaNameExpr-- new

- 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…?

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

evalenv(Appfunarg)=apply(evalenvfun) (evalenvarg)evalenv(Lambdaxbody)=F(\v->eval((x:v):env)body)apply::Value->Value->Valueapply(Ff)v=fvapply__=E"non-function applied to an argument"

- 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!

initial_env=[("false",BFalse), ("true",BTrue), ("if",(...)), ("pred",(...))]

- Recursive functions in Haskell
`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`

?

- 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!

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

Multiple arguments: `\x y -> e`

⟹ `\x -> \y -> e`

Function definitions: `f x y z = e`

⟹ `f = \ x y z -> e`

Local definitions: `let x = e1 in e2`

⟹ `(\x->e2) e1`

- Changes in the parser (and perhaps the show functions)
- The type and the
**Expr**functions are unchanged.`eval`

- The

- Add a command to load definitions from a file
- Refactor …
`readEvalPrintLoop`

- Refactor

- How To Write an Interpreter for a Lambda-Calculus-Based Language:
- a blog post covering similar things as this lecture.
- (added 2017-12-21)