56
Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Embed Size (px)

Citation preview

Page 1: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Introduction to ML

CS 331

Principles of Programming Languages

revised Spring 2003

Page 2: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Features of ML

• A pure functional language– serious programs can be written without using

variables

• Widely accepted– reasonable performance (claimed)– can be compiled– syntax not as arcane (or as simple) as LISP

Page 3: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

In these slides,

• We use Standard ML of New Jersey• Runs on PCs, Linux, and other flavors of UNIX• Much of this material is based on Ullman’s book,

Elements of ML Programming

• See the SML documentation at http://www.smlnj.org

Page 4: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Running SML on linix.gl

• The SML processor is available at/afs/umbc.edu/users/n/i/nicholas/pub/331/smlnj.linux/binor equivalently~nicholas/../pub/331/smlnj.linux/bin

• Add this directory to your path, and do a rehash• Then invoke sml from a shell prompt with the

command sml• Use control d to exit interpreter

Page 5: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Hello, world in SML

Standard ML of New Jersey,- print("Hello world\n");Hello worldval it = () : unit-

Page 6: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Arithmetic in ML

• Copy and paste the following text into a Standard ML window

2+2; (* note semicolon at end*)3*4;4/3; (* an error! *)6 div 2; (* integer division *)7 div 3;

Page 7: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Declaring Constants

• Constants are not exactly the same as variables– they can be redefined, but existing uses of that

constant (e.g. in function definitions) aren’t affected by such redefinition

val freezingFahr = 32;

Page 8: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Ints and Reals

Int.abs ~3;Int.sign ~3;Int.max (4, 7);Int.min (~2, 2);real(freezingFahr); Math.sqrt real(2);Math.sqrt(real(2));Math.sqrt(real 3);

• Note ~ is unary minus• min and max take just

two input arguments, but that can be fixed!

• The real operator converts to real

• Parens can sometimes be omitted, but I don’t recommend it

Page 9: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

- Int.abs ~3;val it = 3 : int- Int.sign ~3;val it = ~1 : int- Int.max (4, 7);val it = 7 : int- Int.min (~2, 2);val it = ~2 : int- Math.sqrt real(2);stdIn:57.1-57.18 Error: operator and operand don't agree [tycon mismatch] operator domain: real operand: int -> real in expression: Math.sqrt real- Math.sqrt(real(2));val it = 1.41421356237 : real- Math.sqrt(real 3);val it = 1.73205080757 : real

Page 10: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Strings

• Delimited by double quotes

• the caret mark ^ is used for string concatenation, e.g. “house”^”cat”

• \n is used for newline, as in C and C++

Page 11: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Comparison Operators

• The usual <, >, <=, >= and <> are available

• For reals, = and <> are not available– For reals a and b, a <= b andalso a>= b is an

equality test

• The connectors “andalso” and “orelse” are logical operators with short-circuit evaluation

Page 12: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

If Then Else

• If Then Else is an expression, not a control structure

• Example, if quotient, dividend and divisor are reals, we might haveval quotient = if divisor > 0 then dividend/divisor else 0

Page 13: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Tuples

• Tuples are data items drawn from a Cartesian product type. Example:type fraction = int * int;val foo: fraction = (44,100);#1(foo); (* returns 44 *)#2(foo); (* returns 100 *)

• Tuples are of fixed size, e.g. 2 in this example

Page 14: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Lists in ML

• Objects in a list must be of the same type– [1,2,3];– [“dog”, “cat”, “moose”];

• The empty list is written [] or nil

Page 15: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Making Lists

• The @ operator is used to concatenate two lists of the same type

• The :: operator makes a new list in which its first operand is the new first element of a list which is otherwise like the second operand.

• The functions hd and tl give the first element of the list, and the rest of the list, respectively

Page 16: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

List Operations

- val list1 = [1,2,3];val list1 = [1,2,3] : int list- val list2 = [3,4,5];val list2 = [3,4,5] : int list- list1@list2;val it = [1,2,3,3,4,5] : int list- hd list1;val it = 1 : int- tl list2;val it = [4,5] : int list

Page 17: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

More List Operations

- val list1 = [1,2,3];val list1 = [1,2,3] : int list- val list2 = [3,4,5];val list2 = [3,4,5] : int list- 4::list1;val it = [4,1,2,3] : int list- val list3 = list1::list2;an error!- val list3=list1@list2;val list3 = [1,2,3,3,4,5] : int list- length(list3);val length(list3) = 6

Page 18: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Strings and Lists

• The explode function converts a string into a list of characters

• The implode function converts a list of characters into a string

