Introduction to ML Last time: Basics: integers, Booleans, tuples,... simple functions introduction to data types This time, we continue writing an evaluator.

Slides:



Advertisements
Similar presentations
Sml2java a source to source translator Justin Koser, Haakon Larsen, Jeffrey Vaughan PLI 2003 DP-COOL.
Advertisements

More ML Compiling Techniques David Walker. Today More data structures lists More functions More modules.
Modern Programming Languages, 2nd ed.
A Fourth Look At ML 1. Type Definitions Predefined, but not primitive in ML: Type constructor for lists: Defined for ML in ML datatype bool = true | false;
A Third Look At ML 1. Outline More pattern matching Function values and anonymous functions Higher-order functions and currying Predefined higher-order.
ML Exceptions.1 Standard ML Exceptions. ML Exceptions.2 Exceptions – The Need  An extensive part of the code is error handling  A function can return.
Type Checking, Inference, & Elaboration CS153: Compilers Greg Morrisett.
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists Dan Grossman Winter 2013.
CMSC 330: Organization of Programming Languages Tuples, Types, Conditionals and Recursion or “How many different OCaml topics can we cover in a single.
ML Lists.1 Standard ML Lists. ML Lists.2 Lists  A list is a finite sequence of elements. [3,5,9] ["a", "list" ] []  ML lists are immutable.  Elements.
ML Datatypes.1 Standard ML Data types. ML Datatypes.2 Concrete Datatypes  The datatype declaration creates new types  These are concrete data types,
Programming Languages Section 1 1 Programming Languages Section 1. SML Fundamentals Xiaojuan Cai Spring 2015.
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Winter 2013.
Getting started with ML ML is a functional programming language. ML is statically typed: The types of literals, values, expressions and functions in a.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
Chapter ElevenModern Programming Languages1 A Fourth Look At ML.
A Fourth Look At ML Chapter ElevenModern Programming Languages, 2nd ed.1.
Patterns in ML functions. Formal vs. actual parameters Here's a function definition (in C): –int add (int x, int y) { return x + y; } –x and y are the.
CS 320: Compiling Techniques David Walker. People David Walker (Professor) 412 Computer Science Building office hours: after each.
Introduction to ML – Part 1 Frances Spalding. Assignment 1 chive/fall05/cos441/assignments/a1.ht m
Standard ML- Part I Compiler Baojian Hua
5/11/2015IT 3271 Types in ML (Ch 11) datatype bool = true | false; datatype 'element list = nil | :: of 'element * 'element list n Predefined, but not.
Module Language. Module language The Standard ML module language comprises the mechanisms for structuring programs into separate units. –Program units.
Introduction to ML – Part 1 Kenny Zhu. Assignment 2 chive/fall07/cos441/assignments/a2.ht m
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
CS 320: Compiling Techniques David Walker. People David Walker (Professor) 412 Computer Science Building office hours: after each.
Introduction to ML - Part 2 Kenny Zhu. What is next? ML has a rich set of structured values Tuples: (17, true, “stuff”) Records: {name = “george”, age.
Introduction to ML You will be responsible for learning ML on your own. Today I will cover some basics Read Robert Harper’s notes on “an introduction to.
Standard ML- Part II Compiler Baojian Hua
Last Time Introduction Course Logistics Introduction to ML Base Types Tuples and Records Functions & Polymorphism See Harper ’ s Intro to ML.
CS 320: Compiling Techniques David Walker. People David Walker (Professor) 412 Computer Science Building office hours: after each.
Crash course on SML Wojciech Moczydłowski SML – functional programming language Complete formal semantics Extremely convenient for writing compilers, interpreters,
1 Functional Programming and ML. 2 What’s wrong with Imperative Languages? State State Introduces context sensitivity Introduces context sensitivity Harder.
CS 320: Compiling Techniques David Walker. People David Walker (Professor) 412 Computer Science Building office hours: after each.
OCaml The PL for the discerning hacker.. Hello. I’m Zach, one of Sorin’s students.
ML Datatypes.1 Standard ML Data types. ML Datatypes.2 Concrete Datatypes  The datatype declaration creates new types  These are concrete data types,
CSE-321 Programming Languages Introduction to Functional Programming (Part II) POSTECH March 13, 2006 박성우.
CSE 341 Programming Languages Racket Datatype Style Programming Zach Tatlock Spring 2014.
CSC 580 – Theory of Programming Languages, Spring, 2009 Week 9: Functional Languages ML and Haskell, Dr. Dale E. Parson.
Chapter 9: Functional Programming in a Typed Language.
Built-in Data Structures in Python An Introduction.
Functional Programming With examples in F#. Pure Functional Programming Functional programming involves evaluating expressions rather than executing commands.
A Second Look At ML 1. Outline Patterns Local variable definitions A sorting example 2.
F28PL1 Programming Languages Lecture 13: Standard ML 3.
A Third Look At ML Chapter NineModern Programming Languages, 2nd ed.1.
CMSC 330: Organization of Programming Languages
Error Example - 65/4; ! Toplevel input: ! 65/4; ! ^^ ! Type clash: expression of type ! int ! cannot have type ! real.
Chapter SevenModern Programming Languages1 A Second Look At ML.
CSED101 INTRODUCTION TO COMPUTING SUM TYPE 유환조 Hwanjo Yu.
1 FP Foundations, Scheme In Text: Chapter Chapter 14: FP Foundations, Scheme Mathematical Functions Def: A mathematical function is a mapping of.
1 Objective Caml (Ocaml) Aaron Bloomfield CS 415 Fall 2005.
CMSC 330: Organization of Programming Languages Object Oriented Programming with OCaml.
CSE-321 Programming Languages Introduction to Functional Programming POSTECH 박성우.
CSE341: Programming Languages Lecture 17 Implementing Languages Including Closures Dan Grossman Spring 2017.
Principles of programming languages 12: Functional programming
ML: a quasi-functional language with strong typing
ML Again ( Chapter 7) Patterns Local variable definitions
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Spring 2013.
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Zach Tatlock Winter 2018.
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Spring 2017.
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Autumn 2018.
Objective caml Daniel Jackson MIT Lab for Computer Science 6898: Advanced Topics in Software Design March 18, 2002.
FP Foundations, Scheme In Text: Chapter 14.
CSE 341 Section 5 Winter 2018.
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Autumn 2017.
CSE-321 Programming Languages Introduction to Functional Programming
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Spring 2016.
CSE-321 Programming Languages Introduction to Functional Programming
CSE341: Programming Languages Lecture 17 Implementing Languages Including Closures Dan Grossman Spring 2019.
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Spring 2019.
Presentation transcript:

Introduction to ML Last time: Basics: integers, Booleans, tuples,... simple functions introduction to data types This time, we continue writing an evaluator for a simple language Pierce, Chapter 4 (in O’Caml) Show how to use: more functions exceptions modules

A little language (LL) An arithmetic expression e is a boolean value an if statement (if e1 then e2 else e3) the number zero the successor of a number the predecessor of a number a test for zero (isZero e)

LL abstract syntax in ML datatype term = Bool of bool | If of term * term * term | Zero | Successor of term | Predecessor of term | IsZero of term datatype declarations give you three things: 1. a new type 2. constructors functions for building objects of the new type 3. patterns for decomposing datatypes

LL abstract syntax in ML If (Bool true, Zero, Successor (Successor Zero)) represents “if true then 0 else succ(succ 0)” If Booltrue Zero Suc. Zero

Function declarations fun isNumberValue t = case t of Zero => true | Successor t2 => isNumberValue t2 | _ => false function name function parameter default pattern matches anything

A very subtle error fun isNumberValue t = case t of zero => true | Successor t2 => isNumberValue t2 | _ => false The code above type checks. But when we test it refined the function always returns “true.” What has gone wrong?

A very subtle error fun isNumberValue t = case t of zero => true | Successor t2 => isNumberValue t2 | _ => false The code above type checks. But when we test it refined the function always returns “true.” What has gone wrong? -- zero is not capitalized -- ML treats it like a variable pattern (matches anything!)

Another function fun isNumberValue t =... fun isValue t = case t of Bool _ => true | t => isNumberValue t

Exceptions exception Error of string fun debug s : unit = raise (Error s)

Exceptions exception Error of string fun debug s : unit = raise (Error s) - debug "hello"; uncaught exception Error raised at: ex.sml: in SML interpreter:

Evaluator fun isNumberValue t =... fun isValue t =... exception NoRule fun eval1 t = case t of Bool _ | Zero => raise NoRule...

Evaluator... fun eval1 t = case t of Bool _ | Zero => raise NoRule | If(Bool b,t2,t3) => (if b then t2 else t3) | If(t1,t2,t3) => If (eval1 t1,t2,t3)...

Evaluator exception NoRule fun eval1 t = case t of... | Successor t => if isValue t then raise NoRule else let val t’ = eval1 t in Successor t’ end let expression: let declarations in expression end

Finishing the Evaluator fun eval1 t = case t of... |... | Successor t =>... | Predecessor t =>... | IsZero t =>... be sure your case is exhaustive

Finishing the Evaluator fun eval1 t = case t of... |... | Successor t =>... What if we forgot a case?

Finishing the Evaluator ex.sml: Warning: match nonexhaustive (Bool _ | Zero) =>... If (Bool b,t2,t3) =>... If (t1,t2,t3) =>... Successor t =>... fun eval1 t = case t of... |... | Successor t =>... What if we forgot a case?

Multi-step evaluation fun eval1 t =... fun eval t = let fun loop t = loop (eval1 t) val message = “Done\n” in ((loop t) handle NoRule => print message | Error s => print s) end Be very careful with the syntax of handle (use extra parens)

Done with the evaluator

ML is all about functions There are many different ways to define functions! I almost always use “fun f x =...” When I am only going to use a function once and it is not recursive, I write an anonymous function: (fn x =>...)

Anonymous functions val n = 3 val isValue = (fn t => case t of Bool _ => true | t => isNumberValue t) binds a variable (n) to a value (3) binds a variable (isValue) to the anonymous function value fn keyword introduces anonymous fun

Anonymous functions type ifun = int -> int val intCompose : ifun * ifun -> ifun =... fun add3 x = intCompose ((fn x => x + 2), (fn y => y + 1)) x a pair of anonymous functions a type definition (very convenient)

Anonymous functions type ifun = int -> int val intCompose : ifun * ifun -> ifun = fn (f,g) => (fn x => f (g x)) fun add3 x = intCompose ((fn x => x + 2), (fn y => y + 1)) x result is a function! argument is pair of functions pattern match against arg

Another way to write a function fun f x = can be written as: val f = (fn x =>......) provided the function is not recursive; f does not appear in

Another way to write a function fun f x =.... can always be written as: val rec f = (fn x =>...f can be used here...) keyword rec declares a recursive function value

Yet another way to write a function fun isNumberValue Zero = true | isNumberValue (Successor t2) = true | isNumberValue (_) = true This is just an abbreviation for fun isNumberValue t = case t of Zero => true | Successor t2 => true | _ => true

Yet another way to create a type error fun isNumberValue 0 = true | isNumberValue (Successor t2) = true | isNumberValue (_) = true ex.sml: Error: parameter or result constraints of clauses don't agree [literal] this clause: term -> 'Z previous clauses: int -> 'Z in declaration: isNumberValue = (fn 0 => true | Successor t2 => true | _ => true)

Parametric Polymorphism Functions like compose work on objects of many different types val compose = fn f => fn g => fn x => f (g x) compose (fn x => x + 1) (fn x => x + 2) compose not (fn x => x < 17)

Parametric Polymorphism Functions like compose work on objects of many different types val compose = fn f => fn g => fn x => f (g x) compose not (fn x => x < 17) compose (fn x => x < 17) not BAD!!

Parametric Polymorphism Functions like compose work on objects of many different types val compose = fn f => fn g => fn x => f (g x) compose: (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b) Note: type variables are written with ‘ a type variable stands for any type

Parametric Polymorphism Functions like compose work on objects of many different types compose: (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b) compose: (int -> ‘b) -> (‘c -> int) -> (‘c -> ‘b) can be used as if it had the type:

Parametric Polymorphism Functions like compose work on objects of many different types compose: (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b) compose: ((int * int) -> ‘b) -> (‘c -> (int * int)) -> (‘c -> ‘b) can be used as if it had the type:

Parametric Polymorphism Functions like compose work on objects of many different types compose: (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b) compose: (unit -> int) -> (int -> unit) -> (int -> int) can be used as if it had the type:

Parametric Polymorphism compose not : ?? compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b) not : bool -> bool

