introduction to ml
Download
Skip this Video
Download Presentation
Introduction to ML

Loading in 2 Seconds...

play fullscreen
1 / 68

Introduction to ML - PowerPoint PPT Presentation


  • 229 Views
  • Uploaded on

Introduction to ML. You will be responsible for learning ML on your own. Today I will cover some basics Read Robert Harper’s notes on “an introduction to ML” See course webpage for pointers and info about how to get the software. Intro to ML. Highlights Functional Language

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Introduction to ML' - arleen


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
introduction to ml
Introduction to ML
  • You will be responsible for learning ML on your own.
  • Today I will cover some basics
  • Read Robert Harper’s notes on “an introduction to ML”
    • See course webpage for pointers and info about how to get the software
intro to ml
Intro to ML
  • Highlights
    • Functional Language
      • Functions are pervasive:
      • First-class values
        • Storable, arguments, results, nested
    • Strongly-typed language
      • Every expression has a type
      • Certain errors cannot occur
      • Polymorphic types provide flexibility
    • Flexible Module System
      • Abstract Types
      • Higher-order modules (functors)
intro to ml1
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
Preliminaries
  • Read – Eval – Print – Loop

- 3 + 2;

preliminaries1
Preliminaries
  • Read – Eval – Print – Loop

- 3 + 2;

> 5: int

preliminaries2
Preliminaries
  • Read – Eval – Print – Loop

- 3 + 2;

> 5: int

- it + 7;

> 12 : int

preliminaries3
Preliminaries
  • Read – Eval – Print – Loop

- 3 + 2;

> 5: int

- it + 7;

> 12 : int

- it – 3;

> 9 : int

- 4 + true;

Type clash in : 3 + true

Looking for a : int Type

I have found a : bool Error

preliminaries4
Preliminaries
  • Read – Eval – Print – Loop

- 3 + 2;

> 5: int

- it + 7;

> 12 : int

- it – 3;

> 9 : int

- 4 + true;

Type clash in : 3 + true

Looking for a : int Type

I have found a : bool Error

- 3 div 0;

Failure : Div - run-time error

basic values
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; “else” clause is always necessary

> 7 : int

- false andalso loop_Forever;

> false : bool and also, or else short-circuit eval

basic values1
Basic Values

Integers

- 3 + 2

> 5 : int

- 3 + (if not true then 5 else 7);

> 10 : int No division between expressions

and statements

Strings

- “Dave” ^ “ “ ^ “Walker”;

> “Dave Walker” : string

- print “foo\n”;

foo

> 3 : int

Reals

- 3.14;

> 3.14 : real

using sml nj
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
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
Compilation Manager

sources.cm

a.sig

b.sml

c.sml

Group is

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
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
An interpreter
  • Interpreters are usually implemented as a series of transformers:

lexing/

parsing

evaluate

print

stream of

characters

abstract

syntax

abstract

value

stream of

characters

an interpreter1
An interpreter

compilers

COS 320

US!

lexing/

parsing

evaluate

print

stream of

characters

abstract

syntax

abstract

value

stream of

characters

a little language ll
A little language (LL)
  • An arithmetic expression e is
    • a boolean value
    • an if statement (if e1 then e2 else e3)
    • the number zero
    • the successor of a number
    • the predecessor of a number
    • a test for zero (isZero e)
ll abstract syntax in ml
LL abstract syntax in ML

datatype term =

Bool of bool

| If of term * term * term

| Zero

| Successor of term

| Predecessor of term

| IsZero of term

-- constructors

are capitalized

-- constructors

can take a single

argument of a

particular type

type of a tuple

another eg: string * char

vertical bar

separates alternatives

ll abstract syntax in ml1
LL abstract syntax in ML

If (Bool true, Zero, Successor (Successor Zero))

represents “if true then 0 else succ(succ 0)”

If

Suc.

Bool

true

Zero

Suc.

Zero

function declarations
Function declarations

function name

function parameter

fun isNumberValue t =

case t of

Zero => true

| Successor t2 => true

| _ => false

default pattern matches anything

what is the type of the parameter t of the function
What is the type of the parameter t? Of the function?

function name

function parameter

fun isNumberValue t =

case t of

Zero => true

| Successor t2 => true

| _ => false

default pattern matches anything

what is the type of the parameter t of the function1
What is the type of the parameter t? Of the function?

fun isNumberValue (t:term) : bool =

case t of

Zero => true

| Successor t2 => true

| _ => false

val isNumberValue : term -> bool

ML does type inference => you need not

annotate functions yourself (but it can be helpful)

a type error
A type error

fun isNumberValue t =

case t of

Zero => 0

| Successor t2 => true

| _ => false

line 22

line 25

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

a type error1
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
A very subtle error

fun isNumberValue t =

case t of

zero => true

| Successor t2 => 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 error1
A very subtle error

fun isNumberValue t =

case t of