• Examples: - explode("foo");val it = [#"f",#"o",#"o"] : char list- implode [#"c",#"a",#"t"];val it = "cat" : string-

Page 19: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Heads and Tails

• The cons operator :: takes an element and prepends it to a list of that same type.

• For example, the expression 1::[2,3] results in the list [1,2,3]

• What’s the value of [1,2]::[ [3,4], [5,6]] ?

• What’s the value of x::[], for any atom x?

Page 20: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Declaring Functions

• A function takes an input value and returns an output value

• ML will figure out the types

Page 21: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Notes

• ML is picky about not mixing types, such as int and real, in expressions

• The value of “it” is always the last value computed

• Function arguments don’t always need parentheses, but it doesn’t hurt to use them

Page 22: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Types of arguments and results

• ML figures out the input and/or output types for simple expressions, constant declarations, and function declarations

• If the default isn’t what you want, you can specify the input and output types, e.g.fun divBy2 x:int = x div 2 : int;fun divideBy2 (y : real) = y / 2.0;divBy2 (5);divideBy2 (5.0);

Page 23: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Two similar divide functions

- fun divBy2 x:int = x div 2 : int;val divBy2 = fn : int -> int

- fun divideBy2 (y : real) = y / 2.0;val divideBy2 = fn : real -> real

- divBy2 (5);val it = 2 : int

- divideBy2 (5.0);val it = 2.5 : real-

Page 24: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Functions and Patterns

• Recall that min and max take just two arguments

• However, using the fact that, for example,– min(a, b, c) = min(a, min(b, c))

Page 25: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Generalizing Min

• An example of ML pattern matching– the cons notation x::xs is both a binary

constructor and a pattern– cases aren’t supposed to overlap

• Note that lists of any size are supported– but the elements are expected to be integers– checking that the rest of the list is non-empty is

critical - but why?

Page 26: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

(* Sample ML program - MinList *)

(* Takes a list of integers as input, and returns a list with at most one element, i.e. the smallest element in the list *)

fun MinList([]) = [] |

MinList(x::xs) =

if null(xs) then [x]

else [Int.min(x,hd(MinList(xs)))];

MinList([]);

MinList([1,2]);

MinList([315, 41, 59, 265, 35, 897]);

Page 27: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

When we run MinList,…

- use "MinList.sml";

[opening MinList.sml]

val MinList = fn : int list -> int list

val it = [] : int list

val it = [1] : int list

val it = [35] : int list

val it = () : unit

Page 28: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Building trees

• It’s easy to build recursive data types in ML

• Some examples follow

Page 29: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

(* Sample ML program - Abstract Syntax Trees *)

(* Declare the ast datatype *)

datatype ast = empty

| leaf of int

| node of string*ast*ast;

fun traverse(empty) = print "empty tree" |

traverse(leaf(n)) = (print (Int.toString(n)); print " ") |

traverse(node(operator, left, right)) = (

traverse(left);

print operator;

traverse(right));

fun prefix(tree:ast) = (traverse(tree); print "\n");

prefix(empty);

prefix(leaf(4));

prefix(node("*",node("+",leaf(5),leaf(3)),node("-",leaf(10),leaf(4))));

Page 30: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Two ways to count

(* count from i to j *)fun countUp(i:int, j:int) = if i=j then print(" "^Int.toString(j)) else (countUp(i,j-1);print(" "^Int.toString(j)));

(* count from i to j *)fun TcountUp(i:int, j:int) = if i=j then print(" "^Int.toString(j)^"\n") else (print(" "^Int.toString(i));TcountUp(i+1,j));

Page 31: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

What about control structures?

• Well, there aren’t any in the usual (procedural) sense

• If then else, case, and iteration are all accomplished by evaluation of expressions

Page 32: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Iteration vs. Recursion

(* note that F is a functional parameter *)fun loopIt(i:int,n:int,F) = if i = n then F(i)else let val dummy = F(i) val dummy2 = loopIt(i+1,n,F) in dummy2 (* any expression could be used *) end;

Page 33: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

The Print Function

• print(“This string\n”);• print(“2+2 is “^Int.toString(2+2)^”\n”);

• Expressions may be grouped with parentheses, e.g (print(“a”);print(“b”))

• But the grouped expressions may not change the environment, so this is not the same as a block in a procedural language

Page 34: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

More About I/O

• To access functions in the TextIO structure, open TextIO;

• To open a file openIn(“somefile”);• The value returned is of type instream

• endOfStream(file:instream): bool

• inputN(file:instream,n:int):string

• input(file:stream):string (* whole file *)

Page 35: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Matches and Functions

• Example of match expression:val rec reverse = fn

nil => nil|x::xs => reverse(xs) @ [x];

• The rec keyword stands for “recursive”, which is necessary because the binding of reverse as a function name is not yet established

Page 36: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Anonymous Functions

• Functions don’t have to have names, e.g.(fn x => x+1) (3) yields 4

• Such functions can be passed as parameters, e.g. for use in the map or reduce functions, to be discussed later in this chapter.

Page 37: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

If Then Else = Case

• The familiar if E1 then E2 else E3 is equivalent tocase E1 of true => E2 | false => E3

• Example: if x<y then #”a” else #“b”is the same ascase x<y of

true => #”a” |false => #“b” (* note same types *)

Page 38: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Exceptions

• exception Foo and Bar;• raise Foo;• exception Foo of string;

• The handle clause matches exceptions with (hopefully) suitable actions

• Exceptions can be defined in let clauses

Page 39: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Polymorphic Functions

• If you don’t know the type in advance, or if it doesn’t matter,‘a list matches a list of any type

• Example:fun listLen(x: ‘a list) =

if x = nil then 0

else 1+listLen(tl(x));

Page 40: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Higher Order Functions

• Functions may be passed as parameters,e.g.

fun trap(a,b,n,F)= if n <= 0 orelse b-a <= 0.0 then 0.0 else let val delta = (b-a)/real(n) in delta*(F(a)+F(a+delta))/2.0+ trap(a+delta,b,n-1,F) end;

Page 41: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Higher-Order Function map

• The map function map(F,[a1,a2,…,an])

produces the list [F(a1),F(a2),…,F(an)]

• The function may be defined (per Harper’s new ML book) fun map f nil = nil| map f (h::t) = (f h)::(map f t)

Page 42: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Higher-Order Function reduce

• The reduce function reduce(F,[a1,a2,…,an])

produces F(a1,F(a2,F(…,F(an-1, an)…)))

• The reduce function may be implemented as follows (from Ullman)

exception EmptyList;fun reduce (F, nil) = raise EmptyList| reduce (F, [a]) = a | reduce (F, x::xs) = F(x, reduce(F,xs));

Page 43: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

More on reduce

• Harper gives a more general form of reduce fun reduce (unit, opn, nil) = unit | reduce (unit, opn, h::t) = opn(h, reduce (unit, opn, t))

• Example: two ways to sum a list of numbersfun add_up nil = 0| add_up(h::t) = h + add_up t

orfun add_up alist = reduce (0, op +, alist)

• The op keyword allows + to be a parameter

Page 44: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

More on reduce

• To avoid passing unit and opn as parameters that don’t change, again from Harper’s book,fun better_reduce (unit, opn, alist) = let fun red nil = unit

| red (h::t) = opn(h, red t))in red alistend