Parametric Polymorphism compose not : ?? compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b) not : bool -> bool type of compose’s argument must equal the type of not: bool -> bool == (‘a -> ‘b)

Parametric Polymorphism compose not : ?? compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b) not : bool -> bool ‘a must be bool ‘b must be bool as well (in this use of compose) therefore:

Parametric Polymorphism compose not : (‘c -> bool) -> (c’ -> bool) compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b) not : bool -> bool ‘a = bool ‘b = bool

Parametric Polymorphism compose not : (‘c -> bool) -> (c’ -> bool) (compose not) not : bool -> bool compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b) not : bool -> bool

Parametric Polymorphism compose not : (‘c -> bool) -> (c’ -> bool) (compose not) not : ?? compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b) not : bool -> bool

Parametric Polymorphism compose (fn x => x) : ? compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b)

Parametric Polymorphism compose (fn x => x) : ? compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b) ‘d -> ‘d

Parametric Polymorphism compose (fn x => x) : ? compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b) ‘d -> ‘d must be the same ie: ‘a = ‘d ‘b = ‘d

Parametric Polymorphism compose (fn x => x) : ? compose : (‘d -> ‘d) -> (‘c -> ‘d) -> (‘c -> ‘d) ‘d -> ‘d must be the same ie: ‘a = ‘d ‘b = ‘d

