Download Interpreters for two simple languages – including exercises

Document related concepts

Lambda lifting wikipedia , lookup

Scala (programming language) wikipedia , lookup

Lambda calculus definition wikipedia , lookup

Intuitionistic type theory wikipedia , lookup

Falcon (programming language) wikipedia , lookup

Standard ML wikipedia , lookup

C Sharp (programming language) wikipedia , lookup

Transcript
02157 Functional Programming
02157
Functional
Programming
Michael R. Ha
Interpreters for two simple languages
– including exercises
Michael R. Hansen
Interpreters for two simple languages, – including exercises
1
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Overview
02157
Functional
Programming
Michael R. Ha
• Miscellaneous
• Value Restriction Polymorphism
• On type declarations — Type abbreviations and ”real” types
• On simplifying programs — using the expression language
• Finite trees: Two examples
• An interpreter for a simple expression language
• An interpreter for a simple while-language
Interpreters for two simple languages, – including exercises
2
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Examples on errors with polymorphic functions (1)
02157
Functional
Programming
Michael R. Ha
let empty = [] @ [];;
stdin(3,5): error FS0030: Value restriction.
The value ’empty’ has been inferred to have generic type
val empty : ’_a list
Interpreters for two simple languages, – including exercises
3
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Examples on errors with polymorphic functions (1)
02157
Functional
Programming
Michael R. Ha
let empty = [] @ [];;
stdin(3,5): error FS0030: Value restriction.
The value ’empty’ has been inferred to have generic type
val empty : ’_a list
Either define ’empty’ as a simple data term,
make it a function with explicit arguments or,
if you do not intend for it to be generic,
add a type annotation.
Interpreters for two simple languages, – including exercises
4
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Examples on errors with polymorphic functions (1)
02157
Functional
Programming
Michael R. Ha
let empty = [] @ [];;
stdin(3,5): error FS0030: Value restriction.
The value ’empty’ has been inferred to have generic type
val empty : ’_a list
Either define ’empty’ as a simple data term,
make it a function with explicit arguments or,
if you do not intend for it to be generic,
add a type annotation.
let empty = [];; // THIS WORKS!
val empty : ’a list
Interpreters for two simple languages, – including exercises
5
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Examples on errors with polymorphic functions (2)
02157
Functional
List.rev [];;
Programming
stdin(5,1): error FS0030: Value restriction.
The value ’it’ has been inferred to have generic type Michael R. Ha
val it : ’_a list
Interpreters for two simple languages, – including exercises
6
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Examples on errors with polymorphic functions (2)
02157
Functional
List.rev [];;
Programming
stdin(5,1): error FS0030: Value restriction.
The value ’it’ has been inferred to have generic type Michael R. Ha
val it : ’_a list
Either define ’it’ as a simple data term,
make it a function with explicit arguments or,
if you do not intend for it to be generic,
add a type annotation.
Interpreters for two simple languages, – including exercises
7
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Examples on errors with polymorphic functions (2)
02157
Functional
List.rev [];;
Programming
stdin(5,1): error FS0030: Value restriction.
The value ’it’ has been inferred to have generic type Michael R. Ha
val it : ’_a list
Either define ’it’ as a simple data term,
make it a function with explicit arguments or,
if you do not intend for it to be generic,
add a type annotation.
List.rev ([]: int list);;
val it : int list = []
// THIS WORKS!
Interpreters for two simple languages, – including exercises
8
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Examples on errors with polymorphic functions (2)
02157
Functional
List.rev [];;
Programming
stdin(5,1): error FS0030: Value restriction.
The value ’it’ has been inferred to have generic type Michael R. Ha
val it : ’_a list
Either define ’it’ as a simple data term,
make it a function with explicit arguments or,
if you do not intend for it to be generic,
add a type annotation.
List.rev ([]: int list);;
val it : int list = []
// THIS WORKS!
• a top-level expression is considered a top-level declaration of it:
let it = List.rev ([]: int list);;
val it : int list = []
Interpreters for two simple languages, – including exercises
9
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Examples on errors with polymorphic functions (3)
let f = List.map (fun x -> (x,x));;
stdin(15,5): error FS0030: Value restriction
The value ’f’ has been inferred to have generic type
val f : (’_a list -> (’_a * ’_a) list)
Interpreters for two simple languages, – including exercises
10
DTU Compute, Technical University of Denmark
02157
Functional
Programming
Michael R. Ha
MRH
11/10/2016
Examples on errors with polymorphic functions (3)
let f = List.map (fun x -> (x,x));;
stdin(15,5): error FS0030: Value restriction
The value ’f’ has been inferred to have generic type
val f : (’_a list -> (’_a * ’_a) list)
02157
Functional
Programming
Michael R. Ha
Either make the arguments to ’f’ explicit or
if you do not intend for it to be generic,
add a type annotation.
Interpreters for two simple languages, – including exercises
11
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Examples on errors with polymorphic functions (3)
let f = List.map (fun x -> (x,x));;
stdin(15,5): error FS0030: Value restriction
The value ’f’ has been inferred to have generic type
val f : (’_a list -> (’_a * ’_a) list)
02157
Functional
Programming
Michael R. Ha
Either make the arguments to ’f’ explicit or
if you do not intend for it to be generic,
add a type annotation.
let f xs = List.map (fun x -> (x,x)) xs;;
val f : xs:’a list -> (’a * ’a) list
// THIS WORKS!
Interpreters for two simple languages, – including exercises
12
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Examples on errors with polymorphic functions (3)
let f = List.map (fun x -> (x,x));;
stdin(15,5): error FS0030: Value restriction
The value ’f’ has been inferred to have generic type
val f : (’_a list -> (’_a * ’_a) list)
02157
Functional
Programming
Michael R. Ha
Either make the arguments to ’f’ explicit or
if you do not intend for it to be generic,
add a type annotation.
let f xs = List.map (fun x -> (x,x)) xs;;
val f : xs:’a list -> (’a * ’a) list
// THIS WORKS!
• What is the problem solved by this restriction?
• What is the solution to this problem?
Interpreters for two simple languages, – including exercises
13
DTU Compute, Technical University of Denmark
MRH
11/10/2016
An ”imperative” issue with Polymorphism
02157
Functional
Programming
• A type issue to be addressed in the imperative fragment of F#.
Michael R. Ha
The following hypothetical code does NOT compile:
let mutable a = []
// let a = ref []
let f x = a <- x::a
val f: ’a -> unit
f 1;;
f "ab";;
a;;
val it :
???? list = ["ab";1] // a BIG type problem
Interpreters for two simple languages, – including exercises
14
DTU Compute, Technical University of Denmark
MRH
11/10/2016
A solution: Value Restriction on Polymorphism
A value expression is an expression that is not reduced further by an
evaluation, for example:
[]
Some []
Michael
R. Ha
fun xs -> List.map (fun x -> (x,x))
xs
Interpreters for two simple languages, – including exercises
15
DTU Compute, Technical University of Denmark
02157
Functional
Programming
MRH
11/10/2016
A solution: Value Restriction on Polymorphism
A value expression is an expression that is not reduced further by an
evaluation, for example:
[]
Some []
02157
Functional
Programming
Michael
R. Ha
fun xs -> List.map (fun x -> (x,x))
xs
The following are not value expressions:
[]@[]
List.rev []
List.map (fun x -> (x,x))
as they can be further evaluated.
Interpreters for two simple languages, – including exercises
16
DTU Compute, Technical University of Denmark
MRH
11/10/2016
A solution: Value Restriction on Polymorphism
A value expression is an expression that is not reduced further by an
evaluation, for example:
[]
Some []
02157
Functional
Programming
Michael
R. Ha
fun xs -> List.map (fun x -> (x,x))
xs
The following are not value expressions:
[]@[]
List.rev []
List.map (fun x -> (x,x))
as they can be further evaluated.
Every top-level declarations let id = e is subject to the following
restriction on e:
• All monomorphic expressions are OK,
• all value expressions are OK, even polymorphic ones, and
• at top-level, polymorphic non-value expressions are forbidden
Interpreters for two simple languages, – including exercises
17
DTU Compute, Technical University of Denmark
MRH
11/10/2016
A solution: Value Restriction on Polymorphism
A value expression is an expression that is not reduced further by an
evaluation, for example:
[]
Some []
02157
Functional
Programming
Michael
R. Ha
fun xs -> List.map (fun x -> (x,x))
xs
The following are not value expressions:
[]@[]
List.rev []
List.map (fun x -> (x,x))
as they can be further evaluated.
Every top-level declarations let id = e is subject to the following
restriction on e:
• All monomorphic expressions are OK,
• all value expressions are OK, even polymorphic ones, and
• at top-level, polymorphic non-value expressions are forbidden
An expresssion e in a declaration of the form
let mutable id = e or equivalently let id = ref e
is NOT considered a value expression (even when e is a constant)
Interpreters for two simple languages, – including exercises
18
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Examples revisited
A polymorphic value expression:
let empty = [];; // THIS WORKS!
val empty : ’a list
Interpreters for two simple languages, – including exercises
19
DTU Compute, Technical University of Denmark
02157
Functional
Programming
Michael R. Ha
MRH
11/10/2016
Examples revisited
A polymorphic value expression:
let empty = [];; // THIS WORKS!
val empty : ’a list
02157
Functional
Programming
Michael R. Ha
A monomorphic expression, that is not a value expression:
List.rev ([]: int list);;
val it : int list = []
// THIS WORKS!
Interpreters for two simple languages, – including exercises
20
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Examples revisited
A polymorphic value expression:
let empty = [];; // THIS WORKS!
val empty : ’a list
02157
Functional
Programming
Michael R. Ha
A monomorphic expression, that is not a value expression:
List.rev ([]: int list);;
val it : int list = []
// THIS WORKS!
A declaration of a function with an explicit parameter
Interpreters for two simple languages, – including exercises
21
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Examples revisited
02157
Functional
Programming
A polymorphic value expression:
let empty = [];; // THIS WORKS!
val empty : ’a list
Michael R. Ha
A monomorphic expression, that is not a value expression:
List.rev ([]: int list);;
val it : int list = []
// THIS WORKS!
A declaration of a function with an explicit parameter
let f xs = List.map (fun x -> (x,x)) xs;;
val f : xs:’a list -> (’a * ’a) list
// THIS WORKS!
Interpreters for two simple languages, – including exercises
22
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Examples revisited
02157
Functional
Programming
A polymorphic value expression:
let empty = [];; // THIS WORKS!
val empty : ’a list
Michael R. Ha
A monomorphic expression, that is not a value expression:
List.rev ([]: int list);;
val it : int list = []
// THIS WORKS!
A declaration of a function with an explicit parameter
let f xs = List.map (fun x -> (x,x)) xs;;
val f : xs:’a list -> (’a * ’a) list
// THIS WORKS!
is an abbreviation for
let f = fun xs -> List.map (fun x -> (x,x)) xs;;
and a closure is a value expression
Interpreters for two simple languages, – including exercises
23
DTU Compute, Technical University of Denmark
MRH
11/10/2016
On type declarations (1)
A tagged-value type like T1:
type T1 = | A of int | B of bool
Michael R. Ha
is a real new type.
Interpreters for two simple languages, – including exercises
24
DTU Compute, Technical University of Denmark
02157
Functional
Programming
MRH
11/10/2016
On type declarations (1)
A tagged-value type like T1:
type T1 = | A of int | B of bool
02157
Functional
Programming
Michael R. Ha
is a real new type.
This type is different from the type T2:
type T2 = | A of int | B of bool;;
let v1 = T1.A(2);;
let v2 = T2.A(2);;
Interpreters for two simple languages, – including exercises
25
DTU Compute, Technical University of Denmark
MRH
11/10/2016
On type declarations (1)
A tagged-value type like T1:
type T1 = | A of int | B of bool
02157
Functional
Programming
Michael R. Ha
is a real new type.
This type is different from the type T2:
type T2 = | A of int | B of bool;;
let v1 = T1.A(2);;
let v2 = T2.A(2);;
v1=v2;;
... error ... : This expression was expected to have type
T1
but here has type
T2
Interpreters for two simple languages, – including exercises
26
DTU Compute, Technical University of Denmark
MRH
11/10/2016
On type declarations (1)
A tagged-value type like T1:
type T1 = | A of int | B of bool
02157
Functional
Programming
Michael R. Ha
is a real new type.
This type is different from the type T2:
type T2 = | A of int | B of bool;;
let v1 = T1.A(2);;
let v2 = T2.A(2);;
v1=v2;;
... error ... : This expression was expected to have type
T1
but here has type
T2
• Values of type T1 and T2 cannot be compared
— the types are, in fact, different.
• A similar observation applies for records.
Interpreters for two simple languages, – including exercises
27
DTU Compute, Technical University of Denmark
MRH
11/10/2016
On type declarations (2)
The other kinds of type declarations we have considered so far
define type abbreviations. For example, the types TA1 and TA2:
type TA1 = int * bool;;
type TA2 = int * bool;;
02157
Functional
Programming
Michael R. Ha
are identical and just shorthands for int * bool.
Interpreters for two simple languages, – including exercises
28
DTU Compute, Technical University of Denmark
MRH
11/10/2016
On type declarations (2)
The other kinds of type declarations we have considered so far
define type abbreviations. For example, the types TA1 and TA2:
type TA1 = int * bool;;
type TA2 = int * bool;;
02157
Functional
Programming
Michael R. Ha
are identical and just shorthands for int * bool.
For example:
let
val
let
val
let
val
v1
v1
v2
v2
v3
v3
=
:
=
:
=
:
(1,true):TA1;;
TA1 = (1, true)
(1,true):TA2;;
TA2 = (1, true)
(1,true):int*bool;;
int * bool = (1, true)
v1=v2;;
val it : bool = true
v2=v3;;
val it : bool = true
Interpreters for two simple languages, – including exercises
29
DTU Compute, Technical University of Denmark
MRH
11/10/2016
On type declarations (3)
Type declarations, including type abbreviations, often have a
pragmatic role. For example, succinct way of presenting a model:
type
type
type
type
CourseNo
Title
ECTS
CourseDesc
=
=
=
=
int
string
int
Title * ECTS
02157
Functional
Programming
Michael R. Ha
type CourseBase = Map<CourseNo, CourseDesc>
type Mandatory
= Set<CourseNo>
type Optional
= Set<CourseNo>
type CourseGroup = Mandatory * Optional
Interpreters for two simple languages, – including exercises
30
DTU Compute, Technical University of Denmark
MRH
11/10/2016
On type declarations (3)
Type declarations, including type abbreviations, often have a
pragmatic role. For example, succinct way of presenting a model:
type
type
type
type
CourseNo
Title
ECTS
CourseDesc
=
=
=
=
int
string
int
Title * ECTS
02157
Functional
Programming
Michael R. Ha
type CourseBase = Map<CourseNo, CourseDesc>
type Mandatory
= Set<CourseNo>
type Optional
= Set<CourseNo>
type CourseGroup = Mandatory * Optional
or the purpose of a function like
isValidCourseGroup: CourseGroup -> CourseBase -> bool
Interpreters for two simple languages, – including exercises
31
DTU Compute, Technical University of Denmark
MRH
11/10/2016
On type declarations (3)
Type declarations, including type abbreviations, often have a
pragmatic role. For example, succinct way of presenting a model:
type
type
type
type
CourseNo
Title
ECTS
CourseDesc
=
=
=
=
int
string
int
Title * ECTS
02157
Functional
Programming
Michael R. Ha
type CourseBase = Map<CourseNo, CourseDesc>
type Mandatory
= Set<CourseNo>
type Optional
= Set<CourseNo>
type CourseGroup = Mandatory * Optional
or the purpose of a function like
isValidCourseGroup: CourseGroup -> CourseBase -> bool
The expanded type for this function is NOT “enriching”:
(Set<int>*Set<int>) -> Map<int,string*int> -> bool
Interpreters for two simple languages, – including exercises
32
DTU Compute, Technical University of Denmark
MRH
11/10/2016
On “simplifying” programs (1)
Programs with the following flavour are too often observed:
let f x =
match x with
|(a,z) -> if not a then true
else if fst z then snd z
else false;;
Interpreters for two simple languages, – including exercises
33
DTU Compute, Technical University of Denmark
02157
Functional
Programming
Michael R. Ha
MRH
11/10/2016
On “simplifying” programs (1)
Programs with the following flavour are too often observed:
let f x =
match x with
|(a,z) -> if not a then true
else if fst z then snd z
else false;;
02157
Functional
Programming
Michael R. Ha
• What is the type of f ?
• What is f computing?
Interpreters for two simple languages, – including exercises
34
DTU Compute, Technical University of Denmark
MRH
11/10/2016
On “simplifying” programs (1)
Programs with the following flavour are too often observed:
let f x =
match x with
|(a,z) -> if not a then true
else if fst z then snd z
else false;;
02157
Functional
Programming
Michael R. Ha
• What is the type of f ?
• What is f computing?
Some rules of thump:
• A match with just one clause can be avoided
• Use of fst and snd is avoided using patterns
• if-then-else expressions having Boolean values are avoided
using Boolean expressions
Interpreters for two simple languages, – including exercises
35
DTU Compute, Technical University of Denmark
MRH
11/10/2016
On “simplifying” programs (2)
Programs with the following flavour are too often observed:
02157
Functional
Programming
let f x = match x with
|(a,z) -> if not a then true
Michael R. Ha
else if fst z then snd z else false;;
Avoid match:
let f(a,z) = if not a then true
else if fst z then snd z else false;;
Interpreters for two simple languages, – including exercises
36
DTU Compute, Technical University of Denmark
MRH
11/10/2016
On “simplifying” programs (2)
Programs with the following flavour are too often observed:
02157
Functional
Programming
let f x = match x with
|(a,z) -> if not a then true
Michael R. Ha
else if fst z then snd z else false;;
Avoid match:
let f(a,z) = if not a then true
else if fst z then snd z else false;;
Avoid fst and snd:
let f(a,(b,c)) = if not a then true
else if b then c else false;;
Interpreters for two simple languages, – including exercises
37
DTU Compute, Technical University of Denmark
MRH
11/10/2016
On “simplifying” programs (2)
Programs with the following flavour are too often observed:
02157
Functional
Programming
let f x = match x with
|(a,z) -> if not a then true
Michael R. Ha
else if fst z then snd z else false;;
Avoid match:
let f(a,z) = if not a then true
else if fst z then snd z else false;;
Avoid fst and snd:
let f(a,(b,c)) = if not a then true
else if b then c else false;;
if p then q else false
is the same as
p && q:
let f(a,(b,c)) = if not a then true else b && c;;
Interpreters for two simple languages, – including exercises
38
DTU Compute, Technical University of Denmark
MRH
11/10/2016
On “simplifying” programs (2)
Programs with the following flavour are too often observed:
02157
Functional
Programming
let f x = match x with
|(a,z) -> if not a then true
Michael R. Ha
else if fst z then snd z else false;;
Avoid match:
let f(a,z) = if not a then true
else if fst z then snd z else false;;
Avoid fst and snd:
let f(a,(b,c)) = if not a then true
else if b then c else false;;
if p then q else false
is the same as
p && q:
let f(a,(b,c)) = if not a then true else b && c;;
if p then true else q
is the same as
p || q:
let f(a,(b,c)) = not a || b && c;;
Interpreters for two simple languages, – including exercises
39
DTU Compute, Technical University of Denmark
MRH
11/10/2016
On “simplifying” programs (3)
02157
Functional
Programming
Michael R. Ha
let f(a,(b,c)) = not a || b && c;;
• The type of f is bool*(bool*bool) -> bool
• f (a, (b, c)) is the value of the proposition “a implies (b and c)”
Interpreters for two simple languages, – including exercises
40
DTU Compute, Technical University of Denmark
MRH
11/10/2016
On “simplifying” programs (3)
02157
Functional
Programming
Michael R. Ha
let f(a,(b,c)) = not a || b && c;;
• The type of f is bool*(bool*bool) -> bool
• f (a, (b, c)) is the value of the proposition “a implies (b and c)”
Introducing implication:
let (.=>) p q = not p || q;;
let f(a,(b,c)) = a .=> (b && c);;
Interpreters for two simple languages, – including exercises
41
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Interpreters for two simple languages — Purpose
To show the power of a functional programming language, we
present a prototype for interpreters for a simple expression language
with local declarations and a simple WHILE language.
Interpreters for two simple languages, – including exercises
42
DTU Compute, Technical University of Denmark
02157
Functional
Programming
Michael R. Ha
MRH
11/10/2016
Interpreters for two simple languages — Purpose
To show the power of a functional programming language, we
present a prototype for interpreters for a simple expression language
with local declarations and a simple WHILE language.
02157
Functional
Programming
Michael R. Ha
• Concrete syntax: defined by a contextfree grammar
Interpreters for two simple languages, – including exercises
43
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Interpreters for two simple languages — Purpose
To show the power of a functional programming language, we
present a prototype for interpreters for a simple expression language
with local declarations and a simple WHILE language.
02157
Functional
Programming
Michael R. Ha
• Concrete syntax: defined by a contextfree grammar
• Abstract syntax (parse trees): defined by algebraic datatypes
Interpreters for two simple languages, – including exercises
44
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Interpreters for two simple languages — Purpose
To show the power of a functional programming language, we
present a prototype for interpreters for a simple expression language
with local declarations and a simple WHILE language.
02157
Functional
Programming
Michael R. Ha
• Concrete syntax: defined by a contextfree grammar
• Abstract syntax (parse trees): defined by algebraic datatypes
• Semantics, i.e. meaning of programs: inductively defined
following the structure of the abstract syntax
succinct programs, fast prototyping
Interpreters for two simple languages, – including exercises
45
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Interpreters for two simple languages — Purpose
To show the power of a functional programming language, we
present a prototype for interpreters for a simple expression language
with local declarations and a simple WHILE language.
02157
Functional
Programming
Michael R. Ha
• Concrete syntax: defined by a contextfree grammar
• Abstract syntax (parse trees): defined by algebraic datatypes
• Semantics, i.e. meaning of programs: inductively defined
following the structure of the abstract syntax
succinct programs, fast prototyping
The interpreter for the simple expression language is a higher-order
function:
eval : Program → Environment → Value
The interpreter for a simple imperative programming language is a
higher-order function:
I : Program → State → State
Interpreters for two simple languages, – including exercises
46
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Expressions with local declarations
02157
Functional
Programming
Concrete syntax:
a * (-3 + (let x = 5 in x + a))
Interpreters for two simple languages, – including exercises
47
DTU Compute, Technical University of Denmark
Michael R. Ha
MRH
11/10/2016
Expressions with local declarations
02157
Functional
Programming
Concrete syntax:
a * (-3 + (let x = 5 in x + a))
Michael R. Ha
The abstract syntax is defined by an algebraic datatype:
type ExprTree = |
|
|
|
|
|
|
Const of int
Ident of string
Minus of ExprTree
Sum
of ExprTree * ExprTree
Diff of ExprTree * ExprTree
Prod of ExprTree * ExprTree
Let of string * ExprTree * ExprTree;;
Interpreters for two simple languages, – including exercises
48
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Expressions with local declarations
02157
Functional
Programming
Concrete syntax:
a * (-3 + (let x = 5 in x + a))
Michael R. Ha
The abstract syntax is defined by an algebraic datatype:
type ExprTree = |
|
|
|
|
|
|
Const of int
Ident of string
Minus of ExprTree
Sum
of ExprTree * ExprTree
Diff of ExprTree * ExprTree
Prod of ExprTree * ExprTree
Let of string * ExprTree * ExprTree;;
Example:
let et =
Prod(Ident "a",
Sum(Minus (Const 3),
Let("x", Const 5, Sum(Ident "x", Ident "a"))));;
Interpreters for two simple languages, – including exercises
49
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Evaluation in Environments
An environment contains bindings of identifiers to values.
02157
Functional
Programming
Michael R. Ha
Interpreters for two simple languages, – including exercises
50
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Evaluation in Environments
An environment contains bindings of identifiers to values.
A tree Let(s,t1 ,t2 ) is evaluated in an environment env:
1 Evaluate t1 to value v1 in environment env.
2 Evaluate t2 in env extended with the binding of s to v1 .
Interpreters for two simple languages, – including exercises
51
DTU Compute, Technical University of Denmark
02157
Functional
Programming
Michael R. Ha
MRH
11/10/2016
Evaluation in Environments
An environment contains bindings of identifiers to values.
02157
Functional
Programming
A tree Let(s,t1 ,t2 ) is evaluated in an environment env:
1 Evaluate t1 to value v1 in environment env.
2 Evaluate t2 in env extended with the binding of s to v1 .
Michael R. Ha
An evaluation function
eval: ExprTree -> Map<string,int> -> int
is defined as follows:
let rec eval t env
match t with
| Const n
| Ident s
| Minus t
| Sum(t1,t2)
| Diff(t1,t2)
| Prod(t1,t2)
| Let(s,t1,t2)
=
->
->
->
->
->
->
->
n
Map.find s env
- (eval t env)
eval t1 env + eval
eval t1 env - eval
eval t1 env * eval
let v1
= eval t1
let env1 = Map.add
eval t2 env1;;
t2 env
t2 env
t2 env
env
s v1 env
Interpreters for two simple languages, – including exercises
52
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Example
02157
Functional
Programming
Concrete syntax:
Michael R. Ha
a * (-3 + (let x = 5 in x + a))
Interpreters for two simple languages, – including exercises
53
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Example
02157
Functional
Programming
Concrete syntax:
Michael R. Ha
a * (-3 + (let x = 5 in x + a))
let et =
Prod(Ident "a",
Sum(Minus (Const 3),
Let("x", Const 5, Sum(Ident "x", Ident "a"))));;
Interpreters for two simple languages, – including exercises
54
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Example
02157
Functional
Programming
Concrete syntax:
Michael R. Ha
a * (-3 + (let x = 5 in x + a))
let et =
Prod(Ident "a",
Sum(Minus (Const 3),
Let("x", Const 5, Sum(Ident "x", Ident "a"))));;
let env = Map.add "a" -7 Map.empty;;
eval et env;;
val it : int = 35
Interpreters for two simple languages, – including exercises
55
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Example: Imperative Factorial program
02157
Functional
Programming
An example of concrete syntax for a factorial program:
Michael R. Ha
{Pre: x=K and x>=0}
y:=1 ;
while !(x=0)
do (y:= y*x;x:=x-1)
{Post: y=K!}
Interpreters for two simple languages, – including exercises
56
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Example: Imperative Factorial program
02157
Functional
Programming
An example of concrete syntax for a factorial program:
Michael R. Ha
{Pre: x=K and x>=0}
y:=1 ;
while !(x=0)
do (y:= y*x;x:=x-1)
{Post: y=K!}
Typical ingredients
• Arithmetical expressions
Interpreters for two simple languages, – including exercises
57
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Example: Imperative Factorial program
02157
Functional
Programming
An example of concrete syntax for a factorial program:
Michael R. Ha
{Pre: x=K and x>=0}
y:=1 ;
while !(x=0)
do (y:= y*x;x:=x-1)
{Post: y=K!}
Typical ingredients
• Arithmetical expressions
• Boolean expressions
Interpreters for two simple languages, – including exercises
58
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Example: Imperative Factorial program
02157
Functional
Programming
An example of concrete syntax for a factorial program:
Michael R. Ha
{Pre: x=K and x>=0}
y:=1 ;
while !(x=0)
do (y:= y*x;x:=x-1)
{Post: y=K!}
Typical ingredients
• Arithmetical expressions
• Boolean expressions
• Statements (assignments, sequential composition, loops, . . .
Interpreters for two simple languages, – including exercises
59
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Arithmetic Expressions
02157
Functional
Programming
• Grammar:
Michael R. Ha
aExp :: − n | v | aExp+aExp |aExp·aExp | aExp−aExp | (aExp)
where n is an integer and v is a variable.
Interpreters for two simple languages, – including exercises
60
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Arithmetic Expressions
02157
Functional
Programming
• Grammar:
Michael R. Ha
aExp :: − n | v | aExp+aExp |aExp·aExp | aExp−aExp | (aExp)
where n is an integer and v is a variable.
• The declaration for the abstract syntax follows the grammar
type
|
|
|
|
|
AExp =
(* Arithmetical expressions
N of int
(* numbers
V of string
(* variables
Add of AExp * AExp
(* addition
Mul of AExp * AExp
(* multiplication
Sub of AExp * AExp;; (* subtraction
*)
*)
*)
*)
*)
*)
Interpreters for two simple languages, – including exercises
61
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Arithmetic Expressions
02157
Functional
Programming
• Grammar:
Michael R. Ha
aExp :: − n | v | aExp+aExp |aExp·aExp | aExp−aExp | (aExp)
where n is an integer and v is a variable.
• The declaration for the abstract syntax follows the grammar
type
|
|
|
|
|
AExp =
(* Arithmetical expressions
N of int
(* numbers
V of string
(* variables
Add of AExp * AExp
(* addition
Mul of AExp * AExp
(* multiplication
Sub of AExp * AExp;; (* subtraction
*)
*)
*)
*)
*)
*)
The abstract syntax is representation independent (no ’+’, ’-’,
’(’,’)’, etc.), no ambiguities — one works directly on syntax trees.
Interpreters for two simple languages, – including exercises
62
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Semantics of Arithmetic Expressions
02157
Functional
Programming
• A state maps variables to integers
Michael R. Ha
type State = Map<string,int>;;
Interpreters for two simple languages, – including exercises
63
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Semantics of Arithmetic Expressions
02157
Functional
Programming
• A state maps variables to integers
Michael R. Ha
type State = Map<string,int>;;
• The meaning of an expression is a function:
A: AExp -> State -> int
Interpreters for two simple languages, – including exercises
64
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Semantics of Arithmetic Expressions
02157
Functional
Programming
• A state maps variables to integers
Michael R. Ha
type State = Map<string,int>;;
• The meaning of an expression is a function:
A: AExp -> State -> int
defined inductively on the structure of arithmetic expressions
let rec A a s
match a with
| N n
| V x
| Add(a1, a2)
| Mul(a1, a2)
| Sub(a1, a2)
=
->
->
->
->
->
n
Map.find
A a1 s +
A a1 s *
A a1 s -
x
A
A
A
s
a2 s
a2 s
a2 s;;
Interpreters for two simple languages, – including exercises
65
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Boolean Expressions
02157
Functional
Programming
• Abstract syntax
type
|
|
|
|
|
|
BExp =
TT
FF
Eq of ....
Lt of ....
Neg of ....
Con of ....
Michael R. Ha
(* Boolean expressions
(* true
(* false
(* equality
(* less than
(* negation
;;
(* conjunction
*)
*)
*)
*)
*)
*)
*)
Interpreters for two simple languages, – including exercises
66
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Boolean Expressions
02157
Functional
Programming
• Abstract syntax
type
|
|
|
|
|
|
BExp =
TT
FF
Eq of ....
Lt of ....
Neg of ....
Con of ....
Michael R. Ha
(* Boolean expressions
(* true
(* false
(* equality
(* less than
(* negation
;;
(* conjunction
*)
*)
*)
*)
*)
*)
*)
• Semantics B : BExp → State → bool
let rec B b s =
match b with
| TT
-> true
| ....
Interpreters for two simple languages, – including exercises
67
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Statements: Abstract Syntax
02157
Functional
Programming
Michael R. Ha
type
|
|
|
|
|
Stm =
Ass of string
Skip
Seq of Stm *
ITE
of BExp
While of BExp
* AExp
(* statements
(* assignment
Stm
* Stm * Stm
* Stm;;
(* sequential composition *)
(* if-then-else
*)
(* while
*)
Interpreters for two simple languages, – including exercises
68
DTU Compute, Technical University of Denmark
*)
*)
MRH
11/10/2016
Statements: Abstract Syntax
02157
Functional
Programming
Michael R. Ha
type
|
|
|
|
|
Stm =
Ass of string
Skip
Seq of Stm *
ITE
of BExp
While of BExp
* AExp
(* statements
(* assignment
*)
*)
Stm
* Stm * Stm
* Stm;;
(* sequential composition *)
(* if-then-else
*)
(* while
*)
Example of concrete syntax:
y:=1 ; while not(x=0) do (y:= y*x ; x:=x-1)
Abstract syntax ?
Interpreters for two simple languages, – including exercises
69
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Update of states
02157
Functional
Programming
An imperative program performs a sequence of state updates.
Michael R. Ha
• The expression
update y v s
is the state that is as s except that y is mapped to v .
Interpreters for two simple languages, – including exercises
70
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Update of states
02157
Functional
Programming
An imperative program performs a sequence of state updates.
Michael R. Ha
• The expression
update y v s
is the state that is as s except that y is mapped to v .
Mathematically:
v
if x = y
(update y v s)(x) =
s(x) if x 6= y
Interpreters for two simple languages, – including exercises
71
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Update of states
02157
Functional
Programming
An imperative program performs a sequence of state updates.
Michael R. Ha
• The expression
update y v s
is the state that is as s except that y is mapped to v .
Mathematically:
v
if x = y
(update y v s)(x) =
s(x) if x 6= y
• Update is a higher-order function with the declaration:
let update x v s = Map.add x v s;;
• Type?
Interpreters for two simple languages, – including exercises
72
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Interpreter for Statements
02157
Functional
Programming
Michael R. Ha
• The meaning of statements is a function
I : Stm → State → State
that is defined by induction on the structure of statements:
let rec I stm s =
match stm with
| Ass(x,a)
| Skip
| Seq(stm1, stm2)
| ITE(b,stm1,stm2)
| While(b, stm)
->
->
->
->
->
update x ( ... ) s
...
...
...
... ;;
Interpreters for two simple languages, – including exercises
73
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Example: Factorial function
(* {pre: x = K and x>=0}
y:=1 ; while !(x=0) do (y:= y*x;x:=x-1)
{post: y = K!}
02157
Functional
Programming
*)
Interpreters for two simple languages, – including exercises
74
DTU Compute, Technical University of Denmark
Michael R. Ha
MRH
11/10/2016
Example: Factorial function
(* {pre: x = K and x>=0}
y:=1 ; while !(x=0) do (y:= y*x;x:=x-1)
{post: y = K!}
02157
Functional
Programming
*)
Michael R. Ha
let fac = Seq(Ass("y", N 1),
While(Neg(Eq(V "x", N 0)),
Seq(Ass("y", Mul(V "x", V "y")) ,
Ass("x", Sub(V "x", N 1)) )));;
Interpreters for two simple languages, – including exercises
75
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Example: Factorial function
(* {pre: x = K and x>=0}
y:=1 ; while !(x=0) do (y:= y*x;x:=x-1)
{post: y = K!}
02157
Functional
Programming
Michael R. Ha
*)
let fac = Seq(Ass("y", N 1),
While(Neg(Eq(V "x", N 0)),
Seq(Ass("y", Mul(V "x", V "y")) ,
Ass("x", Sub(V "x", N 1)) )));;
(* Define an initial state
let s0 = Map.ofList [("x",4)];;
val s0 : Map<string,int> = map [("x", 4)]
*)
Interpreters for two simple languages, – including exercises
76
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Example: Factorial function
(* {pre: x = K and x>=0}
y:=1 ; while !(x=0) do (y:= y*x;x:=x-1)
{post: y = K!}
02157
Functional
Programming
Michael R. Ha
*)
let fac = Seq(Ass("y", N 1),
While(Neg(Eq(V "x", N 0)),
Seq(Ass("y", Mul(V "x", V "y")) ,
Ass("x", Sub(V "x", N 1)) )));;
(* Define an initial state
let s0 = Map.ofList [("x",4)];;
val s0 : Map<string,int> = map [("x", 4)]
*)
(* Interpret the program
*)
let s1 = I fac s0;;
val s1 : Map<string,int> = map [("x", 1); ("y", 24)]
Interpreters for two simple languages, – including exercises
77
DTU Compute, Technical University of Denmark
MRH
11/10/2016
Exercises
02157
Functional
Programming
• Complete the program skeleton for the interpreter, and try some
Michael R. Ha
examples.
• Extend the abstract syntax and the interpreter with if-then and
repeat-until statements.
• Suppose that an expression of the form inc(x) is added. It adds
one to the value of x in the current state, and the value of the
expression is this new value of x.
How would you refine the interpreter to cope with this construct?
• Analyse the problem and state the types for the refined
interpretation functions
Interpreters for two simple languages, – including exercises
78
DTU Compute, Technical University of Denmark
MRH
11/10/2016