Standard ML Mini-tutorial (in particular SML/NJ)
Programming Languages CS442 David Toman
School of Computer Science University of Waterloo
David Toman (University of Waterloo)
Standard ML
1 / 21
Introduction
SML (Standard Meta Language)
originally part of the LCF project (Gordon et al.) based formal semantics (Milner et al.) based on advanced module system SML/NJ (Bell Labs) Moscow ML
Industrial strength PL (SML90, SML97)
SML Basis Library (all you ever wanted) Quality compilers:
David Toman (University of Waterloo)
Standard ML
2 / 21
Features
Everything is built from expressions
functions are rst class citizens pretty much extension of our simple functional PL
Support for structured values: lists, trees, . . . Strong type system
let-polymorphic functions type inference
Powerful module system
signatures, implementations, ADTs,. . .
Imperative features (e.g., I/O)
David Toman (University of Waterloo)
Standard ML
3 / 21
Tutorial Goals
1 2
Make link from our functional language to SML Provide enough SML syntax and examples for A2
How to use SML/NJ interactive environment How to write simple functional programs How to dene new data types How to understand compiler errors Where to nd more information
Show type inference in action (so we understand whats coming)
David Toman (University of Waterloo)
Standard ML
4 / 21
Getting started
Starting it up: sml in UNIX (click somewhere in W/XP)
Example
Standard ML of New Jersey, Version 110.0.7 [CM&CMB] Notation and simple examples:
great support in Emacs
Example
- 1; val it = 1 : int - 2+3; val it = 5 : int I type in blue, SML replies in black
David Toman (University of Waterloo) Standard ML 5 / 21
Simple Declarations
We can create declarations (bindings):
Example
- val x = 2*3+4; val x = 10 : int now x stands for 10
and use them:
Example
- val y = x*2; val y = 20 : int analogue of an environment {x = 10, y = 20}
David Toman (University of Waterloo)
Standard ML
6 / 21
Types of Simple Things
there is more than integers:
Example
- 1.0; val it = 1.0 : real - "abc"; val it = "abc" : string - #"a"; val it = #"a" : char
and these types come with additional operations
Example
- "abc"^"def"; val it = "abcdef" : string
David Toman (University of Waterloo)
Standard ML
7 / 21
Functions
-abstractions:
Example
- fn x => x+1; val it = fn : int -> int
functions can be declared and used:
Example
- val twice = (fn x => 2*x); val twice = fn : int -> int - twice y; val it = 40 : int what if we wanted a recursive function?
David Toman (University of Waterloo) Standard ML 8 / 21
Functions
there is a rec construction (which almost nobody uses) functions are dened explicitly using a fun declaration:
Example
- fun fac n = if (n=0) then 1 else n*(fac (n-1)); val fac = fn : int -> int
but more commonly using match patterns:
Example
- fun fac 0 = 1 = | fac n = n*(fac (n-1)); val fac = fn : int -> int - fac 10; val it = 3628800 : int match patterns better cover all possible parameter values!
David Toman (University of Waterloo) Standard ML 9 / 21
Complex Types: Tuples
Pairs and k -tuples:
Example
- val pair = (1,"abc"); val pair = (1,"abc") : int * string - val triple = (1,true,1.0); val triple = (1,true,1.0) : int * bool * real
and projections:
Example
- #3(triple); val it = 1.0 : real - val (x,y) = pair; val x = 1 : int val y = "abc" : string
David Toman (University of Waterloo) Standard ML 10 / 21
Complex Types: Lists
List construction
Example
- 1::nil; val it = [1] : int list - val l = [1,2,3]; val l = [1,2,3] : int list
and operations:
Example
- hd l; val it = 1 : int - tl l; val it = [2,3] : int list - tl(tl(tl l)); val it = [] : int list
David Toman (University of Waterloo) Standard ML 11 / 21
Functions on Lists
Function that appends two (arbitrary) lists:
Example
- fun app nil l = l = | app (h::t) l = h::(app t l); val app = fn : a list -> a list -> a list what are the a types? polymorphic type variables
And what does it do:
Example
- app [1,2,3] [4,5,6]; val it = [1,2,3,4,5,6] : int list - app ["a","b"] ["c"]; val it = ["a","b","c"] : string list the arguments must be lists of the same type
David Toman (University of Waterloo) Standard ML 12 / 21
Polymorphic Functions
polymorphic = universal functions (for all types)
Example
- fun mklist x = [x]; val mklist = fn : a -> a list - mklist 1; val it = [1] : int list - mklist (mklist 1); val it = [[1]] : int list list - fn x=> mklist (mklist x); val it = fn : a -> a list list - it "a"; val it = [["a"]] : string list list
David Toman (University of Waterloo)
Standard ML
13 / 21
Higher-order Functions
functions as parameters? the map function:
Example
- fun map f [] = [] = | map f (h::t) = (f h)::(map f t); val map = fn : (a -> b) -> a list -> b list
what does it do?
Example
- map (fn x=> x+1) [1,2,3]; val it = [2,3,4] : int list - map (fn x=> [x]) [1,2,3]; val it = [[1],[2],[3]] : int list list - fn l=>map (fn x=> [x]) l; val it = fn : a list -> a list list
David Toman (University of Waterloo) Standard ML 14 / 21
Datatypes
what if we need more than pairs and lists SML provides datatypes (disjoint unions)
Example (Binary Trees)
- datatype a bintr = datatype a bintr = | = LEAF of a | NODE of a bintr*a bintr; LEAF of a NODE of a bintr * a bintr this works for any number of variants
creating a new tree:
Example
- val tree = NODE (NODE(LEAF 1,LEAF 4),LEAF 7); val tree = NODE(NODE(LEAF 1,LEAF 4),LEAF 7) : int bint
David Toman (University of Waterloo) Standard ML 15 / 21
Datatypes (cont.)
functions on trees: use pattern matching again
Example
- fun addl (LEAF n) = n = | addl (NODE(n1,n2)) = (addl n1)+(addl n2); val addl = fn : int bintr -> int - addl tree; val it = 12 : int
we can do better (a polymorphic function):
Example
- fun mapt f g (LEAF l) = (g l) = | mapt f g (NODE(n1,n2)) = = f (mapt f g n1) (mapt f g n2); val mapt = fn : (a -> a -> a) -> (b -> a) -> b bintr -> a
David Toman (University of Waterloo) Standard ML 16 / 21
Local Declarations
local declarations let <decl> in <exp> end
Example
- fun addl (LEAF l) = l = | addl (NODE(n1,n2)) = = let val a1 = (addl n1) = val a2 = (addl n2) = in = a1+a2 = end; val addl = fn : int bintr -> int
local (helper) function declarations:
local <helper-fun-decl> in <main-fun-decl> end
David Toman (University of Waterloo)
Standard ML
17 / 21
Exceptions
what does hd nil do? 1 div 0?
Example
- 1 div 0; uncaught exception divide by zero raised at: <file stdIn>
we can have our own exceptions:
Example
- exception myex of int; exception myex of int - fun cf n = if (n<0) then raise (myex ~1) = else (fac n); val cf = fn : int -> int - cf ~1 handle (myex n) => n; val it = ~1 : int
David Toman (University of Waterloo) Standard ML 18 / 21
Modules
Structures (essentially named declarations)
structure IntLT = struct type t = int val lt = (op <) end
val eq = (op =)
access to components: IntLT.lt
Signatures (essentially types of declarations)
signature ORDERED = sig type t val lt : t * t -> bool end
val eq : t * t -> bool
Ascription (match of signature and structure)
structure strid : sigexp = strexp (transparent) structure strid :> sigexp = strexp (opaque)
Standard ML 19 / 21
Parametrized module: functors
David Toman (University of Waterloo)
Compiler Error Messages
incorrect base syntax: - let x=1 in x end; stdIn:4.1-4.7 Error: syntax error: deleting LET ID EQUAL stdIn:4.9 Error: syntax error found at IN undeclared identiers: - foo; stdIn:4.1 Error: unbound variable or constructor: foo type problems: - [1,"foo"]; stdIn:4.1-4.10 Error: operator and operand dont agree operator domain: int * int list operand: int * string list in expression: 1 :: "foo" :: nil
David Toman (University of Waterloo)
Standard ML
20 / 21
Summary and Quick Hints
This should get you started with SML (go and try) Several helpful hints: 1 reading program text from le: use "file.sml"; 2 print a string on stdout: print "string-here\n"; 3 x-up defaults for printing: Compiler.Control.Print.printDepth := 50; Compiler.Control.Print.printLength:= 1000; Compiler.Control.Print.stringDepth:= 200; 4 these GC #6.42.43.47.144.8522: (0 ms) are harmless unless theyre coming and coming (innite loop) 5 more help: http://www.smlnj.org//index.html more complete tutorial: http://www.cs.cmu.edu/People/rwh/introsml/
David Toman (University of Waterloo) Standard ML 21 / 21