156
CSCC24 — Functional Programming — Typing, Scope, Exceptions— ML Carolyn MacLeod 1 winter 2012 1 Based on slides by Anya Tafliovich, with many thanks to Gerald Penn and Sheila McIlraith. 1

CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

  • Upload
    others

  • View
    5

  • Download
    0

Embed Size (px)

Citation preview

Page 1: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

CSCC24 — Functional Programming — Typing,Scope, Exceptions— ML

Carolyn MacLeod1

winter 2012

1Based on slides by Anya Tafliovich, with many thanks to Gerald Penn andSheila McIlraith.

1

Page 2: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

Consider the following Scheme function definition:

(define foobar

(lambda (x)

(if (even? x)

(first x)

(rest x))))

Anything wrong?

even? expects a number andfirst, rest expect a list=⇒ we’ll get an error at run-time.

We are able to figure it out before run-time. Can’t a PL supportthis kind of reasoning?

2

Page 3: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

Consider the following Scheme function definition:

(define foobar

(lambda (x)

(if (even? x)

(first x)

(rest x))))

Anything wrong?

even? expects a number andfirst, rest expect a list=⇒ we’ll get an error at run-time.

We are able to figure it out before run-time. Can’t a PL supportthis kind of reasoning?

2

Page 4: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

Consider the following Scheme function definition:

(define foobar

(lambda (x)

(if (even? x)

(first x)

(rest x))))

Anything wrong?

even? expects a number andfirst, rest expect a list=⇒ we’ll get an error at run-time.

We are able to figure it out before run-time. Can’t a PL supportthis kind of reasoning?

2

Page 5: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

What is the property of Scheme that is related to this property

Dynamic typing

What other language do you know with dynamic typing?

Python

3

Page 6: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

What is the property of Scheme that is related to this property

Dynamic typing

What other language do you know with dynamic typing?

Python

3

Page 7: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

What is the property of Scheme that is related to this property

Dynamic typing

What other language do you know with dynamic typing?

Python

3

Page 8: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

What is the property of Scheme that is related to this property

Dynamic typing

What other language do you know with dynamic typing?

Python

3

Page 9: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

• It could be worse!

• At least Scheme checks that x is a list (cons pair) beforeaccessing memory in the execution of (rest x) .

• In fact, Scheme is type safe: it will never execute (op arg)

if op is not applicable to arg .

• What’s a language you know that is not type safe?

• C is one you most likely know.

• Languages which are not type safe (e.g., C) allow unsafememory accesses: a major source of security vulnerabilities.

4

Page 10: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

• It could be worse!

• At least Scheme checks that x is a list (cons pair) beforeaccessing memory in the execution of (rest x) .

• In fact, Scheme is type safe: it will never execute (op arg)

if op is not applicable to arg .

• What’s a language you know that is not type safe?

• C is one you most likely know.

• Languages which are not type safe (e.g., C) allow unsafememory accesses: a major source of security vulnerabilities.

4

Page 11: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

• It could be worse!

• At least Scheme checks that x is a list (cons pair) beforeaccessing memory in the execution of (rest x) .

• In fact, Scheme is type safe: it will never execute (op arg)

if op is not applicable to arg .

• What’s a language you know that is not type safe?

• C is one you most likely know.

• Languages which are not type safe (e.g., C) allow unsafememory accesses: a major source of security vulnerabilities.

4

Page 12: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

• It could be worse!

• At least Scheme checks that x is a list (cons pair) beforeaccessing memory in the execution of (rest x) .

• In fact, Scheme is type safe: it will never execute (op arg)

if op is not applicable to arg .

• What’s a language you know that is not type safe?

• C is one you most likely know.

• Languages which are not type safe (e.g., C) allow unsafememory accesses: a major source of security vulnerabilities.

4

Page 13: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

• It could be worse!

• At least Scheme checks that x is a list (cons pair) beforeaccessing memory in the execution of (rest x) .

• In fact, Scheme is type safe: it will never execute (op arg)

if op is not applicable to arg .

• What’s a language you know that is not type safe?

• C is one you most likely know.

• Languages which are not type safe (e.g., C) allow unsafememory accesses: a major source of security vulnerabilities.

4

Page 14: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

• It could be worse!

• At least Scheme checks that x is a list (cons pair) beforeaccessing memory in the execution of (rest x) .

• In fact, Scheme is type safe: it will never execute (op arg)

if op is not applicable to arg .

• What’s a language you know that is not type safe?

• C is one you most likely know.

• Languages which are not type safe (e.g., C) allow unsafememory accesses: a major source of security vulnerabilities.

4

Page 15: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

• Want to catch all errors at compile-time.

• Extremely difficult, if not impossible.

• Identify a certain class of errors and guarantee to catch all ofthem.

• Catch as many errors as possible?

• Costly: programmers’ expertise, computational resources, etc.• Slower development, less expressive languages.• Used in development of safety-critical systems.

• Compromise: type systems.

• Guarantees range widely: from basic safety of memory accessesto just about anything you want.

5

Page 16: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

• Want to catch all errors at compile-time.• Extremely difficult, if not impossible.

• Identify a certain class of errors and guarantee to catch all ofthem.

• Catch as many errors as possible?

• Costly: programmers’ expertise, computational resources, etc.• Slower development, less expressive languages.• Used in development of safety-critical systems.

• Compromise: type systems.

• Guarantees range widely: from basic safety of memory accessesto just about anything you want.

5

Page 17: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

• Want to catch all errors at compile-time.• Extremely difficult, if not impossible.

• Identify a certain class of errors and guarantee to catch all ofthem.

• Catch as many errors as possible?

• Costly: programmers’ expertise, computational resources, etc.• Slower development, less expressive languages.• Used in development of safety-critical systems.

• Compromise: type systems.

• Guarantees range widely: from basic safety of memory accessesto just about anything you want.

5

Page 18: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

• Want to catch all errors at compile-time.• Extremely difficult, if not impossible.

• Identify a certain class of errors and guarantee to catch all ofthem.

• Catch as many errors as possible?

• Costly: programmers’ expertise, computational resources, etc.• Slower development, less expressive languages.• Used in development of safety-critical systems.

• Compromise: type systems.

• Guarantees range widely: from basic safety of memory accessesto just about anything you want.

5

Page 19: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

• Want to catch all errors at compile-time.• Extremely difficult, if not impossible.

• Identify a certain class of errors and guarantee to catch all ofthem.

• Catch as many errors as possible?• Costly: programmers’ expertise, computational resources, etc.

• Slower development, less expressive languages.• Used in development of safety-critical systems.

• Compromise: type systems.

• Guarantees range widely: from basic safety of memory accessesto just about anything you want.

5

Page 20: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

• Want to catch all errors at compile-time.• Extremely difficult, if not impossible.

• Identify a certain class of errors and guarantee to catch all ofthem.

• Catch as many errors as possible?• Costly: programmers’ expertise, computational resources, etc.• Slower development, less expressive languages.

• Used in development of safety-critical systems.

• Compromise: type systems.

