CSCI-GA Final Exam

Similar documents
Datatype declarations

CSCI-GA Scripting Languages

n n Try tutorial on front page to get started! n spring13/ n Stack Overflow!

CSE341 Autumn 2017, Midterm Examination October 30, 2017

Exercises on ML. Programming Languages. Chanseok Oh

CSE 341 Section 5. Winter 2018

CSE341 Spring 2016, Midterm Examination April 29, 2016

List Functions, and Higher-Order Functions

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

G Programming Languages - Fall 2012

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

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

Programming Paradigms, Fall 06

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

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

CSE341 Spring 2016, Midterm Examination April 29, 2016

CompSci 220. Programming Methodology 12: Functional Data Structures

CSE3322 Programming Languages and Implementation

CS558 Programming Languages

CSE341, Fall 2011, Midterm Examination October 31, 2011

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

CSE 341 : Programming Languages Midterm, Spring 2015

An introduction introduction to functional functional programming programming using usin Haskell

INF 212 ANALYSIS OF PROG. LANGS Type Systems. Instructors: Crista Lopes Copyright Instructors.

Programming Languages Fall 2013

CSE341, Fall 2011, Midterm Examination October 31, 2011

CS558 Programming Languages

Haskell Overview II (2A) Young Won Lim 8/9/16

CSE341, Spring 2013, Final Examination June 13, 2013

Computer Science CSC324 Wednesday February 13, Homework Assignment #3 Due: Thursday February 28, 2013, by 10 p.m.

CS 340 Spring 2019 Midterm Exam

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

Introducing Scala-like function types into Java-TX

Functions and Objects. Week 7: Symbolic Computation

Typed Scheme: Scheme with Static Types

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

CSE341 Spring 2017, Midterm Examination April 28, 2017

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

CSE341 Autumn 2017, Final Examination December 12, 2017

Exercise 1 ( = 24 points)

F28PL1 Programming Languages. Lecture 14: Standard ML 4

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

CSci 4223 Principles of Programming Languages

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

The Haskell HOP: Higher-order Programming

INF 212/CS 253 Type Systems. Instructors: Harry Xu Crista Lopes

CS 61A Interpreters, Tail Calls, Macros, Streams, Iterators. Spring 2019 Guerrilla Section 5: April 20, Interpreters.

Part I: Written Problems

CSE341 Spring 2016, Final Examination June 6, 2016

Programming Systems in Artificial Intelligence Functional Programming

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

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

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

Typed Racket: Racket with Static Types

A general introduction to Functional Programming using Haskell

Inductive Data Types

Exercise 8 Parametric polymorphism November 18, 2016

Functional Programming - 2. Higher Order Functions

CSE 307: Principles of Programming Languages

A Fourth Look At ML. Chapter Eleven Modern Programming Languages, 2nd ed. 1

UNIVERSITETET I OSLO

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

The Typed Racket Guide

CSE 307: Principles of Programming Languages

Implementing nml: Hindley-Milner Type Inference

F28PL1 Programming Languages. Lecture 11: Standard ML 1

Programming Languages Lecture 15: Recursive Types & Subtyping

Introduction to ML. Based on materials by Vitaly Shmatikov. General-purpose, non-c-like, non-oo language. Related languages: Haskell, Ocaml, F#,

CS 275 Name Final Exam Solutions December 16, 2016

Overview. Elements of Programming Languages. Advanced constructs. Motivating inner class example

Overview. finally and resource cleanup

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

Wellesley College CS251 Programming Languages Spring, 2000 FINAL EXAM REVIEW PROBLEM SOLUTIONS

CPL 2016, week 10. Clojure functional core. Oleg Batrashev. April 11, Institute of Computer Science, Tartu, Estonia

Introduction to OCaml

Haskell Overview II (2A) Young Won Lim 8/23/16

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

Programming in Scala Second Edition

COMP 105 Assignment: Hindley-Milner Type Inference

