cse321, programming languages and compilers 1 6/21/2015 standard ml in this course we will use an...

Post on 20-Dec-2015

215 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Cse321, Programming Languages and Compilers

104/18/23

Standard ML• In this course we will use an

implementation of the language Standard ML

• Notes by Riccardo Pucella, about programming in ML • http://www.cs.cornell.edu/riccardo/smlnj.html

• The SML/NJ Homepage has lots of useful information: http://www.smlnj.org//

• You can get a version to install on your own machine there.

I will use the version 110.57 of SML. Earlier versions probably will work as well. I don’t foresee any problems with other versions, but if you want to use the identical version that I use in class then this is the one.

Cse321, Programming Languages and Compilers

204/18/23

Characteristics of SML

• Applicative style – input output description of problem.

• First class functions – pass as parameters

– return as value of a function

– store in data-structures

• Less Importantly:– Automatic memory management (G.C. no new or malloc)

– Use of a strong type system which uses type inference, i.e. no declarations but still strongly typed.

Cse321, Programming Languages and Compilers

304/18/23

Syntactic Elements

• Identifiers start with a letter followed by digits or other letters or primes or underscores.– Valid Examples: a a3 a’b aF

– Invalid Examples: 12A

• Identifiers can also be constructed with a sequence of operators like: !@#$%^&*+~

• Reserved words include– fun val datatype if then else– if of let in end type

Cse321, Programming Languages and Compilers

404/18/23

Interacting

• The normal style for interaction is to start SML, and then type definitions into the window.

• Types of commands– 4 + 5;– val x = 34;– fun f x = x + 1;

• Here are two commands you might find useful.

val pwd = OS.FileSys.getDir;val cd = OS.FileSys.chDir;

• To load a file that has a sml program type

Use “file.sml”;

Cse321, Programming Languages and Compilers

504/18/23

The SML Read-Typecheck-Eval-Print Loop

Standard ML of New Jersey v110.57 [built: Mon Nov 21 21:46:28 2005]-- 3+5;val it = 8 : int-- print "Hi there\n";Hi thereval it = () : unit-- val x = 22;val x = 22 : int-- x+ 5;val it = 27 : int--val pwd = OS.FileSys.getDir;-val pwd = fn : unit -> string

- val cd = OS.FileSys.chDir;val cd = fn : string -> unit-

Note the semicolon when you’re ready to evaluate.

Otherwise commands can spread across several

lines.

Cse321, Programming Languages and Compilers

604/18/23

Evaluation vs. Declaration evaluation- 5;val it = 5 : int- 3+4;val it = 7 : int

declaration- val it = 7 : int- val tim = 5 : int

evaluation- tim + 7;val it = 12 : int

declaration- fun plusone x = x + 1;val plusone = fn : int -> int

Cse321, Programming Languages and Compilers

704/18/23

Bindings and environments, and scope:val x = 12;fun f x = x + 2;fun g y = x + 2;

• fun bindings are just like val bindings

val f = (fn x => x + 2);

• But NOT RECURSIVE PROGRAMS! why?

fun plus x y = if x = 0 then y else 1 + (plus (x-1) y); val rec plus = fn x => fn y => if x = 0 then y else 1 + (plus (x-1) y);

Cse321, Programming Languages and Compilers

804/18/23

Functions• Functions are usually defined in Files and

loaded into to SML. Example:– use “lect01.sml”

• Functions on numbers– Type of numbers: Int and Real

– Conversion functions: floor, ceiling, trunc, round

• Functions on Booleans– Relational operators

< > <= >= == !=

– Combinators

andalso orelse

• Examples- 5 > 7

false

- 1==4

false

Cse321, Programming Languages and Compilers

904/18/23

Finding type of functions- length

val it = fn : 'a list -> int

-

- op @;

val it = fn : 'a list * 'a list -> 'a list

-

- rev;

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

-

- op +;

val it = fn : int * int -> int

Cse321, Programming Languages and Compilers

1004/18/23

Functions• Defined by writing equations (sometimes more than

1)• By Declaration: fun plusone x = x+1;

• By Lambda expression: fn x => x + 1– These are anonymous functions, and are probably new to you. Don’t let

them scare you.

• Application by juxtaposition (no parenthesis needed)• plusone 8 • (fn x => x + 1) 8

• Functions of more than 1 argument:• tuples• currying

Cse321, Programming Languages and Compilers

1104/18/23

Multi Argument functions: Tuples

• fun evenprod (x,y) = even(x * y);

• Conditional Expressions: If

• fun minpair (x,y) = if x < y then x else y;

Cse321, Programming Languages and Compilers

1204/18/23

