Crash course on SML Wojciech Moczydowski SML functional

  • Slides: 24
Download presentation
Crash course on SML Wojciech Moczydłowski • SML – functional programming language • Complete

Crash course on SML Wojciech Moczydłowski • SML – functional programming language • Complete formal semantics • Extremely convenient for writing compilers, interpreters, provers and 611 homeworks • OCaml, based on SML, is practical and used in industry

SML - ideology • 3 worlds – expressions, values and types. • Values have

SML - ideology • 3 worlds – expressions, values and types. • Values have types, i. e. 0 : int, “asd” : string • Expressions have types as well, i. e. 3+4 : int, fact : int -> int • Expressions evaluate to values

SML types • Some types: – int, string, char – int*int, int*string – int

SML types • Some types: – int, string, char – int*int, int*string – int -> int, int*int -> int – int list – ‘a -> ‘b -> ‘a

Interpreter - 2+2; val it = 4 : int - 23+17; val it =

Interpreter - 2+2; val it = 4 : int - 23+17; val it = 40 : int - “ 611 rules”; val it = “ 611 rules” : string - ~17 + 17; val it = 0 : int - (17, “a”); val it = (17, “a”) : int * string

Definitions - val i = 10; val i = 10 : int - val

Definitions - val i = 10; val i = 10 : int - val j = i + i; val j = 20 : int - val s = Int. to. String(j); val s = “ 20” : string - val t = (i, i + 1, i + 2); val t = (10, 11, 12) : int *int - val q = #2 t; val q = 11 : int

Datatypes - datatype Bool = True | False - datatype Color = Red |

Datatypes - datatype Bool = True | False - datatype Color = Red | Black - datatype Nat = Zero | S of Nat - True; val it = True : Bool - S(S(Zero)); val it = S(S(Zero)) : Nat

Functions • fun add(n, m : Nat) : Nat = case n of Zero

Functions • fun add(n, m : Nat) : Nat = case n of Zero => m | S(x) => S(add(x, m)); • fun mult(n, m) = case n of Zero => Zero |S(x) => add(n, mult(x, m)) • Evaluation – call by value. • All functions have one argument – add : Nat * Nat -> Nat mult : Nat * Nat -> Nat

Anonymous functions • As in lambda calculus, a function can be specified “on fly”

Anonymous functions • As in lambda calculus, a function can be specified “on fly” - (fn x => x + 17) 26; val it = 43 : int; Large parts of lambda calculus can be expressed.

Polymorphism - val K = fn x => fn y => x; val K

Polymorphism - val K = fn x => fn y => x; val K = fn : ‘a -> ‘b -> ‘a ‘a ‘b are type variables. - K 6 4; val it = 6 : int - K “ 611” 170; val it = “ 611” : string - K K K;

Polymorphism - val I = fn x => x; - val S = fn

Polymorphism - val I = fn x => x; - val S = fn x => fn y => fn z => (x z) (y z); - val Ap = fn f => fn x => f x; However, the following won’t type-check: - val Y = fn f => (fn x => f (x x)); - (fn x => x x);

Datatypes reloaded • datatype ‘a option = NONE | SOME of ‘a; - NONE;

Datatypes reloaded • datatype ‘a option = NONE | SOME of ‘a; - NONE; val it = NONE : ‘a option; - SOME; val it = fn : ‘a -> ‘a option - SOME 5; val it = SOME 5 : int option; - SOME “Cornell”; val it = SOME “Cornell” : string option;

Datatypes - fun div(m, n) = if n = 0 then NONE else SOME

Datatypes - fun div(m, n) = if n = 0 then NONE else SOME (m div n); - datatype (‘a, ‘b) Either = Left of ‘a | Right of ‘b;

Recursive polymorphic datatypes - datatype ‘a Tree = Null | Node of (‘a Tree)

Recursive polymorphic datatypes - datatype ‘a Tree = Null | Node of (‘a Tree) * ‘a * (‘a Tree) - Node (Node(Null, 5, Null), 3, Null); - fun sum(t) = case t of Null => 0 | Node (a, b, c) => sum(a) + b + sum(c)

RPD’s fun size(t) = case t of Null => 0 |Node(t 1, _, t

RPD’s fun size(t) = case t of Null => 0 |Node(t 1, _, t 2) => size t 1 + (size t 2) + 1 fun add(t, n) = case t of Null => Null |Node(t 1, m, t 2) => Node(add(t 1, n), m + n, add(t 2, n))

RPD’s fun mul(t, n) = case t of Null => Null |Node(t 1, m,

RPD’s fun mul(t, n) = case t of Null => Null |Node(t 1, m, t 2) => Node(mul(t 1, n), m * n, mul(t 2, n)) In general?

RPD’s fun map. Tree(t, f) = case t of Null => Null |Node(t 1,

RPD’s fun map. Tree(t, f) = case t of Null => Null |Node(t 1, m, t 2) => Node(map. Tree(t 1, f), f m, map. Tree(t 2, f)) - fun add(t, n) = map. Tree(t, fn m => m + n); - val mul = fn (t, n) => map. Tree (t, fn m => n * m);

RPD’s datatype ‘a list = nil | cons of (‘a * ‘a list); Notation:

RPD’s datatype ‘a list = nil | cons of (‘a * ‘a list); Notation: [] denotes nil (x: : xs) denotes cons (x, xs)

Lists Some lists: [] (1: : (2: : (3: : nil))) (“a”: : ”b”:

Lists Some lists: [] (1: : (2: : (3: : nil))) (“a”: : ”b”: : ”c”: : nil) Another notation: [a, b, c] = a: : b: : c: : nil [1, 2, 3], [“a”, “b”, “c”]

Lists - fun length(l) = case l of [] => 0 |(x: : xs)

Lists - fun length(l) = case l of [] => 0 |(x: : xs) => 1 + length xs; - fun hd [] = raise Fail “Empty” |hd(x: : xs) = x; - fun tl [] = raise Fail “Empty” |tl (x: : xs) = xs;

Lists - fun map(f, l) = case l of [] => [] |(x: :

Lists - fun map(f, l) = case l of [] => [] |(x: : xs) => f x : : (map f xs);

Modules signature SET = sig type ‘‘a set val empty : ‘‘a set val

Modules signature SET = sig type ‘‘a set val empty : ‘‘a set val insert : ‘‘a -> ‘‘a set val elem : ‘‘a -> ‘‘a set -> bool end

Modules structure Set : > SET= struct type ’’a set = ‘‘a list val

Modules structure Set : > SET= struct type ’’a set = ‘‘a list val empty : ‘‘a set = [] val insert : ‘‘a -> ‘‘a set = fn x => fn y => x: : y val elem : ‘‘a -> ‘‘a set -> bool =. . . end

Accessing structure elements - Set. insert, Set. add. . - open Set; - insert,

Accessing structure elements - Set. insert, Set. add. . - open Set; - insert, add, . . .

Standard library • Many useful structures • List : > LIST hd, tl, last,

Standard library • Many useful structures • List : > LIST hd, tl, last, map, find, filter. . . • Option : > OPTION option, is. Some, val Of, filter. . . • String : > STRING size, is. Substring, ^, <=. . .