COMP 105 Assignment: Hindley-Milner Type Inference

Similar documents
Implementing nml: Hindley-Milner Type Inference

COMP 105 Homework: Type Systems

COMP105 Assignment: Lambda Calculus

Functional programming in μscheme

COMP 105 Assignment: Core ML

COMP 105 Assignment: Smalltalk

COMP 105 Assignment: Smalltalk

Datatype declarations

Functional programming in μscheme


Exercises on ML. Programming Languages. Chanseok Oh

Module 8: Local and functional abstraction

CS558 Programming Languages

CSc 372, Fall 2001 Final Examination December 14, 2001 READ THIS FIRST

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

Agenda. CS301 Session 9. Abstract syntax: top level. Abstract syntax: expressions. The uscheme interpreter. Approaches to solving the homework problem

CSCI-GA Final Exam

Lists. Michael P. Fourman. February 2, 2010

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

Flang typechecker Due: February 27, 2015

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

CS558 Programming Languages

ML 4 Unification Algorithm

CSCI-GA Scripting Languages

Homework 5. Notes. Turn-In Instructions. Reading. Problems. Handout 19 CSCI 334: Spring (Required) Read Mitchell, Chapters 6 and 7.

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

ML Type Inference and Unification. Arlen Cox

Learning Standard ML

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

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

TYPE INFERENCE. François Pottier. The Programming Languages Mentoring ICFP August 30, 2015

Metaprogramming assignment 3

PROFESSOR: Last time, we took a look at an explicit control evaluator for Lisp, and that bridged the gap between

CS 11 Ocaml track: lecture 2

CS558 Programming Languages

CSc 372, Spring 1996 Mid-term Examination Solution Key

CSE-321: Assignment 8 (100 points)

Type Systems, Type Inference, and Polymorphism

Homework 6: Higher-Order Procedures Due: 11:59 PM, Oct 16, 2018

Specification and Verification in Higher Order Logic

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

Lecture #13: Type Inference and Unification. Typing In the Language ML. Type Inference. Doing Type Inference

Learning Standard ML

How does ML deal with +?

Introduction to OCaml

Part I: Written Problems

Overloading, Type Classes, and Algebraic Datatypes

Homework 7: Subsets Due: 11:59 PM, Oct 23, 2018

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

CIS 120 Midterm I February 16, 2015 SOLUTIONS

Programming in Standard ML: Continued

CSc 372, Fall 1996 Mid-Term Examination Monday, October 21, 1996 READ THIS FIRST

Polymorphic lambda calculus Princ. of Progr. Languages (and Extended ) The University of Birmingham. c Uday Reddy

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

Polymorphism and Type Inference

Agenda. CS301 Session 11. Common type constructors. Things we could add to Impcore. Discussion: midterm exam - take-home or inclass?

CS2112 Fall Assignment 4 Parsing and Fault Injection. Due: March 18, 2014 Overview draft due: March 14, 2014

Object-Oriented Programming in Smalltalk

CSSE 304 Assignment #13 (interpreter milestone #1) Updated for Fall, 2018

CSCI 3155: Homework Assignment 4

Assignment 0. Computer Science 52. Due Friday, September 7, 2018, at 5:00 pm

Part I: Written Problems

(Refer Slide Time: 4:00)

Homework: More Abstraction, Trees, and Lists

The design of a programming language for provably correct programs: success and failure

Homework 6: Higher-Order Procedures Due: 10:00 PM, Oct 17, 2017

CPS 506 Comparative Programming Languages. Programming Language Paradigm

CSE 143: Computer Programming II Winter 2019 HW6: AnagramSolver (due Thursday, Feb 28, :30pm)

Standard ML. Data types. ML Datatypes.1

a b c d a b c d e 5 e 7

CSE 143: Computer Programming II Summer 2017 HW5: Anagrams (due Thursday, August 3, :30pm)

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

CS52 - Assignment 8. Due Friday 4/15 at 5:00pm.

;; definition of function, fun, that adds 7 to the input (define fun (lambda (x) (+ x 7)))

CSC 372 Haskell Mid-term Exam Feburary 28, 2014

Lecture Notes on Induction and Recursion

Due: 9 February 2017 at 1159pm (2359, Pacific Standard Time)

Programming Languages ML Programming Project Due 9/28/2001, 5:00 p.m.

Functional Programming

Abstraction and Specification

COS 320. Compiling Techniques

Functional abstraction. What is abstraction? Eating apples. Readings: HtDP, sections Language level: Intermediate Student With Lambda

Functional abstraction

CSE341 Spring 2016, Midterm Examination April 29, 2016

CSc 372, Spring 1996 Mid-Term Examination Tuesday, March 5, 1996 READ THIS FIRST

Polymorphism and Type Inference

1. For every evaluation of a variable var, the variable is bound.

CSci 4223 Principles of Programming Languages

Chapter 15. Functional Programming Languages

Introduction to SML Getting Started

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

CS 11 Haskell track: lecture 1

Typed Racket: Racket with Static Types

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

