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

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

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

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.