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

Similar documents
Handout 2 August 25, 2008

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

Lists. Michael P. Fourman. February 2, 2010

CSE3322 Programming Languages and Implementation

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

Functional Programming

CSCI-GA Scripting Languages

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

Programming Languages

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

SML A F unctional Functional Language Language Lecture 19

F28PL1 Programming Languages. Lecture 14: Standard ML 4

Recap: ML s Holy Trinity

Standard ML. Data types. ML Datatypes.1

CSE 130 Programming Languages. Lecture 3: Datatypes. Ranjit Jhala UC San Diego

Programming Languages

Recap: ML s Holy Trinity. Story So Far... CSE 130 Programming Languages. Datatypes. A function is a value! Next: functions, but remember.

CMSC 330: Organization of Programming Languages

CS 11 Ocaml track: lecture 2

CSE 130 Programming Languages. Datatypes. Ranjit Jhala UC San Diego

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

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

CS558 Programming Languages

CSCC24 Functional Programming Typing, Scope, Exceptions ML

CSC324 Principles of Programming Languages

CS558 Programming Languages

CS Lectures 2-3. Introduction to OCaml. Polyvios Pratikakis

Homework 3 COSE212, Fall 2018

Functional programming with OCaml. Programming with OCaml. Fall Software Foundations CIS 500. OCaml and this course. Announcements. features.

CS558 Programming Languages

News. Programming Languages. Recap. Recap: Environments. Functions. of functions: Closures. CSE 130 : Fall Lecture 5: Functions and Datatypes

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

Introduction to SML Getting Started

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

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

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

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics

Introduction to OCaml

F28PL1 Programming Languages. Lecture 12: Standard ML 2

Inductive Data Types

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

CMSC 330, Fall 2013, Practice Problems 3

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

CMSC 330: Organization of Programming Languages. OCaml Data Types

Fall 2018 Stephen Brookes. LECTURE 2 Thursday, August 30

OCaml Data CMSC 330: Organization of Programming Languages. User Defined Types. Variation: Shapes in Java

Lecture #23: Conversion and Type Inference

Data Types The ML Type System

Functional Programming

Some Advanced ML Features

Conversion vs. Subtyping. Lecture #23: Conversion and Type Inference. Integer Conversions. Conversions: Implicit vs. Explicit. Object x = "Hello";

Programming Languages. Next: Building datatypes. Suppose I wanted. Next: Building datatypes 10/4/2017. Review so far. Datatypes.

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

Programming Languages. Datatypes

CMSC 330, Fall 2013, Practice Problem 3 Solutions

Functional Programming in Haskell Part I : Basics

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

cs242 Kathleen Fisher Reading: Concepts in Programming Languages, Chapter 6 Thanks to John Mitchell for some of these slides.

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

Programming Languages

Currying fun f x y = expression;

A Brief Introduction to Standard ML

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

CVO103: Programming Languages. Lecture 5 Design and Implementation of PLs (1) Expressions

15 150: Principles of Functional Programming. More about Higher-Order Functions

CS 457/557: Functional Languages

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

Cornell University 12 Oct Solutions. (a) [9 pts] For each of the 3 functions below, pick an appropriate type for it from the list below.

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

Products and Records

CSE 341 Section 5. Winter 2018

CS153: Compilers Lecture 15: Local Optimization

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

Introduction to OCaml

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

CS131 Typed Lambda Calculus Worksheet Due Thursday, April 19th

Background. CMSC 330: Organization of Programming Languages. Useful Information on OCaml language. Dialects of ML. ML (Meta Language) Standard ML

CS 321 Programming Languages

Introduction to Typed Racket. The plan: Racket Crash Course Typed Racket and PL Racket Differences with the text Some PL Racket Examples

An introduction introduction to functional functional programming programming using usin Haskell

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

CSE341 Autumn 2017, Midterm Examination October 30, 2017

Outline. What is semantics? Denotational semantics. Semantics of naming. What is semantics? 2 / 21

CS153: Compilers Lecture 14: Type Checking

Patterns The Essence of Functional Programming

CSE341, Fall 2011, Midterm Examination October 31, 2011

Advanced features of Functional Programming (Haskell)

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

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

CMSC 330: Organization of Programming Languages. OCaml Expressions and Functions

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

CSC324 Functional Programming Typing, Exceptions in ML

Functional programming Primer I

Exercises on ML. Programming Languages. Chanseok Oh

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

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

Programming Languages

Lecture 09: Data Abstraction ++ Parsing is the process of translating a sequence of characters (a string) into an abstract syntax tree.

