some related slides

advertisement
Introduction to ML – Part 1
Frances Spalding
Assignment 1



http://www.cs.princeton.edu/courses/ar
chive/fall05/cos441/assignments/a1.ht
m
Due next Monday (Oct 3rd)
Make sure you’ve signed up for the
mailing list
Standard ML


Standard ML is a domain-specific
language for building compilers
Support for




Complex data structures (abstract syntax,
compiler intermediate forms)
Memory management like Java
Large projects with many modules
Advanced type system for error detection
Introduction to ML




You will be responsible for learning ML on
your own.
Today I will cover some basics
Aquinas will do a second class on ML on
Thursday
Resources:



Jeffrey Ullman “Elements of ML Programming”
Robert Harper’s “an introduction to ML”
See course webpage for pointers and info about how to
get the software
Intro to ML

Highlights

Data Structures for compilers



Strongly-typed language




Data type definitions
Pattern matching
Every expression has a type
Certain errors cannot occur
Polymorphic types provide flexibility
Flexible Module System


Abstract Types
Higher-order modules (functors)
Intro to ML

Interactive Language




Type in expressions
Evaluate and print type and result
Compiler as well
High-level programming features




Data types
Pattern matching
Exceptions
Mutable data discouraged
Preliminaries

Read – Eval – Print – Loop
- 3 + 2;
Preliminaries

Read – Eval – Print – Loop
- 3 + 2;
> 5: int
Preliminaries

Read – Eval – Print – Loop
- 3 + 2;
> 5: int
- it + 7;
> 12 : int
Preliminaries

Read – Eval – Print – Loop
- 3 + 2;
> 5: int
- it + 7;
> 12 : int
- it – 3;
> 9 : int
- 4 + true;
stdIn:17.1-17.9 Error: operator and operand don't
agree [literal]
operator domain: int * int
operand:
int * bool
in expression:
4 + true
Preliminaries

Read – Eval – Print – Loop
- 3 div 0;
Failure : Div
- run-time error
Basic Values
- ();
> () : unit
=> like “void” in C (sort of)
=> the uninteresting value/type
- true;
> true : bool
- false;
> false : bool
- if it then 3+2 else 7;
> 7 : int
- false andalso loop_Forever;
> false : bool
“else” clause is always necessary
and also, or else short-circuit eval
Basic Values
Integers
-3+2
> 5 : int
- 3 + (if not true then 5 else 7);
> 10 : int
Strings
- “Dave” ^ “ “ ^ “Walker”;
> “Dave Walker” : string
- print “foo\n”;
foo
> 3 : int
Reals
- 3.14;
> 3.14 : real
No division between expressions
and statements
Using SML/NJ
Interactive mode is a good way to start
learning and to debug programs, but…
 Type in a series of declarations into a
“.sml” file
- use “foo.sml”
[opening foo.sml]
list of declarations
…
with their types

Larger Projects


SML has its own built in interactive
“make”
Pros:



It automatically does the dependency
analysis for you
No crazy makefile syntax to learn
Cons:

May be more difficult to interact with other
languages or tools
Compilation Manager
sources.cm
Group is
a.sig
b.sml
c.sml
a.sig
b.sml
c.sml
% sml
- OS.FileSys.chDir “~/courses/510/a2”;
- CM.make();
looks for “sources.cm”, analyzes dependencies
[compiling…]
compiles files in group
[wrote…]
saves binaries in ./CM/
- CM.make’ “myproj/”();
specify directory
What is next?

ML has a rich set of structured values







Tuples: (17, true, “stuff”)
Records: {name = “Dave”, ssn = 332177}
Lists: 3::4::5::nil or [3,4]@[5]
Datatypes
Functions
And more!
Rather than list all the details, we will
write a couple of programs
An interpreter

Interpreters are usually implemented as
a series of transformers:
lexing/
parsing
stream of
characters
evaluate
abstract
syntax
print
abstract
value
stream of
characters
A little language (LL)

