70
New Language: ML Main topics: ML syntax Static typing, explicit data types Parameter matching Lazy lists

New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Embed Size (px)

DESCRIPTION

New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching Lazy lists. Static vs. Dynamic Typing. Static Typing: Typing is (can be) done before run-time Usually at compile-time Advantage: safer C,C++,Java Dynamic Typing: Typing is done at run-time - PowerPoint PPT Presentation

Citation preview

Page 1: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

New Language: MLMain topics:ML syntax

Static typing, explicit data typesParameter matching

Lazy lists

Page 2: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Static vs. Dynamic Typing

• Static Typing: Typing is (can be) done before run-time– Usually at compile-time– Advantage: safer– C,C++,Java

• Dynamic Typing: Typing is done at run-time– Usually when there is no compilation phase– Scheme

• ML is a functional language with static typing!

Page 3: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

ML features

• Functional

• Allows polymorphic and recursive user defined datatypes

• Supports static type inference– Types can either be explicitly defined, or inferred

Page 4: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

ML Basics

In Scheme, declaration of names in the global env: (define <name> <exp>)In ML: val <name> = <exp>;

Page 5: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Type information is optional: inferred if not given

- val seconds = 60;•val seconds = 60 : int- val minutes = 60;•val minutes = 60 : int- val hours = 24;•val hours = 24 : int- seconds * minutes * hours;•val it = 86400 : int- it;•val it = 86400 : int- it*3;•val it = 259200 : int- val secInHour_times3 = it;•val secInHour_times3 = 259200 : int

Page 6: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Functions

- fn x => x*x;•val it = fn : int -> intSame as:-fn(x) => x*x;Application:- (fn(x) => x*x) 3; OR (fn(x) => x*x) (3);•val it = 9 : int-(fn x => x+1) ((fn x => x+1) 4); val it = 6 : int

Page 7: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Types and Functions- val square = fn x : real => x*x;•val square = fn : real -> real- val square = fn x => x*x : real;•val square = fn : real -> real- val square = fn x : int => x*x : real;• Error: expression doesn't match constraint [tycon mismatch] expression: int constraint: real in expression: x * x: real

Page 8: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Multiple arguments- val average = fn( x,y) => (x+y) /2.0;val average = fn : real * real -> real- average(3,5);Error: operator and operand don't agree [literal]operator domain: real * realoperand: int * intin expression:average (3,5)- average(3.0,5.0);val it = 4.0 : real- val average1 = fn(x,y) => (x+y) /2;Error: operator and operand don't agree [literal]operator domain: real * realoperand: real * intin expression:(x + y) / 2

Page 9: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Tuple Datatype

• real*real: The type of all real pairs.• int*real: The type of all integer-real pairs.• (real*real)*(real*real): The type of all pair of

real pairs.• real*int*(int*int):A type of triplets of all real,

integer and integer-pairs.• eal*(real -> int): The type of all pairs of a real

number and a function from real to integers.

Page 10: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Cont.

- (1,2);•val it = (1,2) : int * int- (1,2,3);val it = (1,2,3) : int * int * int- val zeropair = (0.0,0.0);•val zeropair = (0.0,0.0) : real * real- val zero_NegOne = (0.0,~1.0);•val zero_NegOne = (0.0,~1.0) : real * real- (zeropair, zero_NegOne);•val it = ((0.0,0.0),(0.0,~1.0)) : (real * real) * (real * real)- val negpair = fn(x,y) => (~x,~y);•val negpair = fn : int * int -> int * int

Page 11: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

String Datatype