zero => true

| Successor t2 => true

| _ => false

The code above type checks. But when

we test it refined the function always returns “true.”

What has gone wrong?

-- zero is not capitalized

-- ML treats it like a variable pattern (matches anything!)

another function
Another function

fun isNumberValue t = ...

fun isValue t =

case t of

Bool _ => true

| t => isNumberValue t

exceptions
Exceptions

exception Error of string

fun debug s : unit = raise (Error s)

exceptions1
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
Evaluator

fun isNumberValue t = ...

fun isValue t = ...

exception NoRule

fun eval1 t =

case t of

Bool _ | Zero => raise NoRule

...

evaluator1
Evaluator

...

fun eval1 t =

case t of

Bool _ | Zero => raise NoRule

| If(Bool b,t2,t3) => (if b then t2 else t3)

| If(t1,t2,t3) => If (eval1 t1,t2,t3)

...

evaluator2
Evaluator

exception NoRule

fun eval1 t =

case t of

Bool _ | Zero => ...

| ...

| Successor t =>

if isValue t then

raise NoRule

else

let val t’ = eval1 t in

Successor t’

end

finishing the evaluator
Finishing the Evaluator

fun eval1 t =

case t of

...

| ...

| Successor t => ...

| Predecessor t => ...

| IsZero t => ...

be sure your

case is

exhaustive

finishing the evaluator1
Finishing the Evaluator

fun eval1 t =

case t of

...

| ...

| Successor t => ...

What if we

forgot a case?

finishing the evaluator2
Finishing the Evaluator

fun eval1 t =

case t of

...

| ...

| Successor t => ...

What if we

forgot a case?

ex.sml:25.2-35.12 Warning: match nonexhaustive

(Bool _ | Zero) => ...

If (Bool b,t2,t3) => ...

If (t1,t2,t3) => ...

Successor t => ...

multi step evaluation
Multi-step evaluation

fun eval1 t = ...

fun eval t =

let

fun loop t = loop (eval1 t)

val message = “Done\n”

in

((loop t) handle

NoRule => print message

| Error s => print s)

end

Be very

careful

with the

syntax of

handle

(use extra

parens)

ml is all about functions
ML is all about functions
  • There are many different ways to define functions!
  • I almost always use “fun f x = ...”
  • When I am only going to use a function once and it is not recursive, I write an anonymous function:
    • (fn x => ...)
anonymous functions
Anonymous functions

binds a variable (n)

to a value (3)

val n = 3

val isNumberValue =

(fn t =>

case t of

zero => true

| Successor t2 => true

| _ => false)

binds a variable

(isNumberValue)

to the anonymous

function value

fn keyword

introduces

anonymous

fun

anonymous functions1
Anonymous functions

a type definition (very convenient)

type ifun = int -> int

val intCompose : ifun * ifun -> ifun = ...

fun add3 x =

intCompose ((fn x => x + 2), (fn y => y + 1)) x

a pair of anonymous functions

anonymous functions2
Anonymous functions

type ifun = int -> int

val intCompose : ifun * ifun -> ifun =

fn (f,g) =>

(fn x => f (g x))

fun add3 x =

intCompose ((fn x => x + 2), (fn y => y + 1)) x

argument is pair of functions

pattern

match

against

arg

result is a function!

another way to write a function
Another way to write a function

fun f x = ........

can be written as:

val f = (fn x => ......)

provided the function is not recursive;

f does not appear in ........

another way to write a function1
Another way to write a function

fun f x = ....

can always be written as:

val rec f = (fn x => ...f can be used here...)

keyword rec declares a recursive function value

yet another way to write a function
Yet another way to write a function

fun isNumberValue Zero = true

| isNumberValue (Successor t2) = true

| isNumberValue (_) = true

This is just an abbreviation for

fun isNumberValue t =

case t of

Zero => true

| Successor t2 => true

| _ => true

yet another way to create a type error
Yet another way to create a type error

fun isNumberValue 0 = true

| isNumberValue (Successor t2) = true

| isNumberValue (_) = true

ex.sml:9.1-11.29 Error: parameter or result constraints of

clauses don\'t agree [literal]

this clause: term -> \'Z

previous clauses: int -> \'Z

in declaration:

isNumberValue =

(fn 0 => true

| Successor t2 => true

| _ => true)

parametric polymorphism
Parametric Polymorphism
  • Functions like compose work on objects of many different types

val compose =

fn f =>

fn g =>

fn x => f (g x)

compose (fn x => x + 1) (fn x => x + 2)

compose not (fn x => x < 17)

parametric polymorphism1
Parametric Polymorphism
  • Functions like compose work on objects of many different types

val compose =

fn f =>

fn g =>

fn x => f (g x)

compose not (fn x => x < 17)

BAD!!

compose (fn x => x < 17) not

parametric polymorphism2
Parametric Polymorphism
  • Functions like compose work on objects of many different types