Parametric Polymorphism compose (fn x => x) : ? compose : (‘d -> ‘d) -> (‘c -> ‘d) -> (‘c -> ‘d) ‘d -> ‘d (‘c -> ‘d) -> (‘c -> ‘d)

Lists Lists: nil : ‘a list :: : ‘a * ‘a list -> ‘a list 3 :: 4 :: 5 :: nil : int list (fn x => x) :: nil : (‘a -> ‘a) list

Lists Lists: [] : ‘a list 3 :: [4, 5] : int list [fn x => x] : (‘a -> ‘a) list a different way of writing “nil”

List Processing Functions over lists are usually defined by case analysis (induction) over the structure of a list Hint: often, the structure of a function is guided by the type of the argument (recall eval) fun length l = case l of nil => 0 l _ :: l => 1 + (length l)

List Processing fun map f l = case l of nil => [] l x :: l => (f x) :: (map f l) an incredibly useful function: - map (fn x => x+1) [1,2,3]; > val it = [2,3,4] ; int list

List Processing fun fold f a l = case l of nil => a l x :: l => f (fold f a l) x another incredibly useful function what does it do? what is its type? use it to write map.

ML Modules Signatures Interfaces Structures Implementations Functors Parameterized structures Functions from structures to structures

Structures structure Queue = struct type ‘a queue = ‘a list * ‘a list exception Empty val empty = (nil, nil) fun insert (x, q) = … fun remove q = … end

