Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
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