CMSC 330, Fall 2013, Practice Problem 3 Solutions

Similar documents
CMSC 330, Fall 2013, Practice Problems 3

CMSC330 Spring 2014 Midterm 2 Solutions

CMSC330 Fall 2014 Midterm 2 Solutions

OCaml. ML Flow. Complex types: Lists. Complex types: Lists. The PL for the discerning hacker. All elements must have same type.

Tuples. CMSC 330: Organization of Programming Languages. Examples With Tuples. Another Example

CMSC330 Spring 2014 Midterm #2. Score 1 OCaml types & type

CSE 341 Section 5. Winter 2018

CMSC 330: Organization of Programming Languages. OCaml Higher Order Functions

CMSC330 Fall 2016 Midterm #1 2:00pm/3:30pm

Programming Languages

CMSC 330: Organization of Programming Languages. OCaml Higher Order Functions

CMSC 330: Organization of Programming Languages. OCaml Higher Order Functions

News. Programming Languages. Complex types: Lists. Recap: ML s Holy Trinity. CSE 130: Spring 2012

Plan (next 4 weeks) 1. Fast forward. 2. Rewind. 3. Slow motion. Rapid introduction to what s in OCaml. Go over the pieces individually

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

Programming Languages

CMSC 330: Organization of Programming Languages. Closures (Implementing Higher Order Functions)

Introduction to OCaml

OCaml. History, Variants. ML s holy trinity. Interacting with ML. Base type: Integers. Base type: Strings. *Notes from Sorin Lerner at UCSD*

CSCI-GA Scripting Languages

CMSC 330: Organization of Programming Languages

CMSC330 Fall 2013 Practice Problems 6 Solutions

CIS 120 Midterm I February 16, 2015 SOLUTIONS

CS 135 Winter 2018 Tutorial 7: Accumulative Recursion and Binary Trees. CS 135 Winter 2018 Tutorial 7: Accumulative Recursion and Binary Trees 1

Programming Languages

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

CMSC 330: Organization of Programming Languages. Closures (Implementing Higher Order Functions)

