CSE341 Autumn 2017, Midterm Examination October 30, 2017

Similar documents
CSE341 Spring 2016, Midterm Examination April 29, 2016

CSE341, Fall 2011, Midterm Examination October 31, 2011

CSE341, Fall 2011, Midterm Examination October 31, 2011

CSE341 Spring 2016, Midterm Examination April 29, 2016

CSE341 Spring 2017, Midterm Examination April 28, 2017

CSE 341 : Programming Languages Midterm, Spring 2015

CSE341, Spring 2013, Final Examination June 13, 2013

CSE 341 Section 5. Winter 2018

A Concepts-Focused Introduction to Functional Programming Using Standard ML Sample Exam #1 Draft of August 12, 2010

CSE505, Fall 2012, Midterm Examination October 30, 2012

CSE341 Spring 2017, Final Examination June 8, 2017

CSE341 Autumn 2017, Final Examination December 12, 2017

CSE341 Spring 2017, Final Examination June 8, 2017

CSE341 Spring 2016, Final Examination June 6, 2016

CSE 341, Spring 2011, Final Examination 9 June Please do not turn the page until everyone is ready.

CSE 505, Fall 2008, Midterm Examination 29 October Please do not turn the page until everyone is ready.

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

CSci 4223 Principles of Programming Languages

CSE3322 Programming Languages and Implementation

Part I: Written Problems

Fall 2018 Lecture N

CSC324- TUTORIAL 5. Shems Saleh* *Some slides inspired by/based on Afsaneh Fazly s slides

CSE341: Programming Languages Lecture 17 Implementing Languages Including Closures. Dan Grossman Autumn 2018

The type checker will complain that the two branches have different types, one is string and the other is int

CSE331 Winter 2014, Midterm Examination February 12, 2014

CSCI-GA Final Exam

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Winter 2013

CSE 505, Fall 2006, Final Examination 11 December Please do not turn the page until everyone is ready.

CSE373 Fall 2013, Midterm Examination October 18, 2013

Problem Score Max Score 1 Syntax directed translation & type

CSE351 Winter 2016, Final Examination March 16, 2016

CSE 332, Spring 2010, Midterm Examination 30 April 2010

CSE 303, Spring 2005, Midterm Examination 29 April Please do not turn the page until everyone is ready.

Processadors de Llenguatge II. Functional Paradigm. Pratt A.7 Robert Harper s SML tutorial (Sec II)

CSE331 Winter 2014, Midterm Examination February 12, 2014

CS 457/557: Functional Languages

CSE341: Programming Languages Lecture 11 Type Inference. Dan Grossman Spring 2016

Programming Languages

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

CSE 505, Fall 2007, Final Examination 10 December Please do not turn the page until everyone is ready.

Handout 2 August 25, 2008

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

A quick introduction to SML

A Brief Introduction to Standard ML

CSE 130, Fall 2005: Final Examination

Exercises on ML. Programming Languages. Chanseok Oh

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

CSE 341: Programming Languages

Begin at the beginning

CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists. Zach Tatlock Winter 2018

Function definitions. CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists. Example, extended. Some gotchas. Zach Tatlock Winter 2018

CSE3322 Programming Languages and Implementation

CSE3322 Programming Languages and Implementation

SML A F unctional Functional Language Language Lecture 19

CSE-321 Programming Languages 2010 Midterm

CSE341 Section 3. Standard-Library Docs, First-Class Functions, & More

Introduction to SML Basic Types, Tuples, Lists, Trees and Higher-Order Functions

Lists. Adrian Groza. Department of Computer Science Technical University of Cluj-Napoca

Higher-Order Functions

Datatype declarations

Lists. Michael P. Fourman. February 2, 2010

CSE 130, Fall 2006: Final Examination

CSE373 Fall 2013, Final Examination December 10, 2013 Please do not turn the page until the bell rings.

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

Lecture 19: Functions, Types and Data Structures in Haskell

General Computer Science (CH ) Fall 2016 SML Tutorial: Practice Problems

Sample Exam; Solutions