• Guarantees range widely: from basic safety of memory accessesto just about anything you want.

5

Page 21: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

• Want to catch all errors at compile-time.• Extremely difficult, if not impossible.

• Identify a certain class of errors and guarantee to catch all ofthem.

• Catch as many errors as possible?• Costly: programmers’ expertise, computational resources, etc.• Slower development, less expressive languages.• Used in development of safety-critical systems.

• Compromise: type systems.

• Guarantees range widely: from basic safety of memory accessesto just about anything you want.

5

Page 22: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

• Want to catch all errors at compile-time.• Extremely difficult, if not impossible.

• Identify a certain class of errors and guarantee to catch all ofthem.

• Catch as many errors as possible?• Costly: programmers’ expertise, computational resources, etc.• Slower development, less expressive languages.• Used in development of safety-critical systems.

• Compromise: type systems.

• Guarantees range widely: from basic safety of memory accessesto just about anything you want.

5

Page 23: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

motivation

• Want to catch all errors at compile-time.• Extremely difficult, if not impossible.

• Identify a certain class of errors and guarantee to catch all ofthem.

• Catch as many errors as possible?• Costly: programmers’ expertise, computational resources, etc.• Slower development, less expressive languages.• Used in development of safety-critical systems.

• Compromise: type systems.• Guarantees range widely: from basic safety of memory accesses

to just about anything you want.

5

Page 24: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

typing

A type is:

“A name for a set of values and some operations which can beperformed on that set of values.”

“A collection of computational entities that share some commonproperty.”

6

Page 25: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

typing

Some examples of types (in ML notation):

• int : the integers (and their operations).

• real : the real numbers (and their operations).

• string : the strings (and their operations).

• bool : the booleans (and their operations).

• int → bool : the functions that take integers as input andreturn booleans as output.

What constitutes a type is language dependent.

7

Page 26: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

typing

Some examples of types (in ML notation):

• int : the integers (and their operations).

• real : the real numbers (and their operations).

• string : the strings (and their operations).

• bool : the booleans (and their operations).

• int → bool : the functions that take integers as input andreturn booleans as output.

What constitutes a type is language dependent.

7

Page 27: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

typing

Benefits of having a type system:

• Easier to debug programs: compiler can catch many errors.

• Static analysis: a lot of useful information about the programcan be obtained at compile-time.

• Efficiency: typing can be used by the compiler to generatequicker code.

• Correctness: typing can be used (by the programmer or by thecompiler) to prove correctness of code.

• Documentation: types declare your intent with well-chosennames.

8

Page 28: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

Recall - last lecture

We saw this Scheme function definition:

(define foobar

(lambda (x)

(if (even? x)

(first x)

(rest x))))

What is wrong with the code?

What programming language feature would stop us creatingprograms with this kind of bugs?

9

Page 29: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

Recall - last lecture

We saw this Scheme function definition:

(define foobar

(lambda (x)

(if (even? x)

(first x)

(rest x))))

What is wrong with the code?

What programming language feature would stop us creatingprograms with this kind of bugs?

9

Page 30: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

typing

A programming language is type safe if no program is allowed toviolate its type distinctions.

The process of verifying and enforcing the constraints of types iscalled type checking.

Type checking can either occur at compile-time (static typechecking) or at run-time (dynamic type checking).

10

Page 31: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

static vs dynamic typing

Dynamic type checking:

• Performed at run-time.

• Slower execution: need to carry type information around, lotsof run-time checks.

• More flexible.

• Easier refactoring.

Static type checking:

• Faster execution.

• Compiler can do a lot of optimization.

• Some argue that resulting programs are safer.

• Some argue that resulting programs are more elegant andmodular.

• Some argue that programmers will write horrible code to getaround a static type-checker.

11

Page 32: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

static vs dynamic typing

Dynamic type checking:

• Performed at run-time.

• Slower execution: need to carry type information around, lotsof run-time checks.

• More flexible.

• Easier refactoring.

Static type checking:

• Faster execution.

• Compiler can do a lot of optimization.

• Some argue that resulting programs are safer.

• Some argue that resulting programs are more elegant andmodular.

• Some argue that programmers will write horrible code to getaround a static type-checker.

11

Page 33: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

static typing

Explicit static typing: code contains type annotations.

• For example, in Java:• Variable declarationsint x,y,z;

• Function headerspublic static void main(String[] arg)

Type inference: infer all types from the code that does not containexplicit type annotations.

• fun foo(x,y,z) = if x then y + z + 1.5 else 0.0;

• x must be boolean

• y, z must be reals

• the return value is real

• foo : bool * real * real -> real

12

Page 34: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

static typing

Explicit static typing: code contains type annotations.

• For example, in Java:• Variable declarationsint x,y,z;

• Function headerspublic static void main(String[] arg)

Type inference: infer all types from the code that does not containexplicit type annotations.

• fun foo(x,y,z) = if x then y + z + 1.5 else 0.0;

• x must be boolean

• y, z must be reals

• the return value is real

• foo : bool * real * real -> real

12

Page 35: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

static typing

Explicit static typing: code contains type annotations.

• For example, in Java:• Variable declarationsint x,y,z;

• Function headerspublic static void main(String[] arg)

Type inference: infer all types from the code that does not containexplicit type annotations.

• fun foo(x,y,z) = if x then y + z + 1.5 else 0.0;

• x must be boolean

• y, z must be reals

• the return value is real

• foo : bool * real * real -> real

12

Page 36: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

static typing

Explicit static typing: code contains type annotations.

• For example, in Java:• Variable declarationsint x,y,z;

• Function headerspublic static void main(String[] arg)

Type inference: infer all types from the code that does not containexplicit type annotations.

• fun foo(x,y,z) = if x then y + z + 1.5 else 0.0;

• x must be boolean

• y, z must be reals

• the return value is real

• foo : bool * real * real -> real

12

Page 37: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

static typing

Explicit static typing: code contains type annotations.

• For example, in Java:• Variable declarationsint x,y,z;

• Function headerspublic static void main(String[] arg)

Type inference: infer all types from the code that does not containexplicit type annotations.

• fun foo(x,y,z) = if x then y + z + 1.5 else 0.0;

• x must be boolean

• y, z must be reals

• the return value is real

• foo : bool * real * real -> real

12

Page 38: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

static typing

Explicit static typing: code contains type annotations.

• For example, in Java:• Variable declarationsint x,y,z;

• Function headerspublic static void main(String[] arg)

Type inference: infer all types from the code that does not containexplicit type annotations.

• fun foo(x,y,z) = if x then y + z + 1.5 else 0.0;

• x must be boolean

• y, z must be reals

• the return value is real

• foo : bool * real * real -> real

12

Page 39: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

Features of Standard ML

What is ML?

ML is an ALGOL family language, a child of Pascal and Lisp, anda distant cousin of C

ML was designed as the Meta- Language of the Logic forComputable Functions (LCF) System. Its original purpose was forwriting programs that would attempt to construct mathematicalproofs.

Question - What have we seen that is similar?