val compose =

fn f =>

fn g =>

fn x => f (g x)

compose: (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b)

Note: type variables are written with ‘

parametric polymorphism3
Parametric Polymorphism
  • compose not : (‘c -> bool) -> (c’ -> bool)
  • compose not not : bool -> bool

compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b)

not : bool -> bool

parametric polymorphism4
Parametric Polymorphism
  • compose (fn x => x) : ?

compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b)

not : bool -> bool

parametric polymorphism5
Parametric Polymorphism
  • compose (fn x => x) : ?

compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b)

not : bool -> bool

‘d -> ‘d

parametric polymorphism6
Parametric Polymorphism
  • compose (fn x => x) : ?

compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b)

not : bool -> bool

must be

the same

ie:

‘a = ‘d

‘b = ‘d

‘d -> ‘d

parametric polymorphism7
Parametric Polymorphism
  • compose (fn x => x) : ?

compose : (‘d -> ‘d) -> (‘c -> ‘d) -> (‘c -> ‘d)

not : bool -> bool

must be

the same

ie:

‘a = ‘d

‘b = ‘d

‘d -> ‘d

parametric polymorphism8
Parametric Polymorphism
  • compose (fn x => x) : ?

compose : (‘d -> ‘d) -> (‘c -> ‘d) -> (‘c -> ‘d)

not : bool -> bool

‘d -> ‘d

(‘c -> ‘d) -> (‘c -> ‘d)

lists
Lists
  • Lists:

nil : ‘a list

:: : ‘a * ‘a list -> ‘a list

  • 3 :: 4 :: 5 :: nil : int list
  • (fn x => x) :: nil : (‘a -> ‘a) list
list processing
List Processing
  • Functions over lists are usually defined by case analysis (induction) over the structure of a list
  • Hint: often, the structure of a function is

guided by the type of the argument (recall eval)

fun length l =

case l of

nil => 0

l x :: l => 1 + (length l)

list processing1
List Processing

fun map f l =

case l of

nil => []

l x :: l => (f x) :: (map f l)

an incredibly useful function:

- map (fn x => x+1) [1,2,3];

> val it = [2,3,4] ; int list

list processing2
List Processing

fun fold f a l =

case l of

nil => a

l x :: l => f (fold f a l) x

another incredibly useful function

what does it do?

use it to write map.

ml modules
ML Modules
  • Signatures
    • Interfaces
  • Structures
    • Implementations
  • Functors
    • Parameterized structures
    • Functions from structures to structures
structures
Structures
  • structure Queue =

struct

type ‘a queue = ‘a list * ‘a list

exception Empty

val empty = (nil, nil)

fun insert (x, q) = …

fun remove q = …

end

structures1
Structures

structure Queue =

struct

type ‘a queue = ‘a list * ‘a list

exception Empty

...

end

fun insert2 q x y =

Queue.insert (y, Queue.insert (q, x))

structures2
Structures

structure Queue =

struct

...

end

structure Q = Queue

fun insert2 q x y =

Q.insert (y, Q.insert (q, x))

convenient

abbreviation

structures3
Structures

structure Queue =

struct

...

end

open Queue

fun insert2 q x y =

insert (y, insert (q, x))

for lazy

programmers

-- not encouraged!

structures4
Structures

structure Queue =

struct

type ‘a queue = ‘a list * ‘a list

...

end

fun insert2 (q1,q2) x y : ‘a queue =

(x::y::q1,q2)

by default,

all components

of the structure

may be used

-- we know the

type ‘a queue

signatures
Signatures

abstract type

-- we don’t know the

type ‘a queue

signature QUEUE =

sig

type ‘a queue

exception Empty

val empty : ‘a queue

val insert : ‘a * ‘a queue -> ‘a queue

val remove : ‘a queue -> ‘a * ‘a queue

end

information hiding
Information hiding

signature QUEUE =

sig

type ‘a queue

...

end

structure Queue :> QUEUE =

struct

type ‘a queue = ‘a list * ‘a list

val empty = (nil, nil)

end

does not

type check

fun insert2 (q1,q2) x y : ‘a queue =

(x::y::q1,q2)

signature ascription
Signature Ascription
  • Opaque ascription
    • Provides abstract types

structure Queue :> QUEUE = …

  • Transparent ascription
    • A special case of opaque ascription
    • Hides fields but does not make types abstract

structure Queue_E : QUEUE = …

  • SEE Harper, chapters 18-22 for more on modules
other things
Other things
  • functors (functions from structures to structures)
  • references (mutable data structures)
    • ref e; !e; e1 := e2
  • while loops, for loops
  • arrays
  • (* comments (* can be *) nested *)
  • a bunch of other stuff...
last things
Last Things
  • Learning to program in SML can be tricky at first
  • But once you get used to it, you will never want to go back to imperative languages
  • Check out the reference materials listed on the course homepage
ad