UMBC CMSC 331 Final Exam


ML Built-in Functions

CS558 Programming Languages

Variables and Bindings

An Explicit-Continuation Metacircular Evaluator

Handout 2 August 25, 2008

CSE3322 Programming Languages and Implementation

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

COMPUTER SCIENCE TRIPOS

CSCC24 Functional Programming Typing, Scope, Exceptions ML

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

A Brief Introduction to Standard ML

How does ML deal with +?

CSE341: Programming Languages Lecture 25 Subtyping for OOP; Comparing/Combining Generics and Subtyping. Dan Grossman Winter 2013

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

CSCE 314 Programming Languages

Haskell Types, Classes, and Functions, Currying, and Polymorphism

CSE Programming Languages Final exam - Winter Answer Key

Comp 311: Sample Midterm Examination

Watch out for the arrows. Recollecting Haskell, Part V. A start on higher types: Mapping, 1. A start on higher types: Mapping, 2.

Transcription:

CSCI-GA 2110-003 - Final Exam Instructor: Thomas Wies Name: Sample Solution ID: You have 110 minutes time. There are 7 assignments and you can reach 110 points in total. You can solve the exercises directly on the exam sheet. If you need additional paper, ask the instructor. Do not forget to put your name and ID on every page that you hand in. assignment 1 2 3 4 5 6 7 Σ Grade max. points 25 10 13 18 12 12 20 110 - points Good Luck! 1

Assignment 1 (a) Write a polymorphic ML function Programming in ML (25 Points) zip: a list * b list -> ( a * b) list that takes a pair of lists and zips it to a list of pairs. The following examples demonstrate the intended behavior of zip: - zip ([1,2,3], [4,5,6]); val it = [(1,4),(2,5),(3,6)] : (int * int) list - zip ([1,2], [4,5,6]); val it = [(1,4),(2,5)] : (int * int) list - zip ([1,2,3], [] : int list); val it = [] : (int * int) list Note that if the input lists do not have the same length, then the remaining elements of the longer list are dropped. Your function does not need to be tail-recursive. (10 Points) (b) Write a polymorphic ML function foldr2: ( a * b * c -> c) -> c -> a list * b list -> c that is similar to the ML function foldr but folds two lists together. For example, the following function uses foldr2 to compute the sum of products of two lists of integers: fun sumofproducts (xs, ys) = foldr2 (fn (x, y, s) => x * y + s) 0 (xs, ys) In particular, sumofproducts ([1,2,3],[4,5,6]) should expand to 1 * 4 + (2 * 5 + (3 * 6 + 0)) and sumofproducts ([1,2,3],[4,5]) should expand to 1 * 4 + (2 * 5 + 0) Similar to the function zip, the function foldr2 should discard the remaining elements of the longer list, if the two input lists are not of the same length. (10 Points) (c) Express the function zip using the function foldr2. (5 Points) 2

Solution to Assignment 1: (a) fun zip ([], _) = [] zip (_, []) = [] zip (x::xs, y::ys) = (x,y)::zip (xs,ys) fun foldr2 f acc ([], _) = acc foldr2 f acc (_, []) = acc foldr2 f acc (x::xs, y::ys) = f (x, y, foldr2 f acc (xs, ys)) (b) (c) fun zip (xs, ys) = foldr2 (fn (x,y,xys) => (x,y)::xys) [] (xs, ys) 3

Assignment 2 Type Checking and Type Inference (10 Points) Consider the following ML function declaration fun blurgh (x, y) = if x - y then x * y else x / y handle Div => "Error: Division by 0" This declaration is syntactically correct. However, it contains two type errors. Find and explain these errors. 4

Solution to Assignment 2: First error. The term x-y has either type int or type real, depending on how the interpreter resolves the overloaded arithmetic operations. Either way, the term following after the if in the conditional expression must be of type bool. Second error. The handler for the Div exception returns a value of type string. However, the if expression that is guarded by the handler returns a value of type int or real (again depending on how overloaded operators are resolved). Either way, the types are incompatible. In ML, an exception handler must always return a value of a type that is compatible with the type of the expression that it guards. 5