ML is a functional language, although ML can be written in amore imperative style. Arguably, you can call it a mostly functionallanguage, or a function-oriented imperative language.

13

Page 40: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

Features of Standard ML

• Modular:Supports modules and interfaces, determining whatcomponents and types from the module are visible outside.

• Strict Pass By Value: The arguments of the function areevaluated before the beginning of the function beingevaluated.

• Polymorphic: Supports both data type and functionpolymorphism.

• Type System: The ML type system is considered one of thecleanest in any language

• Static typing• Type inference• Type safe

• Functions are first class values: Functions can be defined,passed as arguments, and returned as function results.

• Garbage Collection

• Exception Handling

14

Page 41: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

Standard ML

A few examples

15

Page 42: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML Examples

(* This is a comment in SML *)

fun factorial (n:int):int =

if n = 0

then 1

else n * factorial(n-1)

Notice, we use ”=” both for comparison, and for the functiondefinition. We use an infix notation, unlike in Scheme. In thisexample, we have explicit static typing.

16

Page 43: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML Examples

Another form of writing function definitions:

(* Our first fibonacci solution in Scheme,

translated to ML *)

fun fib 1 = 1

| fib 2 = 1

| fib (n) = fib(n-1) + fib(n-2)

This is also an example of type inference - notice that this versiondoes not specify types for the input and output of fib, however,when compiled or entered into the interpreter, it gives a typesignature of

val fib = fn : int -> int

17

Page 44: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

type inference

Trade-off:

• Want the language to be expressive.

• Want tractable type inference.

ML is designed to make type inference tractable.

Widely regarded as an important language innovation.

18

Page 45: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML data types

Basic types:

• unit : the only member is ().

• bool : booleans.

• int : integers.

• real : reals.

• string : strings.

More types:

• (〈type0〉 ∗ 〈type1〉 ∗ . . . ∗ 〈typen〉) : tuples.

• 〈type〉 list : lists.

• 〈input-type〉 → 〈output-type〉 : functions.

19

Page 46: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML data types

Basic types:

• unit : the only member is ().

• bool : booleans.

• int : integers.

• real : reals.

• string : strings.

More types:

• (〈type0〉 ∗ 〈type1〉 ∗ . . . ∗ 〈typen〉) : tuples.

• 〈type〉 list : lists.

• 〈input-type〉 → 〈output-type〉 : functions.

19

Page 47: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML basic types

unit: this type has only one element ()

- ();

val it = () : unit

ML assigns the last evaluated value to the special variable it.Reading the above snippet of the ML interpreter session:

• evaluate (), please

• the special variable it now has the value () of type unit

20

Page 48: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML basic types

bool: this type has two elements: true and false.

Operations on bools: not, toString, ...

Special operators: andalso, orelse.

For example:

- if (not true andalso false) orelse true

then true

else false;

val it true : bool

21

Page 49: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML basic types

The structure of lists in ML is the same as in Scheme and Prolog.Strings must have elements of all the same type.

- hd [1,2,3];

val it = 1 : int

- tl [1,2,3];

val it = [2,3] : int list

- "a" :: ["b","c"];

val it = ["a","b","c"] : string list

- [1,2]@[3];

val it = [1,2,3] : int list

These are the equivalents of first/car, rest/cdr, and cons inScheme. The ”@” operator is used like append in Scheme.

22

Page 50: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML basic types

fun elem_to_list [] = []

| elem_to_list (h::t) =

[h] :: (elem_to_list t)

23

Page 51: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML basic types

int: {... ˜2, ˜1, 0 , 1 , 2, ... }

Operations: +, −, ∗, ˜, div, mod, <, >, =, <=, >=, <>

For example:

- 5 + 6 * 2 - 3 div 2;

val it = 16 : int

- 5 mod 2 >= 6 mod 2;

val it = true : bool

24

Page 52: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML basic types

int: {... ˜2, ˜1, 0 , 1 , 2, ... }Note the use of ~ for negation. Here’s why: - is a binaryoperator while ~ is a unary operator.

- -5;

stdIn:27.1 Error: expression or pattern begins

with infix identifier "-"

stdIn:27.1-27.3 Error: operator and operand don’t

agree [literal]

operator domain: ’Z * ’Z

operand: int

in expression:

- 5

- ~5;

val it = ~5 : int

25

Page 53: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML basic types

real: { 1.0, 3.14159, 11.7, .... }

Operations: +, −, ∗, <, >, <=, >=

Note: You cannot mix reals and integers in one expression.

Every ML expression has a type. If an expression cannot be typed,we get an error.

26

Page 54: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML basic types

For example:

- 2 - 1.5;

stdIn:43.1-43.8 Error: operator and operand

don’t agree

operator domain: int * int

operand: int * real

in expression:

2 - 1.5

Understanding the error message...

Why int ? For mathematical operators, if the type is notspecified (or inferred), then type int is assumed.

27

Page 55: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML basic types

More examples:

- 2;

val it = 2 : int

- 2.0;

val it = 2.0 : real

- real(2);

val it = 2.0 : real

- 2.0 - 1.5;

val it = 0.5 : real

- real(2) - 1.5;

val it = 0.5 : real

28

Page 56: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML basic types

Note that SML inspects the leftmost argument first. For example:

- 1.5 + 2;

stdIn:1.1-2.3 Error: operator and operand

don’t agree

operator domain: real * real

operand: real * int

in expression:

1.5 + 2

Now it expects two reals.

29

Page 57: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML basic types

Note that while <, <=, >, >= are defined for all numeric types,= and <> are, for example, not defined for reals. In fact,

= : ’’a * ’’a -> bool

<> : ’’a * ’’a -> bool

In ML ’’a means the type for which equality is defined.

With reals we can use a <= b andalso b >= a.

Or, much better, use real arithmetic:

- Real.==(1.0, 1.0);

val it = true : bool

- Real.==(1.0, 1.00000);

val it = true : bool

30

Page 58: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML basic types

string: { ”Hello, world”, ”CSCC24 is fun!”, ... }

Operations: ^ for concatenation

For example:

- "Hello";

val it = "Hello" : string

- "Hello" ^ " " ^ "Jim";

val it = "Hello Jim" : string

31

Page 59: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML data types

Basic types:

• unit : the only member is ().

• bool : booleans.

• int : integers.

• real : reals.

• string : strings.

More types:

• (〈type0〉 ∗ 〈type1〉 ∗ . . . ∗ 〈typen〉) : tuples.

• 〈type〉 list : lists.

• 〈input-type〉 → 〈output-type〉 : functions.

32

Page 60: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML data types

Basic types:

• unit : the only member is ().

• bool : booleans.

• int : integers.

• real : reals.

• string : strings.

More types:

• (〈type0〉 ∗ 〈type1〉 ∗ . . . ∗ 〈typen〉) : tuples.

• 〈type〉 list : lists.

• 〈input-type〉 → 〈output-type〉 : functions.

32

Page 61: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML types

A tuple packs together several types.

- ("foo", "bar");

val it = ("foo","bar") : string * string