Multi Argument functions: By Currying

fun f a b c = a + b + c + 1;

• has type

val f = fn : int -> int -> int -> int

• READ AS: int -> (int -> (int -> int))

• Be sure you understand the difference between the two styles.

• fun evenprod (x,y) = even(x * y);– (int * int) -> bool

• fun evenprod’ x y = even(x * y);– int -> int -> bool

Cse321, Programming Languages and Compilers

1304/18/23

Pattern Matching Definitions:

fun and true false = false

| and true true = true

| and false false = false

| and false true = false;

• (ORDER MATTERS)

• Variables in Patterns:

fun and true true = true

| and x y = false

Note that “and” has more than

1 equation.

Cse321, Programming Languages and Compilers

1404/18/23

Rules for patterns:

• Patterns has only Constructors, (true, false, :: ) variables (x, y, z) , and constants (3, “red”).

• All the patterns (on the left) should have

compatible types

• The cases should be exhaustive

• There should be no ambiguity as to which case applies. (Ordering fixes ambiguity if there is any)

Cse321, Programming Languages and Compilers

1504/18/23

Lists in ML

• Constant lists

• [3,6,8]

• ["red", "yellow", ""]

• []

Cse321, Programming Languages and Compilers

1604/18/23

Construction of lists

• The Empty List

[]

• The "Cons" (op :: ) Constructor

4::[3,7];

val it = [4,3,7] : int list

• Concatenation

[3,4] @ [6,7,8]

val it = [3,4,6,7,8] : int list

Cse321, Programming Languages and Compilers

1704/18/23

Taking Lists Apart? hd [1,2,3]

1

? tl [1,2,3]

[2, 3]

? List.take (2,[1,2,3])

[1,2]

? List.drop (2,[1,2,3])

[3]

Cse321, Programming Languages and Compilers

1804/18/23

Libraries

• There are lots of predefined types and functions in SML when it starts up.

• You can find out about them at:http://www.smlnj.org//basis/pages/top-level-chapter.html

• Many more can be found in the other libraries.– http://www.standardml.org/Basis/manpages.html

• Libraries are encapsulated in Structures which are classified by Signatures (a list of what is in the structure).

Cse321, Programming Languages and Compilers

1904/18/23

Peeking inside a Structure

• To see what is inside a Structure you can open it.

• This is somewhat of a hack, but it is useful.Standard ML of New Jersey v110.57 [built: Mon Nov 21 21:46:28 2005]- signature S = INTEGER;signature INTEGER = sig eqtype int val precision : Int31.int option val minInt : int option val maxInt : int option val ~ : int -> int val + : int * int -> int val - : int * int -> int val * : int * int -> int val div : int * int -> int val mod : int * int -> int val quot : int * int -> int val rem : int * int -> int . . .end

Cse321, Programming Languages and Compilers

2004/18/23

fun lastone x = hd (rev x)fun prefix x = rev (tl (rev x))

In Class Exercise 1• Define prefix and lastone in terms of head tail and reverse.

• First make a file “S01code.sml”• Start sml• Change directory to where the file resides• Load the file ( use “S01code.sml” )• Test the function

Standard ML of New Jersey v110.57 - K;- val cd = OS.FileSys.chDir;val cd = fn : string -> unit- cd "D:/work/sheard/courses/PsuCs321/web/notes";- use "S01code.sml";[opening S01code.sml]val lastone = fn : 'a list -> 'aval prefix = fn : 'a list -> 'a listval it = () : unit- lastone [1,2,3,4];val it = 4 : int

Cse321, Programming Languages and Compilers

2104/18/23

In Class Exercise 2• define map and filter functions

– mymap f [1,2,3] = [f 1, f 2, f 3]– filter even [1,2,3,4,5] = [2,4]

fun mymap f [] = []

| mymap f (x::xs) = (f x)::(mymap f xs);

fun filter p [] = []

| filter p (x::xs) =

if (p x) then x::(filter p xs) else (filter p xs);

• Sample Session

- mymap plusone [2,3,4]

[3, 4, 5]

- myfilter even [1,2,3,4,5,6]

[2, 4, 6]

Cse321, Programming Languages and Compilers

2204/18/23

Case expressions

val ex1 =

case [1,2,3] of

[] => 0

| (1::xs) => if null xs

then 1

else 2

| (x::xs) => 3;

Clauses separated

by “|”

Keyword of

Clauses can span multiple

lines

The semicolon ends the “val ex1 = ” declaration not the

case exp.

Cse321, Programming Languages and Compilers

2304/18/23

Using case in fun definition• The case expression uses patterns

fun length(y) =

case y of

[] => 0

