CSE341, Fall 2011, Midterm Examination October 31, 2011

Similar documents
CSE341, Fall 2011, Midterm Examination October 31, 2011

CSE341 Spring 2016, Midterm Examination April 29, 2016

CSE341 Autumn 2017, Midterm Examination October 30, 2017

CSE341 Spring 2016, Midterm Examination April 29, 2016

CSE 341 : Programming Languages Midterm, Spring 2015

CSE341, Spring 2013, Final Examination June 13, 2013

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

CSE341 Spring 2017, Midterm Examination April 28, 2017

CSE 341 Section 5. Winter 2018

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

CSE505, Fall 2012, Midterm Examination October 30, 2012

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

CSE341 Spring 2017, Final Examination June 8, 2017

CSE341 Spring 2017, Final Examination June 8, 2017

CSE341 Autumn 2017, Final Examination December 12, 2017

CSE341 Spring 2016, Final Examination June 6, 2016

CSE 332, Spring 2010, Midterm Examination 30 April 2010

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

CSE373 Fall 2013, Midterm Examination October 18, 2013

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

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

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

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

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

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

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

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

CSE373 Winter 2014, Midterm Examination January 29, 2014

CSE 505, Fall 2008, Final Examination 11 December 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.

CSE373 Fall 2013, Second Midterm Examination November 15, 2013

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

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

CSci 4223 Principles of Programming Languages

Part I: Written Problems

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

CSE 341: Programming Languages

Datatype declarations

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

Begin at the beginning

CSE 505, Fall 2008, Final Examination 11 December 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.

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

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

A quick introduction to SML

Exercises on ML. Programming Languages. Chanseok Oh

CSE 303, Autumn 2006, Final Examination 12 December 2006

CSE3322 Programming Languages and Implementation

CSE 341, Autumn 2005, Assignment 3 ML - MiniML Interpreter

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

CSE331 Winter 2014, Midterm Examination February 12, 2014

Introduction to OCaml

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

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

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

Higher-Order Functions

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

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

CSE 332, Spring 2010, Final Examination 8 June 2010

CSCI-GA Final Exam

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

CSE351 Spring 2018, Midterm Exam April 27, 2018

Programming Languages

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

CS 320 Midterm Exam. Fall 2018

CS 457/557: Functional Languages

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

CSE331 Spring 2015, Final Examination June 8, 2015

List Processing in SML

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

CSE 130, Winter 2011: Final Examination

CSE341: Programming Languages Winter 2018 Unit 3 Summary Zach Tatlock, University of Washington

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

Fall 2018 Lecture N

List Functions, and Higher-Order Functions

Lecture 3: Recursion; Structural Induction

List Processing in SML

CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion. Zach Tatlock Winter 2018

Programming Languages

CSE 130, Fall 2005: Final Examination

Programming Languages

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

SML Style Guide. Last Revised: 31st August 2011

CSE 130, Fall 2006: Final Examination

Standard ML. Exceptions

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

SML A F unctional Functional Language Language Lecture 19

Fall Lecture 13 Thursday, October 11

Australian researchers develop typeface they say can boost memory, that could help students cramming for exams.

Standard ML. Data types. ML Datatypes.1

Lecture 6: Sequential Sorting

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

Programming Languages

Read and fill in this page now. Your lab section day and time: Name of the person sitting to your left: Name of the person sitting to your right:

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

FUNCTIONAL PROGRAMMING

CSE373 Winter 2014, Final Examination March 18, 2014 Please do not turn the page until the bell rings.

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

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

Transcription:

CSE341, Fall 2011, Midterm Examination October 31, 2011 Please do not turn the page until the bell rings. Rules: The exam is closed-book, closed-note, except for one side of one 8.5x11in piece of paper. Please stop promptly at 3:20. You can rip apart the pages, but please staple them back together before you leave. There are 100 points total, distributed unevenly among 5 questions (all with multiple parts). When writing code, style matters, but don t worry much about indentation. Advice: Read questions carefully. Understand a question before you start writing. Write down thoughts and intermediate steps so you can get partial credit. The questions are not necessarily in order of difficulty. Skip around. Make sure you get to all the problems. If you have questions, ask. Relax. You are here to learn. 1