- ("foo", "bar", 123);

val it = ("foo","bar",123) : string * string * int

- ("foo", (123, 456));

val it = ("foo",(123,456)) : string * (int * int)

Operations: accessing component N of a tuple t is written #N t.

- #2 ("foo", 123, 3.14);

val it = 123 : int

33

Page 62: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML types

In ML all elements in a list must have the same type.

- [1,2,3,4];

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

- ["cscc24","is","fun"];

val it = ["cscc24","is","fun"] : string list

- [("foo",1.0),("bar",3.14)];

val it = [("foo",1.0),("bar",3.14)] : (string * real) list

[ ] (or nil) is the empty list.

Constructor: ::

Selectors: hd, tl

More operations: @, null, length, map, foldr, ...

34

Page 63: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML types

Some examples:

- "foo"::["bar","foobar"];

val it = ["foo","bar","foobar"] : string list

- [1,2]@[3,4];

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

- hd [1,2];

val it = 1 : int

- tl [1,2];

val it = [2] : int list

35

Page 64: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML syntax

A variable declaration in ML looks like:

• val 〈name〉 = 〈expr〉

• val x = 42 + 24

• (define x (+ 42 24))

36

Page 65: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML syntax

A variable declaration in ML looks like:

• val 〈name〉 = 〈expr〉• val x = 42 + 24

• (define x (+ 42 24))

36

Page 66: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML syntax

A variable declaration in ML looks like:

• val 〈name〉 = 〈expr〉• val x = 42 + 24

• (define x (+ 42 24))

36

Page 67: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML functions

The syntax for anonymous functions in ML is:

• fn 〈arg〉 => 〈body〉

• fn x => x + 1

• (lambda (x) (+ x 1))

Giving a name to a function:

• val 〈name〉 = fn 〈arg〉 => 〈body〉• val inc = fn x => x + 1

• (define inc (lambda (x) (+ x 1)))

Or:

• fun 〈name〉 〈arg〉 = 〈body〉• fun inc x = x + 1

• (define (inc x) (+ x 1))

In ML every function accepts exactly one argument.This argumentcould be a tuple.

37

Page 68: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML functions

The syntax for anonymous functions in ML is:

• fn 〈arg〉 => 〈body〉• fn x => x + 1

• (lambda (x) (+ x 1))

Giving a name to a function:

• val 〈name〉 = fn 〈arg〉 => 〈body〉• val inc = fn x => x + 1

• (define inc (lambda (x) (+ x 1)))

Or:

• fun 〈name〉 〈arg〉 = 〈body〉• fun inc x = x + 1

• (define (inc x) (+ x 1))

In ML every function accepts exactly one argument.This argumentcould be a tuple.

37

Page 69: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML functions

The syntax for anonymous functions in ML is:

• fn 〈arg〉 => 〈body〉• fn x => x + 1

• (lambda (x) (+ x 1))

Giving a name to a function:

• val 〈name〉 = fn 〈arg〉 => 〈body〉• val inc = fn x => x + 1

• (define inc (lambda (x) (+ x 1)))

Or:

• fun 〈name〉 〈arg〉 = 〈body〉• fun inc x = x + 1

• (define (inc x) (+ x 1))

In ML every function accepts exactly one argument.This argumentcould be a tuple.

37

Page 70: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML functions

The syntax for anonymous functions in ML is:

• fn 〈arg〉 => 〈body〉• fn x => x + 1

• (lambda (x) (+ x 1))

Giving a name to a function:

• val 〈name〉 = fn 〈arg〉 => 〈body〉• val inc = fn x => x + 1

• (define inc (lambda (x) (+ x 1)))

Or:

• fun 〈name〉 〈arg〉 = 〈body〉• fun inc x = x + 1

• (define (inc x) (+ x 1))

In ML every function accepts exactly one argument.This argumentcould be a tuple.

37

Page 71: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML functions

The syntax for anonymous functions in ML is:

• fn 〈arg〉 => 〈body〉• fn x => x + 1

• (lambda (x) (+ x 1))

Giving a name to a function:

• val 〈name〉 = fn 〈arg〉 => 〈body〉

• val inc = fn x => x + 1

• (define inc (lambda (x) (+ x 1)))

Or:

• fun 〈name〉 〈arg〉 = 〈body〉• fun inc x = x + 1

• (define (inc x) (+ x 1))

In ML every function accepts exactly one argument.This argumentcould be a tuple.

37

Page 72: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML functions

The syntax for anonymous functions in ML is:

• fn 〈arg〉 => 〈body〉• fn x => x + 1

• (lambda (x) (+ x 1))

Giving a name to a function:

• val 〈name〉 = fn 〈arg〉 => 〈body〉• val inc = fn x => x + 1

• (define inc (lambda (x) (+ x 1)))

Or:

• fun 〈name〉 〈arg〉 = 〈body〉• fun inc x = x + 1

• (define (inc x) (+ x 1))

In ML every function accepts exactly one argument.This argumentcould be a tuple.

37

Page 73: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML functions

The syntax for anonymous functions in ML is:

• fn 〈arg〉 => 〈body〉• fn x => x + 1

• (lambda (x) (+ x 1))

Giving a name to a function:

• val 〈name〉 = fn 〈arg〉 => 〈body〉• val inc = fn x => x + 1

• (define inc (lambda (x) (+ x 1)))

Or:

• fun 〈name〉 〈arg〉 = 〈body〉• fun inc x = x + 1

• (define (inc x) (+ x 1))

In ML every function accepts exactly one argument.This argumentcould be a tuple.

37

Page 74: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML functions

The syntax for anonymous functions in ML is:

• fn 〈arg〉 => 〈body〉• fn x => x + 1

• (lambda (x) (+ x 1))

Giving a name to a function:

• val 〈name〉 = fn 〈arg〉 => 〈body〉• val inc = fn x => x + 1

• (define inc (lambda (x) (+ x 1)))

Or:

• fun 〈name〉 〈arg〉 = 〈body〉• fun inc x = x + 1

• (define (inc x) (+ x 1))

In ML every function accepts exactly one argument.This argumentcould be a tuple.

37

Page 75: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML functions

The syntax for anonymous functions in ML is:

• fn 〈arg〉 => 〈body〉• fn x => x + 1

• (lambda (x) (+ x 1))

Giving a name to a function:

• val 〈name〉 = fn 〈arg〉 => 〈body〉• val inc = fn x => x + 1

• (define inc (lambda (x) (+ x 1)))

Or:

• fun 〈name〉 〈arg〉 = 〈body〉

• fun inc x = x + 1

• (define (inc x) (+ x 1))

In ML every function accepts exactly one argument.This argumentcould be a tuple.

37

Page 76: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML functions

The syntax for anonymous functions in ML is:

• fn 〈arg〉 => 〈body〉• fn x => x + 1

• (lambda (x) (+ x 1))

Giving a name to a function:

• val 〈name〉 = fn 〈arg〉 => 〈body〉• val inc = fn x => x + 1

• (define inc (lambda (x) (+ x 1)))