| (x :: xs) => 1 + (length xs)

• In the pattern: (x :: xs)– x, stands for the hd(y)

– xs, stands for the tl(y)

Cse321, Programming Languages and Compilers

2404/18/23

More about patterns• Patterns can be nested• Patterns can have wild-cards

fun double y =

case y of

(a :: (b :: [])) => true

| _ => false

• Special syntax for list Patterns

fun exactlytwo x =

Case x of

[] => false

| [x] => false

| [x,y] => true

| (x:xs) => false;

These features can be used in “fun”

declarations with multiple clauses as

well as in “case” expressions!

Cse321, Programming Languages and Compilers

2504/18/23

Let expressions

• Let expressions allow programmers to make local declaration for both values and functions.

val ex2 =

let val x = 34

fun f x = x - 3

in f x - 4 end;

Multiple declarations allowed, both “val” and

“fun”, no separators necessary

The scope of the new declarations is the

expression between the key words “in” and “end”

Cse321, Programming Languages and Compilers

2604/18/23

Exceptions

exception Error of string;

fun error s = raise (Error s);

fun ex3 b =

(if b then error "true branch"

else "false branch")

handle Error message => message

| other => raise other;

A new exception is declared, it carries a string as error information. Exceptions

can carry any kind of data.

Exceptions can be raised, to short-circuit normal

evaluation.

Main computation

returns a string

Handler also returns a stringA handler, like a “case” has multiple clauses, each can

handle a different kind of error. Note “|” separating clauses.

Keyword handle

Cse321, Programming Languages and Compilers

2704/18/23

Syntax of “case” vs “handle”• “case” is before the computation being

analyzed

case (revonto (g x) 4) of

[] => true

| (x:xs) => false

• “handle” is after the computation that might fail

(compute (g y) (length zs))

handle Error s => g s

| BadLevel n => n+1

| other => raise other

Cse321, Programming Languages and Compilers

2804/18/23

Review

• Case, let, and exceptions are rich constructs in ML.

• Case allows pattern matching without defining a new function.

• Let allows us to introduce local bindings. It allows us to introduce more than 1 binding.

• Exceptions allow non-standard control. The key operations on exceptions are “raise” and “handle”– Handle is like a “case” in that it can have several clause, separated

by “|”, the first that matches “wins”

Cse321, Programming Languages and Compilers

2904/18/23

Introducing new kinds of data• Objects of an inductive type are allocated in

the heap.

• The abstract interface is to use constructor (functions) rather than malloc

• This provides some level of type checking, and abstraction.

• Constructor functions automatically defined. No need to define like constructors in Java

• Two kinds of constructors. Constants like nil ([]), and functions like cons (::).

Cse321, Programming Languages and Compilers

3004/18/23

Constant Constructors• Constant constructors are constant

• Can be allocated once at compile-time.

• Like constant pointers that never change.

• The nil constructor [] for lists is an example.

Cse321, Programming Languages and Compilers

3104/18/23

Constructor Functions• Constructor functions allocate in the heap.• Each constructor may allocate a different

amount of memory• If we had to do this in C we might write

list cons (void * hd, list tl){ list Block = (list) malloc (sizeof (struct listStruct)); Block->Tag = consTag; Block->Data.consData.hd = hd; Block->Data.consData.tl = tl; return (Block);};

• In ML this is done automatically.

Cse321, Programming Languages and Compilers

3204/18/23

Introducing new data and constructors

datatype Tree = Tip | Node of Tree * int * Tree;

val tree1 = Node(Node(Tip,4,Tip) ,7 ,Node(Tip,10,Tip));

Constant constructor, contains no data

Constructor function. Contains 3 fields. The function Node takes a triple with 3

components. The “of” keyword is used for constructor functions

7

4 10

Cse321, Programming Languages and Compilers

3304/18/23

Pattern Matching functions

fun sum Tip = 0

| sum (Node(x,n,y)) = n + sum x + sum y;

• using binary search tree invariant

fun search n Tip = false

| search n (Node(x,m,y)) =

if n=m

then true

else if (n < m) then search n x

else search n y;

Two constructors, two clauses

The bar “|” separates clauses

Cse321, Programming Languages and Compilers

3404/18/23

Searching Trees.fun search n Tip = false

| search n (Node(x,m,y)) =

if n=m then true

else if (n < m) then search n x else search n y;

• val ex4 = search 3 tree1;• search 3 (Node(Node(Tip,4,Tip),7,Node(Tip,10,Tip)))• search 3 (Node (Tip,4,Tip))• search 3 Tip• false