CS109A ML Notes for the Week of 1/16/96. Using ML. ML can be used as an interactive language. We. shall use a version running under UNIX, called

Standard ML. Exceptions

List Processing in SML

List Processing in SML

CSE331 Spring 2015, Final Examination June 8, 2015

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

Typical workflow. CSE341: Programming Languages. Lecture 17 Implementing Languages Including Closures. Reality more complicated

CS 320: Concepts of Programming Languages

The List Datatype. CSc 372. Comparative Programming Languages. 6 : Haskell Lists. Department of Computer Science University of Arizona

A First Look at ML. Chapter Five Modern Programming Languages, 2nd ed. 1

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

CMSC 330, Fall 2013, Practice Problems 3

Standard ML. Data types. ML Datatypes.1

F28PL1 Programming Languages. Lecture 14: Standard ML 4

CSE 303, Winter 2006, Final Examination 16 March Please do not turn the page until everyone is ready.

CSE331 Winter 2014, Final Examination March 17, 2014 Please do not turn the page until 8:30. Rules:

CSE341: Programming Languages Lecture 4 Records, Datatypes, Case Expressions. Dan Grossman Spring 2013

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

A list is a finite sequence of elements. Elements may appear more than once

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

Announcements. CSCI 334: Principles of Programming Languages. Lecture 5: Fundamentals III & ML

Chapter 3 Linear Structures: Lists

CSc 372 Comparative Programming Languages

CSE 505, Fall 2008, Final Examination 11 December Please do not turn the page until everyone is ready.

CSE373 Fall 2013, Second Midterm Examination November 15, 2013

CSE 413 Midterm, May 6, 2011 Sample Solution Page 1 of 8

Haske k ll An introduction to Functional functional programming using Haskell Purely Lazy Example: QuickSort in Java Example: QuickSort in Haskell

Side note: Tail Recursion. Begin at the beginning. Side note: Tail Recursion. Base Types. Base Type: int. Base Type: int

CSc 372. Comparative Programming Languages. 8 : Haskell Function Examples. Department of Computer Science University of Arizona

CSE373 Winter 2014, Midterm Examination January 29, 2014

CSE 130 [Winter 2014] Programming Languages

An introduction introduction to functional functional programming programming using usin Haskell

CSE-321 Programming Languages 2012 Midterm

Transcription:

CSE341 Autumn 2017, Midterm Examination October 30, 2017 Please do not turn the page until 2:30. Rules: The exam is closed-book, closed-note, etc. except for one side of one 8.5x11in piece of paper. Please stop promptly at 3:20. There are 100 points, distributed unevenly among 6 questions (all with multiple parts): The exam is printed double-sided. Advice: Read questions carefully. Understand a question before you start writing. Write down thoughts and intermediate steps so you can get partial credit. But clearly indicate what is your final answer. The questions are not necessarily in order of difficulty. Skip around. Make sure you get to all the questions. If you have questions, ask. Relax. You are here to learn.

1. (20 points) This problem uses this datatype binding, where an exp is a simple arithmetic expression like we studied in class except instead of negations and multiplications, we have doubling and (integer) division. datatype exp = Constant of int Double of exp Add of exp * exp Divide of exp * exp (a) Write a function eval_exp of type exp -> int that returns the answer for executing the arithmetic expression. Some notes on division: Use integer division, which in ML is done with the infix operator div. For example, in ML, 6 div 4 is 1. Division by zero will raise an exception, which is fine. (b) Give an example of a value of type exp where: Calling eval_exp with your expression causes a division-by-zero exception, but...... no use of the Divide constructor has Constant 0 as its second argument. (c) Write a function no_literal_zero_divide of type exp -> bool that returns true if and only if no use of the Divide constructor has Constant 0 as its second argument. Notes: So, no_literal_zero_divide applied to your answer to the previous question would evaluate to true. You should not use eval_exp this question has nothing to do with evaluating expressions. (a) fun eval_exp e = case e of Constant i => i Double e => 2 * eval_exp e Add(e1,e2) => (eval_exp e1) + (eval_exp e2) Divide (e1,e2) => (eval_exp e1) div (eval_exp e2) (b) Many possible answers such as Divide(Constant 4, Double(Constant 0)) Divide(Constant 4, Add(Constant 0, Constant 0)) (c) fun no_literal_zero_divide e = case e of Constant _ => true Double e => no_literal_zero_divide e Add(e1,e2) => no_literal_zero_divide e1 andalso no_literal_zero_divide e2 Divide(_,Constant 0) => false Divide(e1,e2) => no_literal_zero_divide e1 andalso no_literal_zero_divide e2