Or:

• fun 〈name〉 〈arg〉 = 〈body〉• fun inc x = x + 1

• (define (inc x) (+ x 1))

In ML every function accepts exactly one argument.This argumentcould be a tuple.

37

Page 77: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML functions

The syntax for anonymous functions in ML is:

• fn 〈arg〉 => 〈body〉• fn x => x + 1

• (lambda (x) (+ x 1))

Giving a name to a function:

• val 〈name〉 = fn 〈arg〉 => 〈body〉• val inc = fn x => x + 1

• (define inc (lambda (x) (+ x 1)))

Or:

• fun 〈name〉 〈arg〉 = 〈body〉• fun inc x = x + 1

• (define (inc x) (+ x 1))

In ML every function accepts exactly one argument.This argumentcould be a tuple.

37

Page 78: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML functions

The syntax for anonymous functions in ML is:

• fn 〈arg〉 => 〈body〉• fn x => x + 1

• (lambda (x) (+ x 1))

Giving a name to a function:

• val 〈name〉 = fn 〈arg〉 => 〈body〉• val inc = fn x => x + 1

• (define inc (lambda (x) (+ x 1)))

Or:

• fun 〈name〉 〈arg〉 = 〈body〉• fun inc x = x + 1

• (define (inc x) (+ x 1))

In ML every function accepts exactly one argument.This argumentcould be a tuple.

37

Page 79: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML functions

The syntax for anonymous functions in ML is:

• fn 〈arg〉 => 〈body〉• fn x => x + 1

• (lambda (x) (+ x 1))

Giving a name to a function:

• val 〈name〉 = fn 〈arg〉 => 〈body〉• val inc = fn x => x + 1

• (define inc (lambda (x) (+ x 1)))

Or:

• fun 〈name〉 〈arg〉 = 〈body〉• fun inc x = x + 1

• (define (inc x) (+ x 1))

In ML every function accepts exactly one argument.

This argumentcould be a tuple.

37

Page 80: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML functions

The syntax for anonymous functions in ML is:

• fn 〈arg〉 => 〈body〉• fn x => x + 1

• (lambda (x) (+ x 1))

Giving a name to a function:

• val 〈name〉 = fn 〈arg〉 => 〈body〉• val inc = fn x => x + 1

• (define inc (lambda (x) (+ x 1)))

Or:

• fun 〈name〉 〈arg〉 = 〈body〉• fun inc x = x + 1

• (define (inc x) (+ x 1))

In ML every function accepts exactly one argument.This argumentcould be a tuple.

37

Page 81: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML types

The type of a function is determined by the type of the input andthe type of the output.

Some examples:

- fun inc x = x + 1;

val inc = fn : int -> int

- fun addInc(x,y) = x + y + 1;

val addInc = fn : int * int -> int

- fun optInc(x,y,c) = if c then x + y + 1 else x + y;

val optInc = fn : int * int * bool -> int

38

Page 82: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

parametric polymorphism

What is the type of fn x => x ?

- fun id x = x;

val id = fn : ’a -> ’a

- id 324;

val it = 324 : int

- id 3.14;

val it = 3.14 : real

- id "foo";

val it = "foo" : string

- id [1,2,3];

val it = [1,2,3] : int list

- id (fn x => x + 1);

val it = fn : int -> int

39

Page 83: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

parametric polymorphism

What is the type of fn x => x ?

- fun id x = x;

val id = fn : ’a -> ’a

- id 324;

val it = 324 : int

- id 3.14;

val it = 3.14 : real

- id "foo";

val it = "foo" : string

- id [1,2,3];

val it = [1,2,3] : int list

- id (fn x => x + 1);

val it = fn : int -> int

39

Page 84: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

parametric polymorphism

- fun id x = x;

val id = fn : ’a -> ’a

The ’a in ML stands for α. It is a type variable.

id is a polymorphic function.

α→ α means “for every valid type α, α→ α”∀α · α→ α

When id is applied to 324 , the type variable α is instantiatedto int .

40

Page 85: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

parametric polymorphism

- fun id x = x;

val id = fn : ’a -> ’a

The ’a in ML stands for α. It is a type variable.

id is a polymorphic function.

α→ α means “for every valid type α, α→ α”∀α · α→ α

When id is applied to 324 , the type variable α is instantiatedto int .

40

Page 86: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

parametric polymorphism

- fun id x = x;

val id = fn : ’a -> ’a

The ’a in ML stands for α. It is a type variable.

id is a polymorphic function.

α→ α means “for every valid type α, α→ α”∀α · α→ α

When id is applied to 324 , the type variable α is instantiatedto int .

40

Page 87: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

parametric polymorphism

- fun id x = x;

val id = fn : ’a -> ’a

The ’a in ML stands for α. It is a type variable.

id is a polymorphic function.

α→ α means “for every valid type α, α→ α”∀α · α→ α

When id is applied to 324 , the type variable α is instantiatedto int .

40

Page 88: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

parametric polymorphism

Examples:

fun choose (a,b,c) = if a then b else c;

choose : bool * ’a * ’a -> ’a;

fun swap (x,y) = (y,x);

swap : ’a * ’b -> ’b * ’a;

41

Page 89: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

parametric polymorphism

Examples:

fun choose (a,b,c) = if a then b else c;

choose : bool * ’a * ’a -> ’a;

fun swap (x,y) = (y,x);

swap : ’a * ’b -> ’b * ’a;

41

Page 90: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

parametric polymorphism

Examples:

fun choose (a,b,c) = if a then b else c;

choose : bool * ’a * ’a -> ’a;

fun swap (x,y) = (y,x);

swap : ’a * ’b -> ’b * ’a;

41

Page 91: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

parametric polymorphism

Examples:

fun choose (a,b,c) = if a then b else c;

choose : bool * ’a * ’a -> ’a;

fun swap (x,y) = (y,x);

swap : ’a * ’b -> ’b * ’a;

41

Page 92: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

parametric polymorphism

What is the type of the following function?

fun length lst = if (null lst) then 0

else 1 + length (tl lst);

length : ’a list -> int

List is a polymorphic data type.

42

Page 93: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

parametric polymorphism

What is the type of the following function?

fun length lst = if (null lst) then 0

else 1 + length (tl lst);

length : ’a list -> int

List is a polymorphic data type.

42

Page 94: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

parametric polymorphism

What is the type of the following function?

fun length lst = if (null lst) then 0

else 1 + length (tl lst);

length : ’a list -> int

List is a polymorphic data type.

42

Page 95: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

currying

With named functions:

- fun sum x y = x + y;

val sum = fn : int -> int -> int

- sum 2;

val it = fn : int -> int

- sum 2 3;

val it = 5 : int

43

Page 96: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

currying

With anonymous functions:

- fn x => fn y => x + y;

val it = fn : int -> int -> int

- (fn x => fn y => x + y) 2;

val it = fn : int -> int

- (fn x => fn y => x + y) 2 3;

val it = 5 : int

44

Page 97: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

pattern matching

Value declaration (general form): val <pat> = <exp>