1. This problem uses this datatype binding, which describes expression trees where leaves are constants or variables and internal nodes are additions or multiplications. datatype exp = Constant of int Variable of string Add of exp * exp Multiply of exp * exp (a) (10 points) Write an ML function has_variable of type exp * string -> bool that returns true if and only if the string appears somewhere in the expression. You can use = to compare strings. (b) (10 points) Write an ML function const_not_under_add of type exp -> bool that returns true if and only if there exists at least one constant that is not underneath at least one addition. For example, Multiply(Add(Constant 3, Constant 4), Multiply(Variable "x", Constant 6)) would produce true because the 6 is not under an addition, but Add(Multiply(Constant 1, Constant 2), Multiply(Constant 3, Constant 4)) would produce false because all the constants are under an addition even though they are not directly under it. (a) fun has_variable (e,s) = case e of Constant _ => false Variable x => s=x Add(e1,e2) => has_variable (e1,s) orelse has_variable (e2,s) Multiply(e1,e2) => has_variable (e1,s) orelse has_variable (e2,s) (b) fun const_not_under_add e = case e of Constant _ => true Variable _ => false Add _ => false Multiply(e1,e2) => const_not_under_add e1 orelse const_not_under_add e2 2

2. This problem considers this ML code: exception BadArgs fun f (g,xs,ys) = case (xs,ys) of ([],[]) => true (x::xs, y::ys) => f(g,xs,ys) andalso g(x,y) _ => raise BadArgs (a) (12 points) For each of the following expressions that use f, fill in the blank with an argument that causes the overall expression to evaluate to true. i. f((fn (x,y) => x > y), [3,4,5], ) ii. not (f((fn (x,y) => x > y), [3,4,5], )) iii. ((f ((fn (x,y) => x > y), [3,4,5], )) ; false) (b) (5 points) (c) (4 points) In English, briefly describe what f computes (not how it computes it). Is f tail-recursive? Explain briefly. handle BadArgs => true (a) i. Any list [v1,v2,v3] of ints where v1<3, v2<4, and v3<5. For example, [0,0,0]. ii. Any list [v1,v2,v3] of ints where v1>=3, v2>=4, or v3>=5. For example, [2,5,4]. iii. Any list of ints that has a length other than 3. For example, [2]. (b) It takes a function g that takes a pair and two lists xs and ys. It returns true if and only if for all i, g applied to the i th elements of the two lists returns true. It raises an exception if the two lists have different lengths. (Note it applies g to the elements closer to the tail of this list first and uses short-circuiting to return false as soon as a call to g returns false, but if g has no side effects and always terminates, this is only an implementation detail. Solutions did not have to discuss this issue.) (c) No. The recursive call to f is not the last work the caller needs to do (even though the caller s result may be the result of the recursive call). The caller needs to check the result and use it to determine whether g(x,y) is evaluated. This may be easier to see if we remember e1 andalso e2 is sugar for if e1 then e2 else false. The recursive call here is e1 and the first subexpression of a conditional is not in tail position. (Much shorter explanations are fine. Answers suggesting g(x,y) must be computed lost a small amount since it is only evaluated sometimes, but sometimes is enough to prevent tail recursion.) 3

3. For each of the following programs, give the value that ans is bound to after evaluation. (a) (5 points) val x = 2 val y = 3 fun f z = let val y = x val x = y in x + y + z val z = 4 val ans = f x (b) (6 points) val x = 1 fun f y = if y > 2 then fn z => x + z else fn z => x - z val x = 3 val g = f 4 val x = 5 val ans = g 6 (c) (5 points) fun f x = case x of [] => 0 (a,b)::[] => a + b (a,b)::(c,d)::_ => a + d val ans = f (List.map (fn x => (1,x)) [2,4,8,16,32]) (a) 6 (b) 7 (c) 5 4