Dialects of ML. CMSC 330: Organization of Programming Languages. Dialects of ML (cont.) Features of ML. Functional Languages. Features of ML (cont.

CVO103: Programming Languages. Lecture 5 Design and Implementation of PLs (1) Expressions

CS 11 Ocaml track: lecture 2

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

OCaml Data CMSC 330: Organization of Programming Languages. User Defined Types. Variation: Shapes in Java

CMSC330 Spring 2008 Final Exam

CSE 130 [Winter 2014] Programming Languages

Anonymous Functions CMSC 330: Organization of Programming Languages

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

Begin at the beginning

CIS 120 Midterm I October 2, Name (printed): Username (login id):

CS Lectures 2-3. Introduction to OCaml. Polyvios Pratikakis

CSC/MAT-220: Lab 6. Due: 11/26/2018

CMSC330 Spring 2015 Final Exam 9:30am/11:00am/12:30pm

CMSC 330: Organization of Programming Languages

A Brief Introduction to Standard ML

CMSC 330: Organization of Programming Languages. Lets, Tuples, Records

Mini-ML. CS 502 Lecture 2 8/28/08

Background. CMSC 330: Organization of Programming Languages. Useful Information on OCaml language. Dialects of ML. ML (Meta Language) Standard ML

Any questions. Say hello to OCaml. Say hello to OCaml. Why readability matters. History, Variants. Plan (next 4 weeks)

CMSC330. Objects, Functional Programming, and lambda calculus

Recap: Functions as first-class values

CMSC330 Fall 2010 Final Exam Solutions

CSci 4223 Lecture 12 March 4, 2013 Topics: Lexical scope, dynamic scope, closures

max function Next concat function max function What s the pattern? concat function More on recursion Higher-order functions

Introduction to SML Getting Started

CSE 130, Fall 2005: Final Examination

Topics Covered Thus Far. CMSC 330: Organization of Programming Languages. Language Features Covered Thus Far. Programming Languages Revisited

Programming Paradigms

CMSC330 Spring 2012 Final Exam Solutions

CSE 130, Fall 2006: Final Examination

ITT8060: Advanced Programming (in F#)

Topics Covered Thus Far CMSC 330: Organization of Programming Languages

CMSC 330: Organization of Programming Languages. OCaml Data Types

LECTURE 16. Functional Programming

Tail Calls. CMSC 330: Organization of Programming Languages. Tail Recursion. Tail Recursion (cont d) Names and Binding. Tail Recursion (cont d)

Tail Recursion: Factorial. Begin at the beginning. How does it execute? Tail recursion. Tail recursive factorial. Tail recursive factorial

# true;; - : bool = true. # false;; - : bool = false 9/10/ // = {s (5, "hi", 3.2), c 4, a 1, b 5} 9/10/2017 4

Hard deadline: 3/28/15 1:00pm. Using software development tools like source control. Understanding the environment model and type inference.

The Substitution Model

So what does studying PL buy me?

The Substitution Model. Nate Foster Spring 2018

Functional Programming. Pure Functional Programming

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

Booleans (aka Truth Values) Programming Languages and Compilers (CS 421) Booleans and Short-Circuit Evaluation. Tuples as Values.

CMSC 330: Organization of Programming Languages. Objects and Abstract Data Types

CMSC330 Spring 2015 Final Exam 9:30am/11:00am/12:30pm

CMSC 330: Organization of Programming Languages. Operational Semantics

CSE 307: Principles of Programming Languages

F28PL1 Programming Languages. Lecture 14: Standard ML 4

Some Advanced ML Features

Redefinition of an identifier is OK, but this is redefinition not assignment; Thus

Programming Languages and Techniques (CIS120)

CSE341: Programming Languages Lecture 7 First-Class Functions. Dan Grossman Winter 2013

CMSC330 Spring 2016 Midterm #1 9:30am/12:30pm/3:30pm

Programming Languages. Tail Recursion. CSE 130: Winter Lecture 8: NOT TR. last thing function does is a recursive call

Exercises on ML. Programming Languages. Chanseok Oh

CMSC 330: Organization of Programming Languages

CSCC24 Functional Programming Typing, Scope, Exceptions ML

CS 320: Concepts of Programming Languages

CSE 130 [Winter 2014] Programming Languages

A Second Look At ML. Chapter Seven Modern Programming Languages, 2nd ed. 1

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Fall 2011

Haskell Types COMP360

CSE341 Spring 2017, Midterm Examination April 28, 2017

Parametric types. map: ( a (a b) a list b list. filter: ( a bool) a list a list. Why? a and b are type variables!

The Typed Racket Guide

CSCI 2041: Functions, Mutation, and Arrays

CSE 307: Principles of Programming Languages

Functional Programming. Introduction To Cool

Cunning Plan. One-Slide Summary. Functional Programming. Functional Programming. Introduction to COOL #1. Classroom Object-Oriented Language

Transcription:

CMSC 330, Fall 2013, Practice Problem 3 Solutions 1. OCaml and Functional Programming a. Define functional programming Programs are expression evaluations b. Define imperative programming Programs change the value of variables c. Define higher-order functions Functions can be passed as arguments and returned as results d. Describe the relationship between type inference and static types Variable has a fixed type that can be inferred by looking at how variable is used in the code e. Describe the properties of OCaml lists Entity containing 0 or more elements of the same type. Type of list is determined by type of element. f. Describe the properties of OCaml tuples Entity containing 2 or more elements of possibly different types. Type of tuple is determined by type and number of elements. g. Define pattern variables in OCaml Variables making up patterns used by match h. Describe the usage of _ in OCaml Pattern variable that can match anything but does not add binding i. Describe polymorphism Function that can take different types for same formal parameter j. Write a polymorphic OCaml function let f x = x // a -> a, x can be of any type k. Describe variable binding A variable (symbol) is associated with a value in an expression (or environment) l. Describe scope Portion of program where variable binding is visible m. Describe lexical scoping Variable binding determined by nearest scope in text of program n. Describe dynamic scoping Variable binding determined by nearest runtime function invocation o. Describe environment Collection of variable bindings p. Describe closure Function code + environment pair, may be invoked as function q. Describe currying Functions consume one argument at a time, returning closures until all arguments are consumed

2. OCaml Types & Type Inference Give the type of the following OCaml expressions: a. [] // a list b. 1::[] // int list c. 1::2::[] // int list d. [1;2;3] // int list e. [[1];[1]] // int list list f. (1) // int g. (1, bar ) // int * string h. ([1,2], [ foo, bar ]) // (int * int) list * (string * string) list i. [(1,2, foo );(3,4, bar )] // (int * int * string) list j. let f x = 1 // a -> int k. let f (x) = x *. 3.14 // float -> float l. let f (x,y) = x // a * b -> a m. let f (x,y) = x+y // int * int -> int n. let f (x,y) = (x,y) // a * b -> a * b o. let f (x,y) = [x,y] // a * b -> ( a * b) list p. let f x y = 1 // a -> b -> int q. let f x y = x*y // int -> int -> int r. let f x y = x::y // a -> a list -> a list s. let f x = match x with [] -> 1 // a list -> int t. let f x = match x with (y,z) -> y+z // int * int -> int u. let f (x::_) -> x // a list -> a v. let f (_::y) = y // a list -> a list w. let f (x::y::_) = x+y // int list -> int x. let f = fun x -> x + 1 // int -> int y. let rec x = fun y -> x y // a -> b z. let rec f x = if (x = 0) then 1 else 1+f (x-1) // int -> int aa. let f x y z = x+y+z in f 1 2 3 // int bb. let f x y z = x+y+z in f 1 2 // int -> int cc. let f x y z = x+y+z in f // int -> int -> int -> int dd. let rec f x = match x with // a list -> int [] -> 0 (_::t) -> 1 + f t ee. let rec f x = match x with // int list -> int [] -> 0 (h::t) -> h + f t ff. let rec f = function [] -> 0 (h::t) -> h + (2*(f t)) gg. let rec func (f, l1, l2) = match l1 with [] -> [] (h1::t1) -> match l2 with [] -> [f h1] (h2::t2) -> [f h1; f h2] // int list -> int // ( a -> b) * a list * a list -> b list

3. OCaml Types & Type Inference Write an OCaml expression with the following types: a. int list // [1] b. int * int // (1,1) c. int -> int // let f x = x+1 d. int * int -> int // let f (x,y) = x+y e. int -> int -> int // let f x y = x+y f. int -> int list -> int list // let f x y = (x+1)::y g. int list list -> int list // let f (x::_) = 1::x h. a -> a // let f x = x i. a * b -> a // let f (x,y) = x j. a -> b -> a // let f x y = x k. a -> b -> b // let f x y = y l. a list * b list -> ( a * b) list // let f (x::_,y::_) = [(x,y)] m. int -> (int -> int) // let f x y = x+y n. (int -> int) -> int // let f x = 1+(x 1) o. (int -> int) -> (int -> int) -> int // let f x y = 1+(x 1)+(y 1) p. ( a -> b) * ( c * c -> a) * c -> b // let f (x, y, z) = (x (y (z,z))) 4. OCaml Programs What is the value of the following OCaml expressions? If an error exists, describe the error. a. 2 ; 3 // 3 b. 2 ; 3 + 4 // 7 c. (2 ; 3) + 4 // 7 d. if 1<2 then 3 else 4 // 3 e. let x = 1 in 2 // 2 f. let x = 1 in x+1 // 2 g. let x = 1 in x ; x+1 // 2 h. let x = (1, 2) in x ; x+1 // error: x has type int*int but used with int i. (let x = (1, 2) in x) ; x+1 // error: unbound value x j. let x = 1 in let y = x in y // 1 k. let x = 1 let y = 2 in x+y // syntax error: missing in l. let x = 1 in let x = x+1 in let x = x+1 in x // 3 m. let x = x in let x = x+1 in let x = x+1 in x // error: unbound value x n. let rec x y = x in 1 // error: x has type a -> b but used with b o. let rec x y = y in 1 // 1 p. let rec x y = y in x 1 // 1 q. let x y = fun z -> z+1 in x // fun y -> (fun z -> z+1) r. let x y = fun z -> z+1 in x 1 // fun z -> z+1 s. let x y = fun z -> z+1 in x 1 1 // 2 t. let x y = fun z -> x+1 in x 1 // error: unbound value x u. let rec x y = fun z -> x+1 in x 1 // error: x has type a -> b -> c but used with int

v. let rec x y = fun z -> x+y in x 1 // error: x has type a -> b -> c but used with int w. let rec x y = fun z -> x y in x 1 // error: x has type a -> b but used with b x. let rec x y = fun z -> x z in x 1 // error: x has type a -> b but used with b y. let x y = y 1 in 1 // 1 z. let x y = y 1 in x // fun y -> (y 1) aa. let x y = y 1 in x 1 // error: 1 has type int but used with int -> a bb. let x y = y 1 in x fun z -> z + 1 // syntax error at x fun cc. let x y = y 1 in x (fun z -> z + 1) // 2 dd. let a = 1 in let f x y z = x+y+z+a in f 1 2 3 // 7 ee. let a = 1 in let f x y z = x+y+z+a in f 1 2-3 // error: (f 1 2) has type int -> int but used with int 5. OCaml Programming let rec map f l = match l with [] -> [] (h::t) -> (f h)::(map f t) let rec fold f a l = match l with [] -> a (h::t) -> fold f (f a h) t a. Write an OCaml function named fib that takes an int x, and returns the Fibonacci number for x. Recall that fib(0) = 0, fib(1) = 1, fib(2) = 1, fib(3) = 2. let rec fib x = if (x = 0) then 0 else if (x = 1) then 1 else (fib (x-1) + fib (x-2)) b. Write a function find_suffixes which applied to a list lst returns a list of all the suffixes of lst. For instance, suffixes [1;2;5] = [ [1;2;5] ; [2;5] ; [5] ] let rec suffix_helper (x, r) = match x with [] -> r (h::t) -> (suffix_helper (t, (h::t)::r)) let suffixes x = List.rev (suffix_helper (x, []))

c. Write an OCaml function named map_odd which takes a function f and a list lst, applies the function to every other element of the list, starting with the first element, and returns the result in a new list. let rec map_odd f l = match l with [] -> [] (x1::[]) -> [f x1] (x1::x2::t) -> (f x1)::(map_odd f t) d. Use map_odd and fib applied to the list [1;2;3;4;5;6;7] to calculate the Fibonacci numbers for 1, 3, 5, and 7. map_odd fib [1;2;3;4;5;6;7] e. Using map, write a function triple which applied to a list of ints lst returns a list with all elements of lst tripled in value. let triple x = map (fun x -> 3*x) x f. Using fold, write a function all_true which applied to a list of booleans lst returns true only if all elements of lst are true. let all_true lst = fold (fun a x -> (x = true) && (a = true)) true lst g. Using fold and anonymous helper functions, write a function product which applied to a list of ints lst returns the product of all the elements in lst. let product x = fold (fun a y -> a*y) 1 x h. Using fold and anonymous helper functions, write a function find_min which applied to a list of ints lst returns the smallest element in lst. let find_min x = fold (fun a y -> min a y) max_int x i. Using the fold function and anonymous helper functions, write a function count_vote which applied to a list of booleans lst returns a tuple (x,y) where x is the number of true elements and y is the number of false elements. let count_vote x = fold (fun (y,n) v -> if (v) then (y+1,n) else (y,n+1)) (0,0) x j. Using the function count_vote, write a function majority which applied to a list of booleans lst returns true if 1/2 or more elements of lst are true. let majority x = match (count_vote x) with (y,n) -> (y >= n)

6. OCaml Polymorphic Types Consider a OCaml module Bst that implements a binary search tree: module Bst = struct type bst = Empty Node of int * bst * bst let empty = Empty (* empty binary search tree *) let is_empty = function (* return true for empty bst *) Empty -> true Node (_, _, _) -> false let rec insert n = function (* insert n into binary search tree *) Empty -> Node (n, Empty, Empty) Node (m, left, right) -> if m = n then Node (m, left, right) else if n < m then Node(m, (insert n left), right) else Node(m, left, (insert n right)) (* Implement the following functions val min : bst -> int val remove : int -> bst -> bst val fold : ('a -> int -> 'a) -> 'a -> bst -> 'a val size : bst -> int *) let rec min = (* return smallest value in bst *) let rec remove n t = (* tree with n removed *) let rec fold f a t = (* apply f to nodes of t in inorder *) let size t = (* # of non-empty nodes in t *) end a. Is insert tail recursive? Explain why or why not. No, since the return value for recursive call to insert cannot be used as the return value of the original call to insert. The return value is used to create a Node data type first, and the Node value is returned. b. Implement min as a tail-recursive function. Raise an exception for an empty bst. Any reasonable exception is fine. let rec min = function Empty -> (raise (Failure "min")) Node (m, left, right) -> if (is_empty left) then m else min left

c. Implement remove. The result should still be a binary search tree. let rec remove n = function Empty -> Empty Node (m, left, right) -> if m = n then ( if (is_empty left) then right else if (is_empty right) then left else let x = min right in Node(x, left, remove x right) // OR // else let x = max left in // Node(x, remove x left, right) ) else if n < m then Node(m, (remove n left), right) else Node(m, left, (remove n right)) d. Implement fold as an inorder traversal of the tree so that the code List.rev (fold (fun a m -> m::a) [] t) will produce an (ordered) list of values in the binary search tree. let rec fold f a n = match n with Empty -> a Node (m, left, right) -> fold f (f (fold f a left) m) right e. Implement size using fold. let size t = fold (fun a m -> a+1) 0 t