• We have less overhead by passing only those parameters that change

Page 45: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

More on reduce

• “Staging” helps even more! Again from Harperfun staged_reduce (unit, opn) = let fun red nil = unit

| red (h::t) = opn(h, red t))in redend

• We can use staged_reduce on many lists, e.g.reduce(unit, opn, alist)

is the same as (but slower than)staged_reduce(unit, opn) alist

Page 46: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Higher-Order Function filter

• The filter function takes a predicate P and a list [a1,a2,…,an] and returns the sublist such that P is true for every element of the sublist

• To implement filterfun filter(P, nil) = nil| filter(P, x::xs) =

if P x then x::filter(P,xs)

else filter(P,xs)

Page 47: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

The ML Type System

• Basic types include int, real, string, char, bool, and others

• Tuple types, e.g. int*real*char• Function types, e.g. int->bool• Type constructors list and option

– int list– char option

Page 48: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Creating Names for Types

• type orderpair = int*int

• type finiteSequence = real list;

• and these can be parameterized

Page 49: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Datatypes

• Enumerated types, e.g. datatype berryType = raspberry | blueberry | blackberry;

• So then we can say, for example, val b:berryType = raspberry;

Page 50: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Recursive Datatypes

• Example: binary trees, where the values may be of some type ‘label: datatype ‘label btree = Empty |Node of ‘label * ‘label btree * ‘label btree

• val inBinary: int btree = Node(5,Node(1,Empty,Empty),Empty)

Page 51: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

(* Sample ML program - Abstract Syntax Trees *) (* Assume that terminalType and nonterminalType already known *)(* Declare the ast datatype *)

datatype ast = empty| leaf of terminalType| node of nonterminalType*(ast list);

fun traverse(empty) = print "empty tree" | traverse(leaf(t)) = (printTerminal t; print " ") | traverse(node(nt, []) = printNonterminal(nt) | traverse(node(nt, x::xs)) = (printNonterminal(nt);

traverse(x); traverseList(xs))andfun traverseList([]) = print “ “ | traverseList(x::xs) = (traverse(x); traverseList(xs));

ASTs Revisited

Page 52: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Record Structures

• Records are wrapped in curly braces, and fields are separated by commas

• Field names may be used to refer to specific elements of the record

Page 53: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Record Example

- type addressType = {street:string, city:string, zip:int};type addressType = {city:string, street:string, zip:int} (note that SML sorted the fields alphabetically)- val umbc:addressType = {street="1000 Hilltop Circle",city="Baltimore",zip=21250};val umbc = {city="Baltimore",street="1000 Hilltop Circle",zip=21250} : addressType- #city(umbc);val it = "Baltimore" : string

Page 54: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Pattern Matching in Records

• Pattern matching works, as inx as {street=xstr,city=xcity,zip=xzip}::xs

• If we don’t care about all the fields, use an ellipsis, e.g. x as {street=xstr,…}::xs

• Or even x as {city,…}

Page 55: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Arrays

• open Array;val zeroVector = array(100,0);

• sub(zeroVector,0) is zero, as is sub(zeroVector,99)

• update(zeroVector,2,3.14) changes the third element of the (now misnamed) zeroVector

Page 56: Introduction to ML CS 331 Principles of Programming Languages revised Spring 2003

Case Studies

• Hash tables– Make an array of hash buckets, each bucket

containing a simple list of values

• Triangularization of a matrix– If the array has m rows and n columns, make an

array of m elements, each element being an array of n elements.