2. (20 points) This problem uses this somewhat silly function: fun f (xs,ys) = case (xs,ys) of (* 1 *) ([],[]) => SOME 0 (* 2 *) (x::[], y::[]) => SOME (x+y) (* 3 *) (x1::x2::[], y1::y2::[]) => SOME (x1 + x2 + y1 + y2) (* 4 *) (x1::x2::xs, y1::y2::ys ) => f (xs,ys ) (* 5 *) _ => NONE (a) What is the type of f? (b) What does f([3],[10]) evaluate to? (c) What does f([3,4],[10,11]) evaluate to? (d) What does f([3,4,5],[10,11,12]) evaluate to? (e) What does f([3,4,5,6],[10,11,12,13]) evaluate to? (f) Describe in at most 1 English sentence all the inputs to f such that the result of f is NONE. (g) Yes or no: Is f tail-recurisve? For each of the remaining questions, give one of these answers (just the letter is enough): A. The result no longer type-checks. B. The result type-checks but gives different answers for some inputs. C. The result type-checks and gives the same answer for all inputs. Also, ignore the syntax detail that the first branch has no character and the others do assume that is fixed appropriately. (h) What happens if we move branch 2 of f to be the first pattern in the case expression? (i) What happens if we move branch 3 of f to be the first pattern in the case expression? (j) What happens if we move branch 4 of f to be the first pattern in the case expression? (k) What happens if we move branch 5 of f to be the first pattern in the case expression? (a) int list * int list -> int option (b)-(e) SOME 13, SOME 28, SOME 17, SOME 36 (f) Any pair of lists of ints where the lists have different lengths (g) Yes (h)-(k) C, C, A, A

3. (12 points) In this problem, we ask you to give good error messages for why a short ML program does not type-check. A specific phrase or short sentence is plenty. For example, for the program, fun f1 (x,y) = if x then y + 1 else x a fine answer would be, the then-branch-expression and the else-branch-expression do not have the same type. Give good error messages for each of the following: (a) fun f2 g xs = case xs of [] => [] x::xs => (g x) :: f2 xs (b) fun f3 xs = case xs of [] => NONE x::[] => SOME 1 x::xs => SOME (1 + (f3 xs )) (c) datatype t = A of int B of (int * t) list fun f4 x = let fun aux ys = case ys of [] => [] (i,j)::ys => (i+1,j)::(aux ys) in case x of A i => x B ys => B (aux x) end (d) exception Foo fun f5 x = if x > 3 then x else raise Foo fun f6 y = (f5 (y+1)) handle _ => false (a) Recursive call is missing its first argument, probably want f2 g xs. (We also allowed answers indicating that f2 applied to one argument is a function so it cannot be the second argument to ::.) (b) The result of the recursive call is an option, so you can t add it. (valof (f2 xs )) would typecheck.) (c) The (non-recursive) call to aux passes a t but aux expects a list. (d) In e1 handle _ => e2, e1 and e2 need the same type, but here they have types int and bool.

