CSE341 Spring 2017, Midterm Examination April 28, 2017

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

CSE341 Spring 2016, Midterm Examination April 29, 2016

CSE341 Autumn 2017, Midterm Examination October 30, 2017

CSE341, Fall 2011, Midterm Examination October 31, 2011

CSE341, Fall 2011, Midterm Examination October 31, 2011

CSE 341 : Programming Languages Midterm, Spring 2015

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

CSE341, Spring 2013, Final Examination June 13, 2013

CSE341 Spring 2017, Final Examination June 8, 2017

CSE341 Autumn 2017, Final Examination December 12, 2017

CSE341 Spring 2017, Final Examination June 8, 2017

CSE 341 Section 5. Winter 2018

CSE341 Spring 2016, Final Examination June 6, 2016

CSE 332, Spring 2010, Midterm Examination 30 April 2010

CSE505, Fall 2012, Midterm Examination October 30, 2012

CSE373 Fall 2013, Midterm Examination October 18, 2013

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

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

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

CIS 120 Midterm I February 16, 2015 SOLUTIONS

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

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

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

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

CSci 4223 Principles of Programming Languages

CSE3322 Programming Languages and Implementation

CS 457/557: Functional Languages

Part I: Written Problems

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

Lecture 6: Sequential Sorting

CMSC 330, Fall 2013, Practice Problems 3

CSE331 Winter 2014, Midterm Examination February 12, 2014

CSE 130, Fall 2005: Final Examination

CSE 130, Fall 2006: Final Examination

CSE351 Winter 2016, Final Examination March 16, 2016

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

CSE373 Fall 2013, Second Midterm Examination November 15, 2013

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

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

Standard ML. Data types. ML Datatypes.1

CIS 110 Introduction To Computer Programming. February 29, 2012 Midterm

CSE373 Winter 2014, Midterm Examination January 29, 2014

CSE 332 Autumn 2013: Midterm Exam (closed book, closed notes, no calculators)

CSE351 Spring 2018, Midterm Exam April 27, 2018

Functional Paradigm II

Programming Languages and Techniques (CIS120)

CSE331 Winter 2014, Midterm Examination February 12, 2014

Patterns The Essence of Functional Programming

CSE 130, Winter 2011: Final Examination

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

Problem Score Max Score 1 Syntax directed translation & type

CSE 332 Spring 2013: Midterm Exam (closed book, closed notes, no calculators)

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

Preliminary Examination I Computer Science 312, Cornell University 6 March 2003

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

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

CPSC 311, 2010W1 Midterm Exam #2

CSCI-GA Final Exam

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

Sample Exam; Solutions

An introduction introduction to functional functional programming programming using usin Haskell

CSE 143 Final Exam Part 1 - August 18, 2011, 9:40 am

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

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

CMSC 330, Fall 2013, Practice Problem 3 Solutions

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

Programming Languages

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

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

CSE 341 Sample Midterm #2

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

CSE 373 Spring 2010: Midterm #1 (closed book, closed notes, NO calculators allowed)

CSE 130 [Winter 2014] Programming Languages

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

First Midterm Exam CS164, Fall 2007 Oct 2, 2007

CS 321 Programming Languages

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

CSE 130: Programming Languages. Polymorphism. Ranjit Jhala UC San Diego

UNIVERSITY OF TORONTO Faculty of Arts and Science

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

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

CSE 341 : Programming Languages

List Processing in Ocaml

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

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

UNIVERSITY OF TORONTO Faculty of Arts and Science. Midterm Sample Solutions CSC324H1 Duration: 50 minutes Instructor(s): David Liu.

CSE341, Fall 2011, Lecture 12 Summary

CSE 332, Spring 2010, Final Examination 8 June 2010

Programming Paradigms Written Exam (6 CPs)

CSE3322 Programming Languages and Implementation

CSE331 Spring 2015, Final Examination June 8, 2015

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

CSc 372, Spring 1996 Mid-term Examination Solution Key

Lists. Michael P. Fourman. February 2, 2010

Functional Paradigm II

Handout 2 August 25, 2008

Functional Programming Mid-term exam Tuesday 3/10/2017

CS 320 Midterm Exam. Fall 2018

A Third Look At ML. Chapter Nine Modern Programming Languages, 2nd ed. 1

Chapter 3 Linear Structures: Lists

Transcription:

CSE341 Spring 2017, Midterm Examination April 28, 2017 Please do not turn the page until 12: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 1: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. (21 points) This problem uses this datatype binding, where a value of type minihtml describes the contents of an HTML page that uses a tiny subset of HTML. No knowledge of HTML is necessary. datatype minihtml = Text of string (* string holds text that appears on the page *) Image of string * int * int (* string is the name of the file containing the image, first int is image width in pixels, second int is image height in pixels *) BulletList of minihtml list (* a bullet list of other items *) For both problems below, you can use local helper functions or ML standard-library functions. (a) Write a function numpixels of type minihtml -> int that computes the count of all the pixels that are in any of the images anywhere in the argument. (Images are rectangles.) (b) Write a function noimages of type minihtml -> minihtml where the result is like the argument except the result has no images. Each image should be replaced with text: If the file containing the image is foo, then the replacement text should be removed image from file foo. Solution:

fun numpixels1 m = let fun loop ms = case ms of [] => 0 m::ms => numpixels1 m + loop ms in case m of Text _ => 0 Image(_,h,w) => h * w BulletList ms => loop ms fun numpixels2 m = case m of Text _ => 0 Image(_,h,w) => h * w BulletList ms => List.foldl (fn (x,y) => y + numpixels2 x) 0 ms fun noimages1 m = let fun loop ms = case ms of [] => [] m::ms => noimages1 m :: loop ms in case m of Text _ => m Image(s,_,_) => Text ("removed image from file " ^ s) BulletList ms => BulletList (loop ms) fun noimages2 m = case m of Text _ => m Image(s,_,_) => Text ("removed image from file " ^ s) BulletList ms => BulletList (map noimages2 ms)

2. (19 points) This problem uses the following ML code where an int_tree represents a binary tree of ints, but only internal nodes hold ints (leaves do not). Note values of type int_tree are not assumed to be sorted in any particular way (for example, they are not binary search trees). exception Empty datatype int_tree = Leaf Node of int * int_tree * int_tree fun min t = case t of (* 1 *) Leaf => raise Empty (* 2 *) Node(i,Leaf,Leaf) => i (* 3 *) Node(i,t1,Leaf) => let val m = min t1 in if i < m then i else m (* 4 *) Node(i,t1,t2) => let val m1 = min t1 val m2 = min t2 val m3 = if m1 < m2 then m1 else m2 in if i < m3 then i else m3 (* 5 *) (a) What is the type of the min function above? (b) Assuming min is supposed to compute the smallest number in a tree, it is wrong. Fix it by adding one more branch to the case expression in one of the five positions indicated by comments above. That is, write the code for one more branch and indicate where you are putting it. (c) Give an example argument to min such that min behaves differently before and after your change in part (b). Indicate the behavior of min before and after your change. (d) Now consider moving the code you added in part (b) to one of the other positions. For each position, give one of these answers: A. This position would work too. B. This position is actually the one you already picked in part (b). C. This position would not work: moving your part (b) answer here would either lead to a type-checking error or to min producing the wrong answer. Do not consider in your answer that the first branch has no character and the others do. That is, assume we fix that syntactic issue as necessary. Position 1: Position 2: Position 3: Position 4: Position 5:

Solution: (a) int_tree -> int (b) Node(i,Leaf,t2) => let val m = min t2 in if i < m then i else m in position (3) or (4). Other answers possible using more nested patterns, which affects the answer to part (d). (c) Node(7,Leaf,Node(9,Leaf,Leaf) raises an exception before the change and evaluates to 7 after the change. (d) 1:C, 2: C, 3: A/B, 4:A/B, 5:C

3. (13 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 x y = if x = 0 then y + 1 else 2 * f2 (x-1,y) (b) fun f3 x y = x + y + a val a = 17 val b = f3 6 val c = b (c) fun f4 (xs,ys) = case (xs,ys) of ([],_) => 0 (_,[]) => 0 ([],[]) => 0 (_::xs,_::ys) => 1 + f4 (xs,ys) (d) fun f5 = List.map (fn x => x + 3) Solution: (a) recursive call is tupled but function binding is curried (b) no a is in scope where f3 is defined (c) third pattern is redundant: it cannot match unless an earlier pattern matches (d) fun binding needs an argument pattern (probably meant a val binding)

4. (20 points) (a) Without using any helper functions (except ::), write a function choose_map of type ( a * a -> bool) -> ( a -> b) -> a list -> a list -> b list as follows: It takes four arguments in curried form. The length of the result is equal to the length of the longer of the third and fourth arguments. The i th element of the output is the second argument applied to the i th element of either the third argument or the fourth argument. To choose which, we use the first argument on the two i th elements a result of true means use the third argument s element and a result of false means use the fourth argument s element. But if the lists have different lengths, then for positions past the of the shorter list we just use the element of the longer list and, for such elements, the first argument to choose_map is irrelevant. (b) Use a val binding and a partial application of choose_map to define a function pick_bigger of type int list -> int list -> int list where, for example, pick_bigger [1,7,9] [0,10,9,4,2] = [1,10,9,4,2] (c) Fill in the three blanks below such that t2 evaluates to true. fun zero_floor xs = pick_bigger (List.map ) val t2 = zero_floor [~2,~4,0,5,~3,7] = [0,0,0,5,0,7] (d) What is the type of zero_floor? Solution: (a) fun choose_map f1 f2 xs ys = case (xs,ys) of ([],[]) => [] (x::xs,[]) => (f2 x):: choose_map f1 f2 xs ys (* or choose_map f1 f2 ys xs *) ([],y::ys) => (f2 y):: choose_map f1 f2 xs ys (x::xs,y::ys) => if f1 (x,y) then (f2 x)::choose_map f1 f2 xs ys else (f2 y)::choose_map f1 f2 xs ys (b) val pick_bigger = choose_map (fn (x,y) => x > y) (fn z => z) (c) fun zero_floor xs = pick_bigger (List.map (fn x => 0) xs) xs Alternate correct solution we were not anticipating: fun zero_floor xs = pick_bigger (List.map (fn x => if x > 0 then x else 0) xs) [] (d) int list -> int list

5. (8 points) (a) Your fri proposes replacing the implementation of ML s List.map with this tail-recursive implementation: fun new_map f xs = let fun loop acc xs = case xs of [] => acc x::xs => loop ((f x)::acc) xs in loop [] xs Explain to your fri in roughly 1 English sentence why this is a bad idea. (b) Now your fri proposes adding this function of type ( a * b -> c) -> ( a * b) list -> c list to ML s list library as a useful iterator over lists of pairs: fun map_pair f xs = case xs of [] => [] (a,b)::xs => (f (a,b)) :: (map_pair f xs) Explain to your fri in roughly 1 English sentence why this is a bad idea. Solution: (a) new_map returns a list whose elements are in the reverse order from what map does (b) Any call to map_pair can just be a call to map, which is strictly more general

6. (19 points) This problem considers this ML module definition: structure Circ :> CIRC = struct type circle = real * real * real (* center x-coordinate, center y-coordinate, radius *) val unitcircle = (0.0, 0.0, 1.0) (* center at orgin, radius 1 *) fun movex ((x,y,r), dx) = (x+1.0*dx, y, r) fun movey ((x,y,r), dy) = (x, y+1.0*dy, r) fun scaler ((x,y,r), f) = (x, y, 1.0*r*f) fun intersect ((x1,y1,r1),(x2,y2,r2)) = let val dx = x2 - x1 val dy = y2 - y1 in Math.sqrt(dx*dx + dy*dy) < r1 + r2 (a) Complete this signature definition so that clients can use all the variable and function bindings in Circ for circles but the type of circles is abstract. signature CIRC = sig type circle (b) Consider a function area for computing the area of a circle (hints: (1) πr 2, (2) Math.pi). i. Write an implementation of area that works inside the Circ module. ii. Ext CIRC to make area available to clients. iii. What type does your area implementation have inside the Circ module? iv. Yes or no: If area is not provided by the module, is it possible for clients to write an equivalent function outside the module? (c) Consider a function funnycirclemaker that takes one real (call it a) and produces a circle with center-x-coordinate, center-y-coordinate, and radius that are all a. i. Write an implementation of funnycirclemaker that works inside the Circ module. ii. Ext CIRC to make funnycirclemaker available to clients. iii. What type does your funnycirclemaker implementation have inside the Circ module?

Solution: iv. Yes or no: If funnycirclemaker is not provided by the module, is it possible for clients to write an equivalent function outside the module? (a) signature CIRC = sig type circle val unitcircle : circle val movex : circle * real -> circle val movey : circle * real -> circle val scaler : circle * real -> circle val intersect : circle * circle -> bool (b) (c) i. fun area (_,_,r) = Math.pi * r * r ii. Add val area : circle -> real iii. a * b * real -> real (answer can dep on part (i)) iv. No i. fun funnycirclemaker a = (a,a,a) ii. Add val funnycirclemaker : real -> circle iii. a -> a * a * a (answer can dep on part (i)) iv. Yes

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.