An arithmetic expression e is





a boolean value
an if statement (if e1 then e2 else e3)
an integer
an add operation
a test for zero (isZero e)
LL abstract syntax in ML
datatype term =
Bool of bool
| If of term * term * term
| Num of int
| Add of term * term
| IsZero of term
vertical bar
separates alternatives
-- constructors
are capitalized
-- constructors
can take a single
argument of a
particular type
type of a tuple
another eg: string * char
LL abstract syntax in ML
Add
Add (Num 2, Num 3)
Num
represents the expression “2 + 3”
2
Num
3
LL abstract syntax in ML
If
If (Bool true,
Num 0,
Add (Num 2, Num 3))
represents
Bool Num
true
Add
Num Num
0
“if true then 0 else 2 + 3”
2
3
Function declarations
function name
fun isValue t =
case t of
Num n => true
| Bool b => true
| _ => false
default pattern matches anything
function parameter
What is the type of the
parameter t? Of the function?
function name
fun isValue t =
case t of
Num n => true
| Bool b => true
| _ => false
default pattern matches anything
function parameter
What is the type of the
parameter t? Of the function?
fun isValue (t:term) : bool =
case t of
Num n => true
| Bool b => true
| _ => false
val isValue : term -> bool
ML does type inference => you need not
annotate functions yourself (but it can be helpful)
A type error
fun isValue t =
case t of
Num _ => true
| _ => false
ex.sml:22.3-24.15 Error: types of rules don't agree [literal]
earlier rule(s): term -> int
this rule: term -> bool
in rule:
_ => false
A type error
Actually, ML will give you several errors in a row:
ex.sml:22.3-25.15 Error: types of rules don't agree [literal]
earlier rule(s): term -> int
this rule: term -> bool
in rule:
Successor t2 => true
ex.sml:22.3-25.15 Error: types of rules don't agree [literal]
earlier rule(s): term -> int
this rule: term -> bool
in rule:
_ => false
A very subtle error
fun isValue t =
case t of
num => true
| _ => 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 isValue t =
case t of
Num 0 => 1
| Add(Num t1,Num t2) => t1 + t2
| _ => 0
The code above type checks. But when
we test it refined the function always returns “true.”
What has gone wrong?
-- num is not capitalized (and has no argument)
-- ML treats it like a variable pattern (matches anything!)
Exceptions
exception Error of string
fun debug s : unit = raise (Error s)
Exceptions
exception Error of string
fun debug s : unit = raise (Error s)
in SML interpreter:
- debug "hello";
uncaught exception Error
raised at: ex.sml:15.28-15.35
Evaluator
fun isValue t = ...
exception NoRule
fun eval t =
case t of
Bool _ | Num _ => t
| ...
Evaluator
...
let statement
fun eval t =
for remembering
case t of
temporary
Bool _ | Num _ => t
results
| If(t1,t2,t3) =>
let val v = eval t1 in
case v of
Bool b => if b then (eval t2) else (eval t3)
| _ => raise NoRule
end
Evaluator
exception NoRule
fun eval1 t =
case t of
Bool _ | Num _ => ...
| ...
| Add (t1,t2) =>
case (eval v1, eval v2) of
(Num n1, Num n2) => Num (n1 + n2)
| (_,_) => raise NoRule
Finishing the Evaluator
fun eval1 t =
case t of
...
| ...
| Add (t1,t2) => ...
| IsZero t => ...
be sure your
case is
exhaustive
Finishing the Evaluator
fun eval1 t =
case t of
...
| ...
| Add (t1,t2) => ...
What if we
forgot a case?
Finishing the Evaluator
fun eval1 t =
case t of
...
| ...
| Add (t1,t2) => ...
What if we
forgot a case?
ex.sml:25.2-35.12 Warning: match nonexhaustive
(Bool _ | Zero) => ...
If (t1,t2,t3) => ...
Add (t1,t2) => ...
Download