4. (a) (10 points) Without using any helper functions, write an ML function filter_map, which combines aspects of List.filter and List.map, as follows: It takes two arguments in curried form: (1) a function f that takes list elements and produces options and (2) a list xs. It returns a list. If v1 is a value in the input list and f v1 returns SOME v2, then v2 is in the output list. Notice v2 is in the output list, not SOME v2. Like List.map, it preserves the order of results: if v1 precedes v2 in the input, f v1 is SOME v3, and f v2 is SOME v4, then v3 precedes v4 in the output. Like List.filter, the result list may be shorter than the input list: if f returns NONE for n elements, then the result will have n fewer elements. (b) (4 points) What is the type of filter_map? (c) (6 points) Use a val binding and filter_map to define positive_lengths, which should take a list of strings and return the lengths of all non-empty strings. For example, positive_lengths ["", "hi", "currying", "", "", "341"] evaluates to [2,8,3]. Use String.size as part of your solution. (d) (2 points) What is the type of positive_lengths? (e) (2 points) Here is an alternate implementation of filter_map if you fill in the blanks with the right ML library functions. Do so. fun filter_map f = ( valof) o ( issome) o ( f) (a) fun filter_map f xs = case xs of [] => [] x::xs => case f x of NONE => filter_map f xs SOME y => y :: filter_map f xs (b) ( a -> b option) -> a list -> b list (c) (Using a let-binding not required) val positive_lengths = filter_map (fn x => let val s = String.size x in if s > 0 then SOME s else NONE ) (d) string list -> int list (e) fun filter_map f = (List.map valof) o (List.filter issome) o (List.map f) 5

5. This problem continues onto the next page and has a part (b). Consider this structure definition: structure NonEmptyStringList :> NESTRINGLIST = struct type t = string list fun newlist s = [s] fun cons (s,ss) = s::ss fun longest ss = case ss of [] => raise List.Empty [s] => s s::ss => if String.size s >= String.size(longest ss) then s else longest ss (a) (16 points) For each of the five following definitions of NESTRINGLIST, decide which of the following is true for client code (code outside the module) and briefly justify your choice: A: It can cause an exception by calling NonEmptyStringList.longest with an empty list. B: It cannot call NonEmptyStringList.longest at all. C: It can call NonEmptyStringList.longest, but not in a way that can cause an exception. nature NESTRINGLIST = type t = string list val newlist : string -> t val longest : t -> string nature NESTRINGLIST = type t = string list val longest : t -> string nature NESTRINGLIST = type t = string list val newlist : string -> t 6

nature NESTRINGLIST = type t val newlist : string -> t val longest : t -> string nature NESTRINGLIST = type t val newlist : string -> string list val longest : t -> string (b) (3 points) Even for the nature(s) where the answer is (C), why is longest a very poorly written function? Describe an argument that a client could create for which longest would perform very badly. (a) (Five natures in order:) A: Because clients know longest takes a string list, they can call NonEmptyStringList.longest [] A: Same reason as previous B: longest is not in the nature and there is no other way to call it C: Because t is abstract and this the argument to longest, the only way to get a t is via calls to newlist and cons, and no such call would produce [] B: Clients do not know that newlist can produce a t. The only function known to produce a t is cons but it also requires a t argument, so no t can ever be produced and therefore longest cannot be called. (b) longest can take exponential time since it is possible for it to use recursion twice at each step for the tail of the list. The worst-case is when the longest string is not near the beginning of the list since running time is exponential in the number of elements that precede the longest string. Even under a nature where t is abstract, clients could build such a list via calls to newlist and cons. 7

This page intentionally blank. 8