Recap from last time. Programming Languages. CSE 130 : Fall Lecture 3: Data Types. Put it together: a filter function

All the operations used in the expression are over integers. a takes a pair as argument. (a pair is also a tuple, or more specifically, a 2-tuple)

CSE341 Spring 2016, Final Examination June 6, 2016

Functions. Nate Foster Spring 2018

CSE341 Spring 2017, Final Examination June 8, 2017

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

Transcription:

COMP 105 Assignment: Hindley-Milner Type Inference Due Monday, Novermber 21 at 11:59PM. In this assignment you will implement Hindley-Milner type inference, which represents the current ``best practice'' for flexible static typing. The assignment has two purposes: Setup To help you develop a deep understanding of type inference To help you continue to build your ML programming skills Make a clone of the book code: git clone linux.cs.tufts.edu:/comp/105/build-prove-compare The code you need is in bare/nml/ml.sml. Individual Problems Working on your own, please solve Exercise 1 on page 528 and Exercise 2 on page 528 of Ramsey. These exercises explore some implications of type inference. Problem Details 1. Exploring the meaning of polymorphic types I. Do Exercise 1 on page 528 of Ramsey. 2. Exploring the meaning of polymorphic types II. Do Exercise 2 on page 528 of Ramsey. Pair Problems Working with a partner, please solve 18, 19 and 20 from pages 531 532 of Ramsey, and the two exercises S and T below. Problem Details 18. Implementing a constraint solver. Do Exercise 18 on page 531 of Ramsey. This exercise is probably the most difficult part of the assignment. Before proceeding with type inference, make sure your solver produces the correct result on our test cases and on your test cases. You may also want to show your solver code to the course staff before proceeding to type inference. 19. Implementing type inference. Do Exercise 19 on page 532 of Ramsey. 20. Adding primitives. Do Exercise 20 on page 532 of Ramsey. S. Test cases for the solver. Write three test cases for the constraint solver. At least two of these test cases should be constraints that have no solution. Assuming that we provide a function constrainttest : con -> answer, write your test cases as three successive calls to constrainttest. Do not define constrainttest yourself. Here is a sample set of test cases: val _ = constrainttest (TYVAR "a" ~ TYVAR "b") val _ = constrainttest (CONAPP (TYCON "list", [TYVAR "a"]) ~ TYCON "int") val _ = constrainttest (TYCON "bool" ~ TYCON "int") Naturally, you will supply your own test cases, different from these. COMP 105 Assignment: Hindley-Milner Type Inference 1

T. Test cases for type inference. Write three test cases for type inference. At least two of these test cases should be for terms that fail to type check. Each test case should be a definition written in nml. Here is a sample set of test cases: (val weird (lambda (x y z) (cons x y z))) (+ 1 #t) (lambda (x) (cons x x)) Naturally, you will supply your own test cases, different from these. Extra Credit For extra credit, you may complete any of the following: Mutation, as in Exercise 23(a)(b) and possibly (c) Explicit types, as in Exercise 25 Better error messages, as in Exercise 24(a)(b) and possibly (c) Tuples, as in Exercise 22 Of these exercises the most interesting are probably Mutation (easy) and Explicit types (not easy). What to submit: Individual Problems You should submit two files: a README file containing the names of the people with whom you collaborated the number of hours you worked on the assignment. a file meaning.nml containing your code for Exercise 1 on page 528 and Exercise 2 on page 528. Your answers to Exercise 2 should appear in a comment. How to submit: Individual Problems When you are ready, run submit105-ml-inf-solo to submit your work. Note you can run this script multiple times; we will grade the last submission. What to submit: Pair Problems You should submit four files: a README file containing the names of the people with whom you collaborated the numbers of any extra credit problems you solved the number of hours you worked on the assignment. ml.sml, implementing a complete interpreter for nano-ml which includes your answers to Exercises 18, 19, and 20. stest.sml, containing your answer to Exercise S ttest.nml, containing your answer to Exercise T How to submit: Pair Problems When you are ready, run submit105-ml-inf-pair to submit your work. Note you can run this script multiple times; we will grade the last submission. Problem Details 2

Hints, guidelines, and test code This is one assignment where it pays to run a lot of tests, of both good and bad definitions. The most effective test of your algorithm is not that it properly assign types to correct terms, but that it reject ill-typed terms. I have posted a functional topological sort that makes an interesting test case. If you call your interpreter ml.sml, you can build a standalone version in a.out by running mosmlc ml.sml or a faster version in ml by running mlton -output a.out ml.sml. To help you with the solver, once you have implemented solve, the following code redefines solve into a version that checks itself for sanity (ie, idempotence). It is a good idea to check that the substitution returned by your solver is idempotent before using it in your type inferencer. fun isstandard pairs = let fun distinct a' (a, tau) = a <> a' andalso not (member a' (freetyvars tau)) fun good (prev', (a, tau)::next) = List.all (distinct a) prev' andalso List.all (distinct a) next andalso good ((a, tau)::prev', next) good (_, []) = true in good ([], pairs) end val solve = fn c => let val theta = solve c in if isstandard theta then theta else raise BugInTypeInference "non-standard substitution" end In writing the type-inference code, you should refer to the typing rules of nml, which appear on pages 500-501 of Ramsey. With your solver in place, the type inference should be straightforward, with two exceptions: let and letrec. You can emulate the implementations for val and val-rec, but you must split the constraint into local and global portions. The splitting is covered in detail in the book, on pages 469 472, with particular focus in the sidebar on page 470. Testing The course interpreter is located in /comp/105/bin/nml. If your interpreter can process the initial basis and infer correct types, you are doing OK. The real test of your interpreter is that it should reject incorrect definitions. You should prepare a dozen or so definitions that should not type check, and make sure they don't. For example: (val bad (lambda (x) (cons x x))) (val bad (lambda (x) (cdr (pair x x)))) Pick your toughest three test cases to submit for Exercise T. Avoid common mistakes Here some common mistakes: A common mistake is to create too many fresh variables or to fail to constrain your fresh variables. Another surprisingly common mistake is to include redundant cases in the code for inferring the type of a list literal. As is almost always true of functions that consume lists, it's sufficient to write one case for NIL and one case for PAIR. It's a common mistake to define a new exception and not handle it. If you define any new exceptions, make sure they are handled. It's not acceptable for your interpreter to crash with an unhandled exception just because some nano-ml code didn't type-check. It's a common mistake to omit the initial basis for testing and then to forget to include an initial basis in the interpreter you submit. Hints, guidelines, and test code 3