- val myTuple = ("foo", "bar");

val myTuple = ("foo","bar") : string * string

- val (x,y) = myTuple;

val x = "foo" : string

val y = "bar" : string

- val myList = [1,2,3,4];

val myList = [1,2,3,4] : int list

- val h::r = myList;

stdIn:52.5-52.18 Warning: binding not exhaustive

h :: r = ...

val h = 1 : int

val r = [2,3,4] : int list45

Page 98: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

pattern matching

“ ” is “don’t care”: matches everything, binds nothing

- val myTuple = (‘‘foo’’, ‘‘bar’’);

val myTuple = ("foo","bar") : string * string

- val (first, _) = myTuple;

val first = "foo" : string

- val h::_ = [1,2,3];

stdIn:66.5-66.19 Warning: binding not exhaustive

h :: _ = ...

val h = 1 : int

46

Page 99: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

pattern matching

Function declaration with pattern matching:

fun <name> <pattern1> = <exp1>

| <name> <pattern2> = <exp2>

.

.

| <name> <patternN> = <expN>;

This means: the function name is name. It takes one argument (asany other ML function). It tries to match the argument topattern1. If it succeeds, it returns value of exp1. Otherwise, triesto match the argument to pattern2. Etc, etc.

47

Page 100: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

pattern matching

For example we can (and should!) rewrite len to use patternmatching:

fun len [] = 0

| len (x::xs) = 1 + len xs;

len : ’a list -> int

Non-exhaustive patterns:

- fun len (x::xs) = 1 + len xs;

stdIn ... Warning: match nonexhaustive

x :: xs => ...

val len = fn : ’a list -> int

- len [1,2,3];

uncaught exception nonexhaustive match failure

raised at: ...

48

Page 101: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

pattern matching

Function firstlist takes a list of pairs and returns the listconsisting of the first elements only. For example:

firstlist [] ==> []

firstlist [(1,2),(1,3)] ==> [1,1]

firstlist [(1,"a"),(2,"b"),(3,"c")] ==> [1,2,3]

firstlist [([],"a"),([1],"b"),([1,2],"c")] ==>

[[],[1],[1,2]]

fun firstlist [] = []

| firstlist ((e1,e2)::es) =

e1::(firstlist es);

firstlist : (’a * ’b) list -> ’a list

49

Page 102: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML notes

Syntax of an ML let expression:

let

<declaration>

<declaration>

...

in

<expression>

end

50

Page 103: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML notes

Example:

fun reverse lst =

let

fun reverseAcc [] acc = acc

| reverseAcc (x::xs) acc =

reverseAcc xs (x::acc)

in

reverseAcc lst []

end;

reverse : ’a list -> ’a list

- reverse [1,2,3];

val it = [3,2,1] : int list

51

Page 104: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML notes

Function application is left-associative:

f g h == (f g) h

Example:

- reverse 1::[2,3];

... Error: operator and operand don’t agree

operator domain: ’Z list

operand: int

in expression:

reverse 1

- reverse (1::[2,3]);

val it = [3,2,1] : int list

52

Page 105: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

type synonyms

We can give existing types new names. Syntax:

type new type = ty

new type becomes an alias (a synonym) for the existing type ty.

-type float = real;

type float = real

-type count = int

and average = real;

type count = int

type average = real

-val f : float = 2.3;

val f = 2.3: float

-val i = 3 : count;

val i = 3: count 53

Page 106: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

type synonyms

But notice float, real, and average are all of the same basetype, i.e. real

-val f : float = 2.3;

val f = 2.3 : float

-val a = f : average;

val a = 2.3 : average

-val sum = a+f;

val sum = 4.6 : average

-val sum = f+a;

val sum = 4.6 : float

54

Page 107: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

user defined datatypes

General Syntax:

datatype new_type =

Cons1 of type1

| Cons2 of type2

...

| ConsN of typeN

• Defines a new type called new type.

• type1,...,typeN are previously defined types.

• Cons1,...,ConsN are constructors. They are used to createa value of new type type.

• of type is omitted if a constructor does not need anyargument (such constructors are called constants).

55

Page 108: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

enumerated types

All constructors are constants (no argument).Example:

-datatype color = Red | Blue | Green;

datatype color = Blue | Green | Red

-val c = Red;

val c = Red : color

-fun colorStr Red = "Red"

| colorStr Blue = "Blue"

| colorStr Green= "Green";

val colorStr = fn : color -> string

-colorStr c;

val it = "Red" : string

56

Page 109: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

variant types

Create union of different types:

datatype number = R of real | I of int;

val n1 = I 2;

val n2 = R 3.0;

val lst = [R 2.2, I 3, I 4, R 0.1];

(* val lst = [R 2.2,I 3,I 4,R 0.1] : number list *)

57

Page 110: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

variant types

datatype number = R of real | I of int;

val lst = [R 2.2, I 3, I 4, R 0.1];

fun sumInts [] = 0

| sumInts ((I x)::rest) = x + sumInts rest

| sumInts ((R x)::rest) = sumInts rest;

sumInts : number list -> int;

sumInts lst;

(* val it = 7 : int *)

58

Page 111: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

recursive types

A datatype can be recursive: e.g. a linked list

datatype llist = Nil | Node of int * llist;

(* datatype llist = Nil | Node of int * llist *)

val x = Nil;

(* val x = Nil : llist *)

val y = Node (5,Nil);

(* val y = Node (5,Nil) : llist *)

val z = Node(3, Node(2, Node(1,Nil)));