• val ex5 = search 10 tree1;• search 10 (Node(Node(Tip,4,Tip),7,Node(Tip,10,Tip)))• search 10 (Node (Tip,10,Tip))• true

Cse321, Programming Languages and Compilers

3504/18/23

Expressions

datatype Exp

= Const of int

| Add of Exp * Exp

| Mult of Exp * Exp

| Sub of Exp * Exp;

val exp1 = Add(Const 4,Const 3); (* 4+3 *)

val exp2 = Mult(exp1,exp1); (* (4+3)*(4+3) *)

Mult(Add(Const 4,Const 3)

, Add(Const 4,Const 3));

Cse321, Programming Languages and Compilers

3604/18/23

Pattern matching functions

fun ExpValue (Const n) = n

| ExpValue (Add(x,y))

= ExpValue x + ExpValue y

| ExpValue (Mult(x,y))

= ExpValue x * ExpValue y

| ExpValue (Sub(x,y))

= ExpValue x - ExpValue y;

Cse321, Programming Languages and Compilers

3704/18/23

More SML

• In SML we use library functions all the time.– Int.toString– List.exists

• The list library functions are particularly useful.– These library functions often take a function as an argument– List.map : ('a -> 'b) -> 'a list -> 'b list– List.find : ('a -> bool) -> 'a list -> 'a option– List.filter : ('a -> bool) -> 'a list -> 'a list– List.exists : ('a -> bool) -> 'a list -> bool– List.all : ('a -> bool) -> 'a list -> bool– List.foldr : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b

• It is worth studying these functions closely

Cse321, Programming Languages and Compilers

3804/18/23

List.map captures a pattern

• Add one to every element of a list– fun addone [] = []– | addone (x::xs) = (x + 1) :: addone xs

addone [2,3,4] val it = [3,4,5] : int list

• Turn a list of ints into a list of strings– fun stringy [] = []– | stringy (x::xs) = (Int.toString x) :: stringy xs

stringy [2,5,9] val it = ["2","5","9"]:string list

• Negate every element of a list– fun negL [] = []– | negL (x::xs) = (not x) :: negL xs

negL [true,3 > 4] val it = [false,true] : bool list

Cse321, Programming Languages and Compilers

3904/18/23

Patternfun addone [] = [] | addone (x::xs) = (x + 1) :: addone xsfun stringy [] = [] | stringy (x::xs) = (Int.toString x) :: stringy xsfun negL [] = [] | negL (x::xs) = (not x) :: negL xs

fun map f [] = [] | map f (x::xs) = (f x) :: (map f xs)

val ex1 = map (fn x => (x+1)) [2,3,4];val ex1 = [3,4,5] : int list

val ex2 = map Int.toString [2,5,7];val ex2 = ["2","5","7"] : string list

val ex3 = map not [true, 3 > 4];val ex3 = [false,true] : bool list

Cse321, Programming Languages and Compilers

4004/18/23

Anonymous functions• Study: (fn x => (x+1))

– It is an anonymous function. A function without a name.– It has one parameter “x”– It adds one to its parameter, and returns the result.

(fn x => (x+1)) 4;val it = 5 : int

• Any non-recursive function can be written anonymously.– (fn x => x = 5)

» Tests if its parameter is equal to 5map (fn x => x=5) [1,4,5,3,5];val it = [false,false,true,false,true] : bool list

– (fn x => fn y => (x,y))» Has two parameters» Returns a pair

– (fn (x,y) => (not y, x+3))» What is the type of this function?

Cse321, Programming Languages and Compilers

4104/18/23

List.find

• Used for searching a list.– List.find : ('a -> bool) -> 'a list -> 'a option

• Uses a function as a parameter to determine if the search is successful.

• E.g. Is there an even element in a list?List.find even [1,3,5];

val it = NONE : int option

List.find even [1,3,4];

val it = SOME 4 : int option

Cse321, Programming Languages and Compilers

4204/18/23

List.find and anonymous functions

List.find (fn x => x = "Tim")

["Tom", "Jane"];

val it = NONE : string option

List.find (fn x => even x andalso x>10)

[2,4,5,12];

val it = SOME 12 : int option

Cse321, Programming Languages and Compilers

4304/18/23

List.filter

Filter keeps some elements, and throws away others.– List.filter : ('a -> bool) -> 'a list -> 'a list

It uses a function (p) as a parameter to decide which elements to keep (p x = true), and which to throw away (p x = false)

val ex6 = List.filter even [1,2,3,4,5,6];

val ex6 = [2,4,6] : int list

Cse321, Programming Languages and Compilers

4404/18/23

List.filter and anonymous functionsval people = [("tim",22),("john",18),("jane",25),("tim",8)];

val ex7 = filter

(fn (nm,age) => nm <> "tim" orelse age>10)

people;

val ex7 =

[("tim",22),("john",18),("jane",25)]

: (string * int) list

Cse321, Programming Languages and Compilers

4504/18/23

List.exists

• “exists” is like “find” in that it searches a list– but rather than the element that completes the search it is only

interested in if such an element exists.– List.exists : ('a -> bool) -> 'a list -> bool

• Uses a function as a parameter to determine if the search is successful.

val ex8 = List.exists even [2,3,5];

val ex8 = true : bool

• Note that even if only 1 element in the list causes the function to be true, exists returns true.

Cse321, Programming Languages and Compilers

4604/18/23

List.all

• List.all tests elements in a list for a property. It returns true only if every element has that property.– List.all : ('a -> bool) -> 'a list -> bool

• Uses a function as a parameter to perform the test.

val ex9 = List.all even [2,4,5];

val ex9 = false : bool

• List.exists and List.all are related functions. They are duals.– not(List.all p xs) = List.exists (fn x => not(p x)) xs

Cse321, Programming Languages and Compilers

4704/18/23

List.foldr captures a pattern

• Add up every element in a list.

fun sum [] = 0

| sum (x::xs) = x + (sum xs);

• Compute the maximum element in a list of natural numbers (Integers >= 0).

fun maximum [] = 0

| maximum (x::xs) = Int.max(x,maximum xs);

• Compute if every element in a list of boolean is true.

fun allTrue [] = true

| allTrue (x::xs) = x andalso (allTrue xs);

Cse321, Programming Languages and Compilers

4804/18/23

Patternfun sum [] = 0

| sum (x::xs) = x + (sum xs);

fun maximum [] = 0

| maximum (x::xs) = Int.max(x,maximum xs);

fun allTrue [] = true

| allTrue (x::xs) = x andalso (allTrue xs);

fun foldr acc base [ ] = base

| foldr acc base (x::xs)

= acc(x,foldr acc base xs);

Cse321, Programming Languages and Compilers

4904/18/23

See the pattern in use.fun sum [] = 0

| sum (x::xs) = x + (sum xs);

fun sum xs = foldr (op +) 0 xs;

fun maximum [] = 0

| maximum (x::xs) = Int.max(x,maximum xs);

fun maximum xs = foldr Int.max 0 xs;

fun allTrue [] = true

| allTrue (x::xs) = x andalso (allTrue xs);

fun allTrue xs =

foldr (fn (a,b) => a andalso b) true xs;

Cse321, Programming Languages and Compilers

5004/18/23

Take another lookWhat does this function do?

fun ok [] = false

| ok xs = not(exists (fn ys => xs=ys) (!old))

andalso

not(exists (fn ys => xs=ys) (!worklist))

Cse321, Programming Languages and Compilers

5104/18/23

The Option Library- open Option;opening Option datatype 'a option = NONE | SOME of 'a exception Option val getOpt : 'a option * 'a -> 'a val isSome : 'a option -> bool val valOf : 'a option -> 'a val filter : ('a -> bool) -> 'a -> 'a option val join : 'a option option -> 'a option val app : ('a -> unit) -> 'a option -> unit val map : ('a -> 'b) -> 'a option -> 'b option val mapPartial : ('a -> 'b option) -> 'a option -> ‘ b option

Cse321, Programming Languages and Compilers

5204/18/23

Interesting functions that use Options• Int.fromString: string -> int option

Int.fromString "234";

val it = SOME 234 : int option

Int.fromString "abc";

val it = NONE : int option

• String.extract: string * int * int option -> stringString.extract("abcde",1,SOME 3);

val it = "bcd" : string

String.extract("abcde",1,NONE);

val it = "bcde" : string

Cse321, Programming Languages and Compilers

5304/18/23

More option functions• List.find: ('a -> bool) -> 'a list -> 'a option

List.find even [1,3,5];

val it = NONE : int option

List.find (fn x => x="tim") ["tom","tim","jane"];

val it = SOME "tim" : string option

• List.getItem: 'a list -> ('a * 'a list) option– List.getItem [1,2,3,4];– val it = SOME (1,[2,3,4])

– List.getItem [];– val it = NONE

Cse321, Programming Languages and Compilers

5404/18/23

Using While Loopsfun ident c cs = let val xs = ref cs val x = ref c val ans = ref [] in while (not(null(!xs)) andalso Char.isAlpha (hd (!xs))) do ( ans := !ans @ [!x] ; x := hd(!xs) ; xs := tl(!xs) ); (Id (String.implode (!ans @ [!x])), !xs)

end

Don’t forget to test for empty list

top related