There are also some common assumptions which are mistaken: It is a mistake to assume that an element of a literal list always has a monomorphic type. It is a mistake to assume that begin is never empty. How your work will be evaluated Your solutions are going to be evaluated automatically. We must be able to compile your solution in Moscow ML by typing, e.g., mosmlc ml.sml If there are errors or warnings in this step, your work will earn No Credit for functional correctness. We will focus most of our evaluation on your constraint solving and type inference. Form Exemplary Satisfactory Must improve The code has no offside violations. Or, the code has just a couple of minor offside violations. Indentation is consistent everywhere. The submission has no bracket faults. The submission has a few minor bracket faults. Or, the submission has no bracketed names, but a few bracketed conditions or other faults. The code has several offside violations, but course staff can follow what's going on without difficulty. In one or two places, code is not indented in the same way as structurally similar code elsewhere. The submission has some redundant parentheses around function applications that are under infix operators (not checked by the bracketing tool) Offside violations make it hard for course staff to follow the code. The code is not indented consistently. The submission contains more than a handful of parenthesized names as in (x) The submission contains more than a handful of parenthesized if conditions. Names Type variables have names beginning with a; types have names beginning with t or tau; constraints have names beginning with c; substitutions have names beginning with theta; lists of things have names that begin conventionally and end in s. Structure The nine cases of simple type equality are handled by these five patterns: TYVAR/any, any/tyvar, CONAPP/CONAPP, TYCON/TYCON, other. The code for solving αâ â¼â Ï has exactly three cases. Or, the submission contains a handful of bracketing faults. Or, the submission contains more than a handful of bracketing faults, but just a few bracketed names or conditions. Types, type variables, constraints, and substitutions mostly respect conventions, but there are some names like x or l that aren't part of the typical convention. The nine cases are handled by nine patterns: one for each pair of value constructors for ty The code for αâ â¼â Ï has more than three cases, but the nontrivial cases all look different. Some names misuse standard conventions; for example, in some places, a type variable might have a name beginning with t, leading a careless reader to confuse it with a type. The case analysis for a simple type equality does not have either of the two structures on the left. The code for αâ â¼â Ï has more than three cases, and different nontrivial cases share duplicate or near-duplicate code. Avoid common mistakes 4

The constraint solver is implemented using an appropriate set of helper functions, each of which has a good name and a clear contract. Type inference for list literals has no redundant case analysis. Type inference for expressions has no redundant case analysis. In the code for type inference, course staff see how each part of the code is necessary to implement the algorithm correctly. Wherever possible appropriate, submission uses map, filter, foldr, and exists, either from List or from ListPair Back to the class home page The constraint solver is implemented using too many helper functions, but each one has a good name and a clear contract. The constraint solver is implemented using too few helper functions, and the course staff has some trouble understanding the solver. Type inference for list literals has one redundant case analysis. Type inference for expressions has one redundant case analysis. In some parts of the code for type inference, course staff see some code that they believe is more complex than is required by the typing rules. Submission sometimes uses a fold where map, filter, or exists could be used. Course staff cannot identify the role of helper functions; course staff can't identify contracts and can't infer contracts from names. Type inference for list literals has more than one redundant case analysis. Type inference for expressions has more than one redundant case analysis. Course staff believe that the code is significantly more complex than what is required to implement the typing rules. Submission includes one or more recursive functions that could have been written without recursion by using map, filter, List.exists, or a ListPair function. How your work will be evaluated 5