4. (21 points) (a) Without using any helper functions (except ::) write a function zipwith of type ( a * b -> c) -> a list -> b list -> c list as follows: It takes three arguments in curried form. The length of the result is the length of the shorter of the second or third argument. The i th element of the output is the first argument applied to the i th elements of the second and third arguments. (b) Use a val binding and a partial application of zipwith to define a function first_bigger of type int list -> int list -> bool list where, for example, first_bigger [1,7,9] [0,10,9,4,2] = [true, false, false] (c) Here are two ML library functions: List.map : ( a -> b) -> a list -> b list map as discussed in class, with curried arguments ListPair.zip : a list * b list -> ( a * b) list equivalent to zipwith (fn pr => pr) except takes its arguments as a pair Reimplement zipwith in one line using these two library functions and a fun binding. (d) How many times does zipwith (fn _ => true) [1,2,3] [7,8,9] call the :: function (so do not count uses of the :: pattern) if zipwith is your answer to part (a)? (e) How many times does zipwith (fn _ => true) [1,2,3] [7,8,9] call the :: function (so do not count uses of the :: pattern) if zipwith is your answer to part (c)? (a) fun zipwith f xs ys = case (xs,ys) of ([],_) => [] (_,[]) => [] (x::xs,y::ys ) => (f(x,y)) :: zipwith f xs ys (b) val first_bigger = zipwith (fn (x,y) => x > y) (c) fun zipwith f xs ys = List.map f (ListPair.zip (xs,ys)) (d) 3 (e) 6 (we gave a little partial credit for 0 but calling a function that calls :: should definitely count )

5. (8 points) Here is a definition of flat_map as shown in section (recall @ is list append): fun flat_map f xs = case xs of [] => [] x::xs => (f x) @ flat_map f xs (a) Reimplement a curried map of type ( a -> b) -> a list -> b list in one line using a fun binding and flat_map. (b) Reimplement a curried filter of type ( a -> bool) -> a list -> a list in one line using a fun binding and flat_map. (a) fun map f = flat_map (fn x => [f x]) (b) fun filter f = flat_map (fn x => if f x then [x] else [])

6. (19 points) This problem considers an ML module RBNum1 for numbers in the range 0 999 that also have a color of blue or red. The structure definition is on a separate page you will not turn in. (a) Complete this signature definition so that clients of RBNum1 can use all the function bindings in RBNum1 but are not able to make bad values like Red ~7 or Blue 2000. signature RBNUM = sig val max_value : int exception OutOfRange end (b) Complete this structure definition so that it also has signature RBNUM and is equivalent to RBNum1 from any client s perspective. You need to add four bindings put them in the left column of the table below. structure RBNum2 :> RBNUM = struct type t = int exception OutOfRange val max_value = 999 fun red_num i = if i > max_value orelse i < 0 then raise OutOfRange else i fun blue_num i = if i > max_value orelse i < 0 then raise OutOfRange else i+1000 (*... part (b)... *) end (c) For each of the bindings you added in part (b), what are their types inside the RBNum2 module? Put your answers in the middle column of the table. (d) For each of the bindings you added in part (b), is it possible for the client to implement an equivalent function outside the module? Put your yes/no answers in the right column of the table. part (b) part (c) part (d)

signature RBNUM = sig val max_value : int exception OutOfRange type t val red_num : int -> t val blue_num : int -> t val is_blue : t -> bool val is_red : t -> bool val is_max_blue : t -> bool val to_int : t -> int end part (b) part (c) part (d) fun is_blue x = x >= 1000 int -> bool No fun is_red x = x < 1000 int -> bool No fun is_max_blue x = x = 1999 int -> bool Yes fun to int x = if x >= 1000 then x 1000 else x fun to int x = x mod 1000 int -> int No Notes: In part (c), the intended answers are those above, but since inside the module we have type t = int, any int above can be replaced with t and we allowed such answers. In part (d), an external client could implement is_blue as not o is_red and vice versa we gave most of the credit for answers that explained this unexpected trick.

Here is an extra page in case you need it. If you use it for a question, please write see also extra sheet or similar on the page with the question.

Here is RBNum1 on a separate page. Do not turn in this page, so do not write answers on it. structure RBNum1 :> RBNUM = struct val max_value = 999 exception OutOfRange datatype t = Red of int Blue of int fun red_num i = if i > max_value orelse i < 0 then raise OutOfRange else Red i fun blue_num i = if i > max_value orelse i < 0 then raise OutOfRange else Blue i fun is_blue x = case x of Red _ => false Blue _ => true fun is_red x = case x of Red _ => true Blue _ => false fun is_max_blue x = case x of Red _ => false Blue i => i = 999 fun to_int x = case x of Red i => i Blue i => i end