(* val z = Node (3,Node (2,Node #)) : llist *)

59

Page 112: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

recursive types

datatype llist = Nil | Node of int * llist;

(* datatype llist = Nil | Node of int * llist *)

(* length of a linked list *)

fun len Nil = 0

| len (Node (_,xs)) = 1 + len xs;

len : llist -> int

len z;

(* val it = 3 : int*)

60

Page 113: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

recursive types

What about a polymorphic linked list?

datatype ’a llist = Nil | Node of ’a * (’a llist);

(* datatype ’a llist = Nil | Node of ’a * ’a llist *)

val y = Node (5,Nil);

(* val y = Node (5,Nil) : int llist *)

val z = Node("A", Node("B",Nil));

(* val z = Node ("A",Node ("B",Nil)) : string llist *)

61

Page 114: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

recursive types

datatype ’a llist = Nil | Node of ’a * (’a llist);

(* datatype ’a llist = Nil | Node of ’a * ’a llist *)

fun len Nil = 0

| len (Node (_,xs)) = 1 + len xs;

len : ’a llist -> int

len y;

(* val it = 1 : int *)

len z;

(* val it = 2 : int *)

62

Page 115: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

recursive types

Example: Tree representation of simple mathematical expressions.

(| − 3|+ 2) + ((−1) + 4) ∗ 7)

add

abs

add mult

add2

7

neg 4neg

13

What is the datatype we need?63

Page 116: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

recursive types

The datatype:

datatype math_tree =

Leaf of int

| Unary of (int -> int) * math_tree

| Binary of (int * int -> int) *

math_tree *

math_tree

64

Page 117: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

recursive types

The tree in the figure:

val t =

Binary(op +,

Binary(op +,

Unary((fn x => if x > 0 then x else ~x),

Unary (op ~,

Leaf 3)),

Leaf 2),

Binary(op * ,

Binary(op +,

Unary(op ~,

Leaf 1),

Leaf 4),

Leaf 7))

65

Page 118: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

recursive types

Evaluating the tree:

(* evaluate the math_tree *)

fun eval (Leaf n) = n

| eval (Unary (f,t)) = f (eval t)

| eval (Binary (f,l,r)) = f (eval l,eval r);

eval : math_tree -> int

- eval t;

val it = 26 : int

66

Page 119: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

SML notes — mutual recursion

Let’s mimic the Scheme definitions of even and odd:

fun even 0 = true

| even x = odd (x - 1);

fun odd 0 = false

| odd x = even (x - 1);

Error: unbound variable or constructor: odd

67

Page 120: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

mutual recursion

Use the keyword and.

fun even 0 = true

| even x = odd (x - 1)

and odd 0 = false

| odd x = even (x - 1);

even : int -> bool;

odd : int -> bool

even 42;

(* val it = true : bool *)

odd 42;

(* val it = false : bool *)

68

Page 121: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

mutually recursive types

Example: a tree with labeled branches:

1

7 823

45

6

datatype ’a tree = Empty

| Node of ’a branch * ’a branch

and ’a branch = Branch of ’a * ’a tree;

69

Page 122: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

mutually recursive types

The tree in the figure:

val lt =

Node(Branch(1,

Node(Branch(2,

Empty),

Branch(3,

Node(Branch(4,

Empty),

Branch(5,

Empty))))),

Branch(6,

Node(Branch(7,

Empty),

Branch(8,

Empty))));

70

Page 123: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

mutually recursive types

datatype ’a tree = Empty

| Node of ’a branch * ’a branch

and ’a branch = Branch of ’a * ’a tree

Return the list of branch labels, in order:

fun listTree Empty = []

| listTree (Node (l,r)) =

(listBranch l) @ (listBranch r)

and listBranch (Branch (b,t)) =

b :: (listTree t);

listTree : ’a tree -> ’a list;

listBranch : ’a branch -> ’a list

listTree t;

(* val it = [1,2,3,4,5,6,7,8] : int list *)

71

Page 124: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

recursive types

1. A powerful tool for constructing new types.

2. The structure of the datatype suggests the structure of therecursive function on the datatype.

72

Page 125: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

recursive types

Recall our CFG for arithmetic expressions:

<expn> --> <expn> + <expn> |

<expn> - <expn> |

<expn> * <expn> |

<expn> / <expn> |

<identifier> |

<literal>

Let’s define a (somewhat) corresponding datatype:

datatype expn = Plus of expn * expn

| Minus of expn * expn

| Times of expn * expn

| Divn of expn * expn

| Num of real;

73

Page 126: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

recursive types

datatype expn = Plus of expn * expn

| Minus of expn * expn

| Times of expn * expn

| Divn of expn * expn

| Num of real;

For example:

5 + 7*(-2) - 8 / 4

val e =

Minus(Plus(Num 5.0,

Times(Num 7.0,

Num ~2.0)),

Divn(Num 8.0,

Num 4.0));

74

Page 127: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

recursive types

Evaluating the expression:

fun eval (Num n) = n

| eval (Divn (x,y)) = (eval x) / (eval y)

| eval (Times (x,y)) = (eval x) * (eval y)

| eval (Minus (x,y)) = (eval x) - (eval y)

| eval (Plus (x,y)) = (eval x) + (eval y);

eval : expn -> real;

eval e;

(* val it = ~11.0 : real *)

75

Page 128: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

SML

• types, types, types...

• built-in types

• type synonyms, user-defined types

• enumerated, variant, union, recursive, mutually recursive

• recursion, higher-order functions (maps, folds)

76

Page 129: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

using let in ML

fun sumcube n =

let

fun cube x = x * x * x

in

if n = 0 then 0

else cube (n) + sumcube (n-1)

end;

Is it a good idea?cube is redefined every recursive call.

77

Page 130: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

using let in ML

Better idea:

fun sumcube n =

let

fun cube x = x * x * x;

fun sumc 0 = 0

| sumc m = cube m + sumc (m-1)

in

sumc n

end;

78

Page 131: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

scope

Name resolution: Given the use of a name (variable or functionname), which instance of the entity with that name is referred to?

Each use of a name must be associated with a single entity atrun-time (i.e., an offset within a stack frame).

The scope of a declaration of a name is the part of the program inwhich a use of that name refers to that declaration.

The design of a language includes scope rules for resolving themapping from the use of each name to its appropriate declaration.

79

Page 132: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

scope

A name is:

• visible to a piece of code if its scope includes that piece ofcode.

• local to a piece of code (block/ procedure/main program) ifits declaration is within that piece of code.

• non-local to a piece of code if it is visible, but its declarationis not within that piece of code.

A declaration of a name is hidden if another declaration supersedesit in scope.

80

Page 133: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

scope example

program L;

var n: char; {n declared in L}

procedure W;

begin

write(n); {n referenced in W}

end;

procedure D;

var n: char; {n declared in D}

begin

n:= ’D’; {n referenced in D}

W

end;

begin

n:= ’L’; {n referenced in L}

W;

D

end. 81

Page 134: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

lexical scope

• Names are associated with declarations at compile time.

• Find the smallest block syntactically enclosing the referenceand containing a declaration of the name.

• Example:• The reference to n in W is associated with the declaration of n

in L.• The output is?

• Also called static scope.

82

Page 135: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

dynamic scope

• Names are associated with declarations at run time.

• Find the most recent, currently active run-time stack framecontaining a declaration of the name.

• Example:• The reference to n in W is associated with two different

declarations at two different times.• The output is?

83

Page 136: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

scope

Lexical scope is based on the principle that consistent renaming ofvariables should not effect the value of an expression.

Lexical scope goes a long way to establishing referentialtransparency — easy to determine where variables obtain theirvalues, because program itself (unlike run-time contexts) is notchanging.

Most modern languages (including Scheme and ML) use lexicalscope, although early interpreted languages (LISP) used dynamicscope because of the flexibility and ease of implementation.

84

Page 137: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

exceptions

Many functions are partial, i.e. they are only defined for a subsetof the function’s domain type. Other values in the domain typemay be treated as exceptions: e.g., f (x) = 1/x

Exceptions are a control construct. They provide a structured formof jump to exit a construct such as a function invocation or ablock.

Terminate part of computation:

• Jump out of construct.

• Pass data as part of jump.

• Return to most recent site set up to handle exception.

• Unnecessary activation records may be deallocated (may needto free heap space, other resources).

85

Page 138: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

exceptions

Many functions are partial, i.e. they are only defined for a subsetof the function’s domain type. Other values in the domain typemay be treated as exceptions: e.g., f (x) = 1/x

Exceptions are a control construct. They provide a structured formof jump to exit a construct such as a function invocation or ablock.

Terminate part of computation:

• Jump out of construct.

• Pass data as part of jump.

• Return to most recent site set up to handle exception.

• Unnecessary activation records may be deallocated (may needto free heap space, other resources).

85

Page 139: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

exceptions

Many functions are partial, i.e. they are only defined for a subsetof the function’s domain type. Other values in the domain typemay be treated as exceptions: e.g., f (x) = 1/x

Exceptions are a control construct. They provide a structured formof jump to exit a construct such as a function invocation or ablock.

Terminate part of computation:

• Jump out of construct.

• Pass data as part of jump.

• Return to most recent site set up to handle exception.

• Unnecessary activation records may be deallocated (may needto free heap space, other resources).

85

Page 140: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

exceptions

Consider the following functions:

fun f x = 1.0 / x;

fun g x = hd x;

fun h x = tl x;

Will the type-checker complain? Is there a problem?

86

Page 141: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

SML exceptions

ML’s exceptions (similar to the ones in Java or Python) provide auniform way to handle errors, and eliminate the need for ad hoc,special exceptional return values from functions.

When encountering a special case, raise an exception. The callerwill catch/handle the exception and will take care of it.

Primitive exceptions:

3 div 0 (* raises Div *)

hd nil (* raises Empty *)

87

Page 142: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

SML user-defined exceptions

Defining an exception: exception <name> of <type>

Raising an exception: raise <name> <arg>

exception factNeg;

fun robustFact n=

let

fun fact 0 = 1

| fact n = n * fact (n-1);

in

if n < 0 then raise factNeg

else fact n

end;

robustFact 5;

(* val it = 120 : int *)

robustFact ~5;

(* uncaught exception factNeg *)88

Page 143: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

SML exceptions

Exceptions can have arguments, just like datatypes:

exception factNeg of int;

fun robustFact n=

let

fun fact 0 = 1

| fact n = n * fact (n-1);

in

if n < 0 then raise factNeg n

else fact n

end;

89

Page 144: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

SML exceptions

Handling exceptions:

<expr> handle <match1> => <expr1>

| <match2> => <expr2>

...

| <matchn> => <exprn>

Any restrictions on types?

90

Page 145: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

SML exceptions

Example:

fun printFact n =

print (Int.toString(robustFact n)^"\n")

handle factNeg x =>

print ("printFact "^(Int.toString x)^

": argument must be >= 0\n");

(* val printFact = fn : int -> unit *)

printFact ~5;

(* printFact ~5: argument must be >= 0

val it = () : unit *)

91

Page 146: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

SML exceptions

Exceptions are handled according to dynamic scoping.

exception e1 and e2 and e3;

fun h 1 = raise e1

| h 2 = raise e2

| h 3 = raise e3

| h _ = "ok";

fun g(N) = h(N)

handle e2 => "error g2"

| e3 => "error g3";

fun f(N) = g(N)

handle e1 => "error f1"

| e2 => "error f2";

f(4);

f(3);

f(2);

f(1);

f(0);

92

Page 147: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

exception handling

General dynamic scoping rule:

• Jump to most recently established handler on run-time stack.

Dynamic scoping is not an accident:

• User knows how to handler error.

• Author of library function does not.

93

Page 148: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

exceptions

Why do we need exceptions in a strongly typed language?

• Type-checker only checks types of parameters, not theirvalues.

• In languages w/o exception handling, when an exceptionoccurs, control goes to the OS and the program is terminated,or special code must be written to handle exceptions (e.g.,pass special parameter or use return value of procedure toindicate status of program, etc.)

• In contrast, with exception handling, programs can fix theproblem and continue, if desirable.

Some uses: (see examples in Mitchell 8.2)

• Error handling (when no reasonable value can be returned).• Efficiency (we don’t like this one).

Two types of exceptions in SML:

• Built-in exceptions.• User-defined exceptions.

94

Page 149: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

exceptions

Why do we need exceptions in a strongly typed language?

• Type-checker only checks types of parameters, not theirvalues.

• In languages w/o exception handling, when an exceptionoccurs, control goes to the OS and the program is terminated,or special code must be written to handle exceptions (e.g.,pass special parameter or use return value of procedure toindicate status of program, etc.)

• In contrast, with exception handling, programs can fix theproblem and continue, if desirable.

Some uses: (see examples in Mitchell 8.2)

• Error handling (when no reasonable value can be returned).• Efficiency (we don’t like this one).

Two types of exceptions in SML:

• Built-in exceptions.• User-defined exceptions.

94

Page 150: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

immutable data

• Variables (and data structures), once created and initialized,are immutable: they are never changed, updated, or storedinto.

• Powerful guarantees of noninterference.

• Build new data structures (and let the old ones be garbagecollected) instead of modifying old ones.

95

Page 151: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

references

• functional programming ⇒ no side effects

• ML separates pure expressions and side effects.

• Assignment is restricted to reference cells, which are of adifferent type.

• Assignment restrictions are enforced by the type system.

96

Page 152: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

references

Syntax:• ref v creates a reference cell with value v

• !r returns contents of reference cell r• r:=v sets contents of reference cell r to value v

val x = ref 0;

(* val x = ref 0 : int ref *)

x;

(* val it = ref 0 : int ref *)

!x;

(* val it = 0 : int *)

x:=3;

(* val it = () : unit *)

x;

(* val it = ref 3 : int ref *)

!x;

(* val it = 3 : int *)97

Page 153: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

references

• The type of a reference cell that contains value v of type α isα ref.

• Assignment to a reference cell must be consistent with thetype of the reference cell

Example:

val x = ref "cscc24";

(* val x = ref "cscc24" : string ref *)

x:=0;

(* Error: operator and operand don’t agree

operator domain: string ref * string

operand: string ref * int

in expression:

x := 0

*)

98

Page 154: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

references

(* absLst = fn : int ref list -> unit *)

fun absLst [] = ()

| absLst (x::rest) = (x:=abs(!x); absLst rest);

val L = [ref ~1, ref 0, ref ~2];

(* val L = [ref ~1,ref 0,ref ~2] : int ref list*)

absLst L;

(* val it = () : unit *)

L;

(* val it = [ref 1,ref 0,ref 2] : int ref list *)

99

Page 155: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

references

(* absLst = fn : int list -> int list *)

fun absLst [] = []

| absLst (x::rest) = (abs x)::(absLst rest);

fun absLst lst = map abs lst;

val L = [~1, 0, ~2];

(* val L = [~1,0,~2] : int list *)

absLst L;

(* val it = [1,0,2] : int list *)

L;

(* val it = [~1,0,~2] : int list *)

100

Page 156: CSCC24 Functional Programming Typing, Scope, Exceptions MLcmacleod/teaching/ml.pdftyping Bene ts of having a type system: Easier to debug programs: compiler can catch many errors

ML

• functional

• type safe

• static type checking

• type inference

• polymorphic

• abstract data types

• exception handling

• static scope

• formal definition

• garbage collection

• immutable data types

• updatable references

101