* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download Interpreters for two simple languages – including exercises
Survey
Document related concepts
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