Programming Languages Lecture 14: Sum, Product, Recursive Types

Parametric types. map: ( a (a b) a list b list. filter: ( a bool) a list a list. Why? a and b are type variables!

Transcription:

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

ML This course focuses on compilation techniques for functional languages Programs expressed in Standard ML Mini-ML (the source language) is an expressive core subset of SML. Implementation will need to use modules and structures. Functional programming immutable data structures recursion and functional call as the primary control structure heavy use of higher-order functions Contrast with imperative and object-oriented languages

Expressions Programs are expressions. The meaning of a program is the value of the expression: # 16 + 18 ; val it = 34 : int # 2 * 8 + 3 * 6; val it = 34 : int

Names Introduce bindings using let: # let val v = 200 in v + 1 end; val it = 201 : int # let val y = it * 3 in y end; val it = 603 : int Bindings cannot refer to themselves in definitions: # let val z = z + 1 in z end;; (* illegal *)

Functions # val double = fn (x:int) => x + x val double = fn: int -> int # double 3; val it = 6: int - x is the parameter of the function. The expression x * x is the body. - The expression double 3 is the application of the function - The type of the function is int -> int

Functions # val sumsquare = fn (x:int) => fn (y:int) => x*x + y*y val sumsquare = fn: int -> int -> int (* type annotations required in Mini-ML, but not ML *) # sumsquare 3 4; val it = 25 : int # sumsquare 3; val it = fn: int -> int # fun sumsquare x y = x * x + y * y (* in Mini-ML would write: fun sumsquare(x:int): int -> int = fn(y:int) => (x*x) + (y*y) *) val sumsquare = fn: int -> int -> int # fun sumsquare (x,y) = x * x + y * y (* in Mini-ML would write: fun sumsquare(p: (int * int)):int = (case p of (x,y) => (x * x) + (y * y)) *) val sumsquare = fn: int * int -> int

Booleans and Conditionals There are only two values of type Boolean: true and false # 1 = 2; val it = false : bool # not (5 <= 10); val it = false : bool In Mini-ML true and false represented as constructors of a bool datatype: datatype bool = true false Conditional expressions defined as usual: # if 3 < 4 then 7 else 100; val it = 7 : int # if false then (3 + 3) else 10; val it = 10 : int # if true then 10 else false; Error: types of rules don t agree

Inductive and Recursive Definitions # fun sum 0 = 0 sum n = n + sum(n-1) - val sum = fn: int -> int # sum 3 - val it = 6 : int (* Can t write this in Mini-ML: instead write *) fun sum (n:int):int = case n of 0 => 0 n => n + sum(n-1) Or write: # fun sum(n) = if n = 0 then 0 else n + sum(n-1) - val sum = fn: int -> int # sum 3; - val it = 6 : int

Lists Lists store a collection of homogeneous data values. The empty list is written as [ ]; hd and tl used to deconstruct lists # [1,2,3]; val it = [1,2,3] : int list # let val l = [1,2,3] in [hd(l),hd(tl(l))] end; val it = [1,2] : int list # let val l = [1,2,3] in [hd(l),tl(l)] end;??? Lists can be built from any of type Can build list of lists: # [ [1,2], [1,2,3] ] - val it = [ [1,2], [1,2,3]] : int list list Mini-ML only supports integer lists; must construct lists constructively. datatype intlist = Cons of int * intlist Nil # Cons(1,Cons(2,Cons(3,Nil)))

Lists In ML, can construct lists using cons: # 1 :: [2,3] val it = [1,2,3] : int list Functions to build lists: # fun map(f, []: int list) = [] map(f:int->int, x::l) = f(x)::map(f,l) val map = fn: (int -> int) * int list -> int list # map(fn x => x + 1, [1,2,3]) val it = [2,3,4]: int list What would happen if we removed the type declarations on f and []?

Example Reverse a list: # fun snoc(x:int,y) = if y = [] then [x] else hd(y)::snoc(x,tl(y)) val snoc = fn: int * int list -> int list # fun reverse(l: int list) = if l = [] then [] else snoc( hd(l), reverse(tl l)) Why is this inefficient?

Example # fun reverse l: int list = let fun aux([], result) = result aux(l,result) = aux(tl(l ),hd(l )::result) in aux l [] end - val reverse = fn: int list -> int list Why is this better?

Tail Recursion Express loops using tail recursion: A tail recursive function is one in which the result of every control-path is defined in terms of another function call. # fun fact 0 = 1 fact n = n * fact(n-1) This is not in tail form. # fun fact n = let fun aux(0,r) = r aux(n,r) = aux(n-1,r*n) in aux(n,1) end This is in tail form. Why is this better?

Type Inference & Polymorphism # fun fact 0 = 1 fact n = n * fact (n - 1) val fact = fn: int -> int Compiler deduces that n must be an integer,and that fact is a function over integers # fun map(f,[]) = [] map(f, x::l) = f(x)::map(f,l) val map = fn: ( a -> b) * a list -> b list No polymorphic types (for now) in Mini-ML. a and b are type variables The inferred type tells us that f operates over something of type a and returns something of type b, and that l is a list of type a and map returns a list of type b

Pattern matching and type checking fun reverse (l, r) = if l = nil then r else reverse(tl(l), hd(l) :: r) reverse([1,2,3],[]) [3,2,1] What are the implications of comparing l with nil? What is the type of reverse? val reverse: fn: a list * b list -> b list Assumes that a is an equality type. What happens on the following call? reverse([floor,trunc,ceil])

Pattern matching and type checking Now consider: Or: fun reverse(nil) = nil fun reverse(l,r) = case l of reverse(x::xs) = reverse(xs) @ [x] [] => r x::y => reverse(y,[x]@r) What is the type of reverse? % val reverse: fn : a list -> a list val reverse = fn : a list * a list => a list What happens if we evaluate: % reverse([floor,trunc,ceil]) What about: % reverse(fn a => a, fn b => b+1) The type checker will attempt to instantiate polymorphic types to satisfy the context in which polymorphic functions are used. The type of this expression is therefore (int -> int) list

Data Types Can create new inductively defined, recursive datatypes A powerful programming tool that is useful in preventing errors Example: we have circles and squares, both represented in terms of coordinates: circles: center and radius square: bottom left corner and width both represented as a triple of floats how do we prevent accidentally mistaking a square for a circle? Mini-ML provides three built-in datatypes: datatype bool = true false datatype intoption = NONE SOME of int datatype intlist = Nil Cons of int * intlist Mini-ML doesn t support the creation of new datatypes

Datatypes # datatype shape = Circle of real * real * real Square of real * real * real Creates two constructors of type shape named Circle and Square # Square(1.0,2.0,3.0); - val it = Square(1.0,2.0,3.0) : shape

Datatypes Use pattern matching to extract elements of a datatype: # fun areaofsquare s = case s of Square(_,_,z) => z * z _ => raise Fail not a square # fun areaofsquare(square(_,_,z)) = z * z Constructors behave as both patterns and functions. Identified by being capitalized.

Datatypes # fun areaof s = (case s of Square(_,_,z) => z * z Circle(x,y,r) = 3.14 * r*r) - val areaof = fn: shape -> real

Recursive types Consider the language of arithmetic expressions: exp :: number ( exp + exp) ( exp exp) ( exp * exp)

Recursive types We can translate this grammar directly into a datatype definition datatype ast = Num of int Plus of ast * ast Minus of ast * ast Times of ast * ast Like the grammar, this datatype is recursive Surface details about the syntax (e.g., brackets) have been omitted.

Using abstraction fun ( elem, state) The type variables elem and fold (lst : elem list, state indicate that this istate: state, function is polymorphic over folder: elem * state -> its list and internal state. state : state = let fun loop (lst, state) = They can be omitted. case lst of nil => state h::t = loop(t, folder(h,state)) in loop (lst,istate) end # fold([1,2,3],0,fn(i,s) => i+s) val it = 6:int

Using fold fun ( a, b) map (lst: a list, f: a -> b): b list = fold(lst, [], fn (e,ac) => ac @ [f (e)]) # map([1,2,3],fn a => a+1) [2,3,4]

Value restriction Value Restriction: prevents references from holding values of different type. val r: 'a option ref = ref NONE val r1: string option ref = r val r2: int option ref = r val () = r1 := SOME "foo" val v: int = valof (!r2) First line violates the restriction because ref NONE is not a value. What about: val f: unit -> 'a option ref = fn () => ref NONE val r: 'a option ref = f () b 25

Value restriction Can be unnecessarily restrictive: val id: 'a -> 'a = fn x => x val f = id id However, providing enough context would succeed: val id: 'a -> 'a = fn x => x val f = id id val _ = f 13 But, cannot use f polymorphically: val id: 'a -> 'a = fn x => x val f = id id val _ = f 13 val _ = f "foo" 26

Value restriction What happens in the following: val f: 'a -> 'a = let val r: 'a option ref = ref NONE in fn x => let val y =!r val () = r := SOME x in case y of NONE => x SOME y => y end end val _ = f 13 val _ = f "foo" 27