Assignment 3 Type Inhabitation (13 Points) Write polymorphic ML functions that satisfy the following type signatures: where ˆ a function f: a -> b -> a ˆ a function g: ( a -> b -> c) -> b -> a -> c ˆ a function h: ( a, b) sum * ( a -> c) * ( b -> c) -> c ˆ a function i: ( a, b * c) sum -> ( b, a) sum * ( c, a) sum datatype ( a, b) sum = L of a R of b Do not use recursion or explicit type annotations in your declarations. Remember that in ML type expressions, the type constructor * has higher precedence than the type constructor ->. (3 + 3 + 3 + 4 Points) 6

Solution to Assignment 3: fun f a b = a fun g x b a = x a b fun h (L a, x, y) = x a h (R b, x, y) = y b fun i (L a) = (R a, R a) i (R (b, c)) = (L b, L c) 7

Assignment 4 Scala Traits and Dynamic Binding (18 Points) Consider the following Scala classes and traits: abstract class Term { def eval: Int trait Double extends Term { abstract override def eval = 2 * super.eval trait Increment extends Term { abstract override def eval = 1 + super.eval trait Nullify extends Term { abstract override def eval = 0 class Sum(x: Int, y: Int) extends Term { override def eval = x + y To which value does each of the following expressions evaluate (4 * 3 Points): (a) (new Sum(1,2)).eval (b) (new Sum(1,2) with Double with Increment).eval (c) (new Sum(1,2) with Increment with Double).eval (d) (new Sum(1,2) with Nullify with Increment).eval Explain your results. (6 Points) 8

Solution to Assignment 4: (a) 3. Here eval is bound to the eval method declared in the class Sum. (b) 7. Here eval is bound to the eval method declared in the trait Increment. This method calls the eval method of the class it is mixed in, which is the eval method of Double. This method, in turn, calls the eval method of Sum. The latter returns 3 which is rst multiplied by 2 and then incremented by 1. (c) 8. Here eval is bound to the eval method declared in the trait Double. This method calls the eval method of the class it is mixed in, which is the eval method of Increment. This method, in turn, calls the eval method of Sum. The latter returns 3 which is rst incremented by 1 and then multiplied by 2. (d) 1. Here eval is bound to the eval method declared in the trait Increment. This method calls the eval method of the class it is mixed in, which is the eval method of Nullify. The latter returns 0 immediately, which is then incremented by 1. 9

Assignment 5 Scala Generics (12 Points) Scala provides two traits Function1 and Function2 for objects representing unary and binary functions. They are dened as follows: trait Function1[-T1,+R] { abstract def apply(x: T1): R //... some other methods defined using apply trait Function2[-T1,-T2,+R] { abstract def apply(x: T1, y: T2): R //... some other methods defined using apply For example, we can dene an object Sum that extends Function2 as follows object Sum extends Function2[Int,Int,Int] { def apply(x: Int, y: Int) = x + y and then use it like this scala> Sum(3,4) res0: Int = 7 Write a trait CurriedFunction2 that is both a Function2 and a Function1 where the unary apply method of Function1 is the curried version of the binary apply method of Function2. For example, if we dene: object Sum extends CurriedFunction2[Int,Int,Int] { def apply(x: Int, y: Int) = x + y then we should be able to use the apply method of Sum also in its curried form: scala> Sum(3)(4) res1: Int = 7 Make sure that you provide the correct type parameters when you extend or mix in the traits Function2 and Function1. Also the variance annotations for the type parameters of CurriedFunction2 should be as general as possible. 10

Solution to Assignment 5: trait CurriedFunction2[-T1, -T2, +R] extends Function1[T1,Function1[T2,R]] with Function2[T1,T2,R] { def apply(x: T1) = (y: T2) => apply(x,y) The following solution also works: trait CurriedFunction2[-T1, -T2, +R] extends Function2[T1,T2,R] with Function1[T1,Function1[T2,R]] { def apply(x: T1) = (y: T2) => apply(x,y) 11

Assignment 6 Subtyping and Variances (12 Points) Consider the following two generic Scala classes: class CoVar[+T](x: T) { def method1: T = x def method2(y: T) : List[T] = List(x,y) class ContraVar[-T](x: T) { def method1: T = x def method2(y: T) : List[T] = List(x,y) The Scala compiler will reject both classes because at least one method in each class violates the variance annotation of the type parameter T of that class. (a) For each class, explain what these variance violations are. (6 Points) (b) Change each class such that the violations of variances are xed. You are not allowed to change any of the following: ˆ the variance annotation of the type parameter T; ˆ the type of the parameter x; ˆ the parameter names and bodies of the methods. However, you are allowed to introduce additional type parameters and type bounds, and change the argument and return types of methods. If you change any of the method types, they should remain as precise as possible (e.g., you are not allowed to use the types Any or Nothing). You might nd it more dicult to x the class ContraVar. Hint: introduce an additional type parameter for the whole class. (6 Points) 12

Solution to Assignment 6: (a) In the class CoVar the covariant type parameter T appears in contravariant position in the argument type of method method2. On the other hand, in the class ContraVar the contravariant type parameter T appears in covariant position in the result types of methods method1 and method2. (b) class CoVar[+T](x: T) { def method1: T = x def method2[u >: T](y: U) : List[U] = List(x,y) class ContraVar[+U, -T <: U](x: T) { def method1: U = x def method2(y: T) : List[U] = List(x,y) 13

Assignment 7 Exceptions and call/cc (20 Points) (a) Explain why it is useful to dene exceptions as classes in object oriented languages like C++, Java, and Scala. (4 Points) (b) Languages such as Java and Scala provide try-finally blocks for exception handling. What do they do and what are they used for? (4 Points) (c) How do exception handlers in functional languages like ML and Scala dier from those of imperative languages like C++ and Java? (4 Points) (d) Consider the following Scheme programs. evaluate to? (2 + 2 + 4 Points) Which value does each of these programs (i) (+ 4 (call/cc (lambda (c) 1))) (ii) (+ (+ 1 2) (call/cc (lambda (c) (+ (+ 1 2) (c 5))))) (iii) (define (search return wanted? lst) (if (wanted? (car lst)) (return (car lst)) (search return wanted? (cdr lst)))) (define (fluffy lst) (+ 1 (call/cc (lambda (return) (search return (lambda (x) (> x 3)) lst))))) (fluffy (1 2 3 4 5)) You do not need to explain your results to get full credit. Though, you might want to explain how you obtained the result for a chance of receiving partial credit in case your answer is incorrect. 14

Solution to Assignment 7: (a) This allows to group exceptions based on their subtype relationship. For example, one can dene a common exception handler for all exceptions that are subclasses of a specic class. (b) The finally block is executed when control leaves the try block, no matter whether this is due to normal termination of the block or because an exception was thrown but not caught in the try block. This is useful, for example, to ensure that all resources (such as locks, le descriptors, network sockets etc.) that have been acquired for usage in the current control block are properly released before control exits this block (e.g., because a thrown exception was not caught). (c) Unlike in imperative languages, where exception handlers are statements, in functional languages exception handlers return values just like any other expression. The result value of the exception handler is also the result value of the expression that is guarded by the handler in the case that an exception is thrown and caught by the handler. In statically typed languages such as ML and Scala, the type of the exception handler therefore has to be compatible with the type of the expression that it guards. (d) (i) 5 (ii) 8 (iii) 5. The function search calls the passed continuation return with the rst list element that satises the given predicate. This is the element 4. The continuation then increments this value by 1. 15