- "Monday" ^ "Tuesday";•val it = "MondayTuesday" : string- size(it);•val it = 13 : int- val title = fn name => "Dr. " ^ name;•val title = fn : string -> string- title ("Racket”);•val it = "Dr. Racket" : string

Page 12: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Conditionals and Booleans

- val sign = fn (n) => if n>0 then 1 else if n=0 then 0 else ~1 (* n<0 *);•val sign = fn : int -> int- sign(~3);•val it = ~1 : int

Arithmetic relations: <, >, <=, >=.Logic operators: andalso, orelse, not.

Page 13: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

val size = fn(n) => if n>0 andalso n<100 then "small“ else 100

Error: types of if branches do not agree [literal]then branch: stringelse branch: intin expression:if (n>0) andalso (n<100) then "small" else 100

Page 14: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Notes

1. Using - in symbol names is not allowed : it is interpreted as the - operator.val fact-iter = 3;•Error: non-constructor applied to argument in pattern: -==> use _.2. ML is case sensitive!3. Order of definitions matter (see next)4. Recursive functions require special treatment (see next)

Page 15: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Recursive Functions

• In Scheme:(define fact (lambda (n) (if (= n 0) 1 (* n (fact (- n 1))))))

Page 16: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

• - val fact = fn n:int => if n=0 then 1 else n*fact(n-1);• Error: unbound variable or constructor: fact• Why?

Page 17: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

rec keyword

val rec fact = fn n:int => if n=0 then 1 else n * fact(n-1);

•val fact = fn : int -> int

Page 18: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Mutual Recursion

val rec isEven = fn n:int => if n=0 then true else not isOdd(n-1);

and val rec isOdd = fn n:int => if n=0 then false else not isEven(n-1);

Page 19: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Patterns in Function Arguments- val rec fact = fn 0 => 1 | n => n * fact(n-1);val fact = fn : int -> int

- val rec fact = fn 0 => 1 | 1 => 1 * fact(0);•Warning: match nonexhaustive0 => ...1 => ...val fact = fn : int -> int

Page 20: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

val rec ackermann =fn (0,b) => b+1 | (a,0) => ackermann(a-1,1) | (a,b) => ackermann(a-1, ackermann(a, b-1));

val ackermann = fn : int * int -> int

Page 21: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

“Wildcard”

- val or =fn (true, _) => true| (_, true) => true| (_, _) => false;val or = fn : bool * bool -> bool

Page 22: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

High-order procedures

- val rec sum = fn (term, a, next, b) => if a>b then 0 else term(a)+sum(term,next(a),next,b);

val sum = fn : (int -> int) * int * (int -> int) * int -> int

Page 23: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

average_damp

- val average_damp = fn f => (fn x => (x+f(x))/2.0);

val average_damp = fn : (real -> real) -> real -> real

Page 24: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

let

letval m : int = 3val n : int = m*minm * nend;

val it = 27 : int

Page 25: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

val fact =letval rec iter =fn (0, result) => result | (count, result) => iter(count-1, count*result)infn n => iter(n, 1)end;val fact = fn : int -> int

Page 26: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Lists in ML• val rec list_length = fn(h::t) => 1+list_length(t) | nil => 0;

Response: val list_length = fn:'a list -> int

:: is the value constructor (like cons in scheme)nil =[] (= scheme NULL)All elements of the list must be of the same type (homogenous list)

Polymorphic type: ‘a is a type variabletype string_list = string list;

Page 27: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

head and tail

val head =fn h::_ => h;

val tail=fn _::t => t;

Page 28: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

What about NULLs?

exception Empty;val head =fn nil => raise Empty | h::_ => h;val head = fn : 'a list -> 'a

Page 29: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Example: foldr

val rec foldr =fn (f, e, []) => e | (f, e, (h :: tl) ) => f(h, foldr(f, e, tl));

•val foldr = fn : (('a * 'b -> 'b) * 'b * 'a list) -> 'b

Page 30: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Example: Key-value storage

val rec assoc = fn (str:string, []) => 0 | (str, ((key, value)::s)) => if (str=key) then value else assoc(str, s);

Page 31: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Adding new types

Simple: Atomic User-Defined Types

datatype week = Sunday | Monday | Tuesday | Wednesday | Thursday |Friday | Saturday

week is a type constructorSunday… are the value constructors (convention: start with upper case letter)

Page 32: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Eager list implementation

datatype pair_selector_name = Car | Cdr;datatype pair_selector_name = Car | Cdr;

val cons = fn(x,y) => fn Car => x | Cdr => y;

fn : ('a * 'a) -> (pair_selector_name -> 'a)

Page 33: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Composite User Defined Types

• datatype address = MailBox of int | CityCon1 of string * string * int | CityCon2 of string * string * string * int | Village of string * string;

CityCon1, CityCon2, Village are the value constructors

Page 34: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Equality predicate for addresses

• val eq_address = fn (CityCon1(city, street, number), CityCon2(city', _, street', number')) => city=city' andalso street=street' andalso number = number' | (x, y) => x=y;

Page 35: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Patterns Revisited

• A powerful tool for manipulating different data types– No need for explicit predicates, selectors

• Can’t be used for equality via the repeated use of the same variable name– In fact no symbol can occur twice in the pattern

except for “_”

Page 36: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Equality types

• We have used “=“ to compare both ints and strings– Real.== is used for reals

• “=“ is then automatically defined for complex types if defined for each of their components

• Only such types can be used in patterns• If “=“ is used for a type not known to be an

equality type, a warning will be issued

Page 37: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Recursive Types

• datatype expr = Const of real | Add of expr * expr | Sub of expr * expr | Mul of expr * expr | Div of expr * expr;

Page 38: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Trees: Recursive Polymorphic Types

datatype 'a binary_tree = Empty| Node of 'a binary_tree * 'a * 'a binary_tree;

Type constructor: binary_treeValue constructors: Node (3 params), Empty (no params)

Page 39: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

(*Signature: tree_sizePurpose: Calculate the size (number of nodes) in a binary treeType: 'a binary_tree -> int *)- val rec tree_size =fn Empty => 0 | Node(lft, _, rht) => (1 + tree_size(lft) + tree_size(rht));

Response: val tree_size = fn : 'a binary_tree -> int

Page 40: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Explicit “unioning” through constructors

datatype int_or_string = Int of int | String of string;type int_or_string_binary_tree = int_or_string binary_tree;

Page 41: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Lazy Lists

Page 42: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Motivation

42

(define (sum-primes a b) (define (iter count accum) (cond ((> count b) accum) ((prime? count) (iter (+ count 1) (+ count accum))) (else (iter (+ count 1) accum)))) (iter a 0))

(define (sum-primes a b) (accumulate + 0 (filter prime? (enumerate-interval a b))))

Second implementation consumes a lot of storage

Page 43: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Motivation (Cont.)

43

(car (cdr (filter prime? (enumerate-interval 10000 1000000))))

Requires a lot of time and space

How can we gain the efficiency of iteration, and retain the elegance of sequence-operations?

In ML:Lazy Lists! (Sequences)

Page 44: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Remember scheme applicative vs. normal order evaluation?

• Normal (Lazy) Order Evaluation:– go ahead and apply operator with unevaluated

argument subexpressions– evaluate a subexpression only when value is needed

• to print• by primitive procedure (that is, primitive procedures are

"strict" in their arguments)

• Compromise approach: give programmer control between normal and applicative order.

• Lazy lists: lists with delays

44

Page 45: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

More Motivation

45

Some data types are inherently infiniteIntegers, Reals,…

Can we generate a list of “all” integers?

YES! (if at each point we only materialize a finite prefix..)

Page 46: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Main Idea: Delayed evaluation

46

A list is a pair of (item, remaining list)We will generate a pair (item,promise_to_generate_remaining_list)

Concrete ideas for implementation of a “promise”?

Page 47: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Sequences in ML

47

A list is a pair of (item, remaining list)We will generate a pair (item,promise_to_generate_remaining_list)

Concrete ideas for implementation of a “promise”?

Page 48: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Sequences

48

datatype 'a seq = Nil | Cons of 'a * (unit -> 'a seq);

Cons(1,Nil)=> error

Page 49: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Sequences

49

datatype 'a seq = Nil | Cons of 'a * (unit -> 'a seq);

Cons(1,Nil)=> error

Page 50: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Sequences

50

datatype 'a seq = Nil | Cons of 'a * (unit -> 'a seq);

Cons(1,Nil)=> error

Cons(1, (fn() => Nil)) CORRECT

Page 51: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Sequences

51

datatype 'a seq = Nil | Cons of 'a * (unit -> 'a seq);

Cons(1,Nil)=> error

Cons(1, (fn() => Nil)) CORRECT

Page 52: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Sequence head and tail

exception Empty; -val head = fn Cons(h,tl) => h

| Nil => raise Empty;

-val tail= fn Cons(h,tl) => tl)( | Nil => raise Empty;

Page 53: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

take (first n elements)

val rec take = fn (seq, 0) => [ ]| (Nil, n) => raise Subscript| (Cons(h, tl), n) => h :: take( tl(), n-1);

Page 54: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Infinite sequences

val rec integers_from =fn k => Cons(k, (fn() =>integers_from(k+1)) );

val rec ones=Fn() => Cons(1, (fn() => ones())) );

Definition: an item belongs to an infinite sequence if reachable by finite number of invocations of tail

Page 55: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Using sequences

- head(integers_from (1));val it = 1 : int- integers_from(1);val it = Cons (1,fn) : int seq- tail it;val it = Cons (2,fn) : int seq- tail it;val it = Cons (3,fn) : int seq- take(integers_from(30), 7);val it = [30,31,32,33,34,35,36] : int list

Page 56: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Processing sequences

val rec squares =fn Nil => Nil| Cons(h, tl) => Cons(h*h, (fn()=>squares( tl () )) );val squares = fn : int seq -> int seq

Page 57: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Processing sequences

val rec seq_add =fn (Cons(h1, tl1), Cons(h2, tl2)) =>Cons(h1+h2, (fn() => seq_add(tl1(), tl2() ) ) )| (_,_) => Nil;

val seq_add = fn : int seq * int seq -> int seq

Page 58: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

?Appending sequences

val rec list_append =fn ([], lst) => lst| (h :: lst1, lst2) => h :: list_append(lst1, lst2);val list_append = fn : 'a list * 'a list -> 'a list

val rec seq_append =fn (Nil, seq) => seq| (Cons(h, seq1), seq2) => Cons(h, (fn() => seq_append( seq1(), seq2) ) );val seq_append = fn : 'a seq * 'a seq -> 'a seq

Page 59: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Problem

What if seq1 is infinite??

val rec seq_append =fn (Nil, seq) => seq| (Cons(h, seq1), seq2) => Cons(h, (fn() => seq_append( seq1(), seq2) ) );val seq_append = fn : 'a seq * 'a seq -> 'a seq

Page 60: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Interleave

val rec seq_append =fn (Nil, seq) => seq| (Cons(h, seq1), seq2) => Cons(h, (fn() => seq_append( seq1(), seq2) ) );val seq_append = fn : 'a seq * 'a seq -> 'a seq

val rec interleave =fn (Nil, seq) => seq| (Cons(h, tl), seq) => Cons(h, (fn() => interleave(seq, tl() ) ) );

Page 61: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Interleave

val rec seq_append =fn (Nil, seq) => seq| (Cons(h, seq1), seq2) => Cons(h, (fn() => seq_append( seq1(), seq2) ) );val seq_append = fn : 'a seq * 'a seq -> 'a seq

val rec interleave =fn (Nil, seq) => seq| (Cons(h, tl), seq) => Cons(h, (fn() => interleave(seq, tl() ) ) );

Page 62: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

More sequence processing

val rec seq_filter= fn (pred, Nil) => Nil

( |pred, Cons(h,tl)>= )if pred(h)then Cons(h, (fn()=>seq_filter(pred, tl() )) )else seq_filter(pred, tl() );

val rec seq_map =fn (f, Nil) => Nil| (f, Cons(h,tl)) =>Cons( f(h), (fn() => seq_map(f, tl() )) );val seq_map = fn : ('a -> 'b) * 'a seq -> 'b seq

Page 63: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

63

Infinite sequences of pairsWant to produce the sequence of pairs of all integers (i,j) with i j and bind it to int-pairs.

Abstraction:

Let’s solve an even more general problem. Given two streams

S=(S1, S2 . . . . .) T=(T1, T2 . . . . .)

Consider the infinite rectangular array

(S1,T1) (S1,T2) (S1,T3) . . .(S2,T1) (S2,T2) (S2,T3) . . .(S3,T1) (S3,T2) (S3,T3) . . .. . . . . . . . .

Page 64: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

64

Infinite sequence of pairs(S1,T1) (S1,T2) (S1,T3) . . .(S2,T1) (S2,T2) (S2,T3) . . .(S3,T1) (S3,T2) (S3,T3) . . .. . . . . . . . .Wish to produce all pairs that lie on or above the diagonal:

(S1,T1) (S1,T2) (S1,T3) . . . (S2,T2) (S2,T3) . . . (S3,T3) . . . . . .

If S and T are both the integers then this would be int-pairs

j

i

Page 65: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

65

Infinite sequence of pairs(S1,T1) (S1,T2) (S1,T3) . . . (S2,T2) (S2,T3) . . . (S3,T3) . . . . . .

Write a function pairs such that (pairs s t) would be the desired sequence.

Wishful thinking:

Break the desired sequence into pieces

How do we combine?

1

2

Page 66: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

66

Infinite sequence of pairs

val rec pairs=fn(Nil,…)=>…fn (Cons(h,tl), Cons(h1,tl1)) => interleave ( seq_map( fn(x) => (h,x)), Cons(h1,tl1)), pairs(tl(),tl1()) )

INFINITE LOOP!!!!

Page 67: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

67

Infinite sequence of pairs(S1,T1) (S1,T2) (S1,T3) . . . (S2,T2) (S2,T3) . . . (S3,T3) . . . . . .

1 2

3

val rec pairs=fn(Nil,…)=>…fn (Cons(h,tl), Cons(h1,tl1)) => Cons( (h,h1), fn()=> interleave ( seq_map( fn(x) => (h,x)), tl1()), pairs(tl(),tl1()) )

Now recursion is delayed

Page 68: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Filter- curried version

Page 69: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Stream of all primes?

Page 70: New Language : ML Main topics: ML syntax Static typing, explicit data types Parameter matching

Sieve