SML by example Compila(on 2016 Aslan Askarov ( aslan@cs.au.dk ) - - PowerPoint PPT Presentation

sml by example
SMART_READER_LITE
LIVE PREVIEW

SML by example Compila(on 2016 Aslan Askarov ( aslan@cs.au.dk ) - - PowerPoint PPT Presentation

SML by example Compila(on 2016 Aslan Askarov ( aslan@cs.au.dk ) Revised from slides by E.Ernst Star%ng an SML interac%ve session sml Standard ML of New Jersey v110.78 [built: Sun Apr 26 01:06:11 2015] - 1 + 1; val it = 2 : int This is an


slide-1
SLIDE 1

SML by example

Compila(on 2016

Aslan Askarov (aslan@cs.au.dk)

Revised from slides by E.Ernst

slide-2
SLIDE 2

Star%ng an SML interac%ve session

› sml Standard ML of New Jersey v110.78 [built: Sun Apr 26 01:06:11 2015]

  • 1 + 1;

val it = 2 : int

This is an explicit declara0on. It is treated as implicit declara0on of a standard variable it. We can examine its content by evalua0ng it

  • it;

val it = 2 : int

slide-3
SLIDE 3

Ge#ng in and out of SML interac3ve session

  • ^D (* Exit back to shell with ^D *)

> _

Use rlwrap program to improve your experience of the SML interac8ve session (On course VM it is already set via bash alias, so just sml is OK)

> rlwrap sml

slide-4
SLIDE 4

Ge#ng in and out of SML interac3ve session

  • (fn x => fn y => x = y );

stdIn:1.21 Warning: calling polyEqual val it = fn : ''a -> ''a -> bool

Eq warning can be suppressed

> rlwrap sml -Ccontrol.poly-eq-warn=false ...

  • (fn x => fn y => x = y );

val it = fn : ''a -> ''a -> bool

  • ^D
slide-5
SLIDE 5

Not all types can be compared for equality

  • 42.0 = 42.0;

stdIn:1.2-1.13 Error: operator and operand don't agree [equality type required]

  • perator domain: ''Z * ''Z
  • perand: real * real

in expression: 42.0 = 42.0

  • Real.== (42.0, 42.0);

val it = true : bool

slide-6
SLIDE 6

Expressions, declara0ons

  • 3 + 4;

val it = 7 : int

  • val res = 3 + 4;

val res = 7 : int

  • res * 2 ;

val it = 14 : int

  • res div 2: int;

val it = 3 : int

  • (res: int) div (2 : int);

val it = 3 : int

slide-7
SLIDE 7

Arithme(c and logical expressions

  • val y = Math.sqrt 2.0;

[autoloading] [library $SMLNJ-BASIS/basis.cm is stable] [autoloading done] val y = 1.41421356237 : real

  • val large = 10 < res;

val large = false : bool

  • y > 0.0 andalso 1.0/y > 7.0;

val it = false : bool

  • if 3 < 4 then 42 else 43;

val it = 42 : int

slide-8
SLIDE 8

String values and operators

  • val title = "Mr";

val title = "Mr" : string

  • val name = "Tambourine Man";

val name = "Tambourine Man" : string

  • val junkmail = "Dear " ^ title ^ " " ^ name ^ ", you have won $$$!";

val junkmail = "Dear Mr Tambourine Man, you have won $$$!" : string

  • val n = size junkmail;

val n = 41 : int

  • substring (junkmail, 0, 22);

val it = "Dear Mr Tambourine Man" : string

slide-9
SLIDE 9

A type error

  • Math.sqrt 2;

stdIn:35.1-35.12 Error: operator and operand don't agree [literal]

  • perator domain: real
  • perand: int

in expression: Math.sqrt 2

  • perator domain = expected (required) type
  • perand = actual type
slide-10
SLIDE 10

Func%on declara%ons

  • fun circleArea r = Math.pi * r * r;

val circleArea = fn : real -> real

  • val a = circleArea 10.0;

val a = 314.159265359 : real

  • fun doubl x = 2.0 * x ;

val doubl = fn : real -> real

  • doubl (doubl 3.5);

val it = 14.0 : real

slide-11
SLIDE 11

Func%on declara%ons (cont')

  • fun junkmail title name =

= "Dear " ^ title ^ " " ^ name ^ ", You have won $$$!"; val junkmail = fn : string -> string -> string

  • junkmail "Mr" "Tambourine Man";

val it = "Dear Mr Tambourine Man, You have won $$$!" : string

slide-12
SLIDE 12

Swapping arguments

  • fun swapped x y = junkmail y x;

val swapped = fn : string -> string -> string

  • swapped "Mr";

val it = fn : string -> string

  • (swapped "Mr") "Alice";

val it = "Dear Alice Mr, You have won $$$!" : string

  • val f = swapped "Mr";

val f = fn : string -> string

slide-13
SLIDE 13

Func%on composi%on

  • fun half x = x / 2.0;

val half = fn : real -> real

  • half (Math.sqrt 2.0);

val it = 0.707106781187 : real

  • (half o Math.sqrt) 2.0; (* same as above *)

val it = 0.707106781187 : real

  • half o Math.sqrt; (* function composition is a function *)

val it = fn : real -> real

slide-14
SLIDE 14

Func%ons are first-class

  • val also_sqrt = Math.sqrt;

val also_sqrt = fn : real -> real

  • also_sqrt 2.0;

val it = 1.41421356237 : real

slide-15
SLIDE 15

Recursive func,on declara,ons

  • fun fac n = if n = 0 then 1 else n * fac (n - 1);

val fac = fn : int -> int

  • fac 10;

val it = 3628800 : int

  • fun even n = if n = 0 then true else odd (n - 1)

= and odd n = if n = 0 then false else even (n - 1); val even = fn : int -> bool val odd = fn : int -> bool

In general, func-ons can only be used to a4er declara-on

slide-16
SLIDE 16

Anonymous func+ons

  • fn x => x * 10;

val it = fn : int -> int

  • (fn x => x * 10) 42;

val it = 420 : int

slide-17
SLIDE 17

Type constraints

  • fun isLarge (x : real): bool = 10.0 < x ; (* constrain argument *)

val isLarge = fn : real -> bool

  • isLarge 89.0;

val it = true : bool

  • (res: int) div (2 : int); (* constrain operand *)

val it = 3 : int

  • (op div: int * int -> int ) (res:int, 2 : int); (* constrain operator *)

val it = 3 : int

slide-18
SLIDE 18

The scope of a binding

  • let val res = 7 in res div 2 end (* local binding *)

val it = 3 : int

  • val x = 5; (* set x to 5: int *)

val x = 5 : int

  • let val x = 3 < 4 (* new x is true: bool *)

= in if x then 117 else 118 (* uses the new x *) = end; val it = 117 : int

  • x; (* old x is stil 5: int*)

val it = 5 : int

slide-19
SLIDE 19

Basic pa(ern matching

  • fun fac 0 = 1 (* use first case that matches *)

= | fac n = n * fac (n - 1); val fac = fn : int -> int

  • fac 10 ;

val it = 3628800 : int

  • fun fac n = (* same meaning *)

= case n of = 0 => 1 = | _ => n * fac (n - 1); val fac = fn : int -> int

slide-20
SLIDE 20

Pairs and tuples

  • val p = (2,3);

val p = (2,3) : int * int

  • val w = (2, true, (7, false), "blah");

val w = (2,true,(7,false),"blah") : int * bool * (int * bool) * string

  • #2 w; (* projection *)

val it = true : bool

  • #4 w;

val it = "blah" : string

  • #1 (#3 w);

val it = 7 : int

slide-21
SLIDE 21

Pairs and tuples

  • fun add (x,y) = x + y ; (* "argument list" is a single argument*)

val add = fn : int * int -> int

  • add (2,3);

val it = 5 : int

  • val noon = (12,0); (* tuples are values *)

val noon = (12,0) : int * int

  • val talk = (09,00);

val talk = (9,0) : int * int

  • print "Hello\n";

Hello val it = () : unit (* the empty tuple: no info *)

slide-22
SLIDE 22

Pairs and tuples

  • fun earlier ((h1, m1), (h2, m2)) =

= h1 < h2 orelse (h1 = h2 andalso m1 < m2 ); val earlier = fn : (int * int) * (int * int) -> bool

  • earlier noon talk;

stdIn:166.1-166.18 Error: operator and operand don't agree [tycon mismatch]

  • perator domain: (int * int) * (int * int)
  • perand: int * int

in expression: earlier noon

  • earlier (noon, talk);

val it = false : bool

slide-23
SLIDE 23

Lists

  • val x1 = [7,9,13];

val x1 = [7,9,13] : int list

  • val x2 = 7:: 9 :: 13 :: [];

val x2 = [7,9,13] : int list

  • val equal = ( x1 = x2);

val equal = true : bool

  • val ss = ["Dear ", title, "", name, ", You have won $$$!"];

val ss = ["Dear ","Mr","","Tambourine Man",", You have won $$$!"] : string list

  • val junkmail2 = String.concat ss;

val junkmail2 = "Dear MrTambourine Man, You have won $$$!" : string

slide-24
SLIDE 24

Func%ons on lists

  • fun len [] = 0

= | len (x::xr) = 1 + len xr; val len = fn : ''a list -> int

  • val x2len = len x2;

val x2len = 3 : int

  • val sslen = len ss;

val sslen = 5 : int

  • val x3 = [47,11];

val x3 = [47,11] : int list

  • val x1x3 = x1@x3;

val x1x3 = [7,9,13,47,11] : int list

slide-25
SLIDE 25

Func%ons on lists

  • List.hd [1,2,3];

val it = 1 : int

  • List.tl [1,2,3];

val it = [2,3] : int list

  • val z = ListPair.zip ([1,2,3], ["a", "b", "c"]);

val z = [(1,"a"),(2,"b"),(3,"c")] : (int * string) list

  • ListPair.unzip z;

val it = ([1,2,3],["a","b","c"]) : int list * string list

slide-26
SLIDE 26

Records and labels

  • val x = { name = "Alice", phone = 777 };

val x = {name="Alice",phone=777} : {name:string, phone:int}

  • #name x;

val it = "Alice" : string

  • #phone x;

val it = 777 : int

  • fun show {name, phone} = name ^ " has extension " ^ Int.toString phone;

val show = fn : {name:string, phone:int} -> string

  • show x;

val it = "Alice has extension 777" : string

slide-27
SLIDE 27

Excep&ons

  • exception IllegalHour;

exception IllegalHour

  • fun mins h = if h < 0 orelse h > 23 then raise IllegalHour else h * 60;

val mins = fn : int -> int

  • mins 25;

uncaught exception IllegalHour raised at: stdIn:204.48-204.59

  • (mins 25) handle IllegalHour => ~1;

val it = ~1 : int

slide-28
SLIDE 28

Datatypes

  • datatype person = Student of string

= | Teacher of string * int; datatype person = Student of string | Teacher of string * int

  • val people = [Student "Alice", Teacher ("Bob", 444)];

val people = [Student "Alice",Teacher ("Bob",444)] : person list

  • fun getphone (Teacher (name, phone)) = phone

= | getphone (Student name) = raise Fail "no phone"; val getphone = fn : person -> int

  • getphone (List.hd people);

uncaught exception Fail [Fail: no phone]

slide-29
SLIDE 29

The op'on datatype

  • datatype intopt = SOME of int

= | NONE; datatype intopt = NONE | SOME of int

  • fun getphone (Teacher (name, phone)) = SOME phone

= | getphone (Student name) = NONE; val getphone = fn : person -> intopt

  • getphone (Student "Alice");

val it = NONE : intopt

slide-30
SLIDE 30

Binary trees represented by recursive datatypes

  • datatype intTree = Lf

= | Br of int * intTree * intTree; datatype intTree = Br of int * intTree * intTree | Lf

  • val t1 = Br (34, Br (23, Lf, Lf), Br (54, Lf, Br (78, Lf, Lf)));

val t1 = Br (34,Br (23,Lf,Lf),Br (54,Lf,Br #)) : intTree

  • fun sumTree Lf = 0

= | sumTree (Br (v, t1, t2)) = v + sumTree t1 + sumTree t2; val sumTree = fn : intTree -> int

  • val t1sum = sumTree t1;

val t1sum = 189 : int

slide-31
SLIDE 31

Curried func+ons

  • fun addp ( x, y) = x + y;

val addp = fn : int * int -> int

  • fun addc x y = x + y;

val addc = fn : int -> int -> int

  • val res1 = addp (17,25);

val res1 = 42 : int

  • val res2 = addc 17 25;

val res2 = 42 : int

slide-32
SLIDE 32

Curried func+ons (cont')

  • val addSeventeen = addc 17;

val addSeventeen = fn : int -> int

  • val res3 = addSeventeen 25;

val res3 = 42 : int

  • val res4 = addSeventeen 100;

val res4 = 117 : int

slide-33
SLIDE 33

Summary

  • SML is func,onal and strongly typed
  • Basic usage: a ReadEvalPrintLoop ("REPL")
  • Allows in-session defini,ons
slide-34
SLIDE 34

Summary of examples

  • pragrama'c op'ons, rlwrap
  • expressions, defini'ons, types, func'ons, errors
  • recursion, mutual recursion
  • pa8ern matching, tuples, lists, records, labels
  • excep'ons
  • datatypes
  • currying