Structures structure Queue = struct type ‘a queue = ‘a list * ‘a list exception Empty... end fun insert2 q x y = Queue.insert (y, Queue.insert (q, x))

Structures structure Queue = struct... end structure Q = Queue fun insert2 q x y = Q.insert (y, Q.insert (q, x)) convenient abbreviation

Structures structure Queue = struct... end open Queue fun insert2 q x y = insert (y, insert (q, x)) for lazy programmers -- not encouraged!

Structures structure Queue = struct type ‘a queue = ‘a list * ‘a list... end fun insert2 (q1,q2) x y : ‘a queue = (x::y::q1,q2) by default, all components of the structure may be used -- we know the type ‘ a queue

Signatures signature QUEUE = sig type ‘a queue exception Empty val empty : ‘a queue val insert : ‘a * ‘a queue -> ‘a queue val remove : ‘a queue -> ‘a * ‘a queue end abstract type -- we don ’ t know the type ‘ a queue

Information hiding signature QUEUE = sig type ‘a queue... end structure Queue :> QUEUE = struct type ‘ a queue = ‘ a list * ‘ a list val empty = (nil, nil) … end fun insert2 (q1,q2) x y : ‘ a queue = (x::y::q1,q2) does not type check

Signature Ascription Opaque ascription Provides abstract types structure Queue :> QUEUE = … Transparent ascription A special case of opaque ascription Hides fields but does not make types abstract structure Queue_E : QUEUE = … SEE Harper, chapters for more on modules

Other things functors (functions from structures to structures) references (mutable data structures) ref e; !e; e1 := e2 while loops, for loops arrays (* comments (* can be *) nested *) a bunch of other stuff...

Last Things Learning to program in SML can be tricky at first But once you get used to it, you will never want to go back to imperative languages Check out the reference materials listed on the course homepage