cs 2104 : prog. lang. concepts. functional programming i lecturer : dr. abhik roychoudhury school of...

41
CS 2104 : Prog. Lang. Concepts. Functional Programming I Lecturer : Dr. Abhik Roychoudhury School of Computing From Dr. Khoo Siau Cheng’s lecture notes

Upload: edwin-barton

Post on 25-Dec-2015

226 views

Category:

Documents


0 download

TRANSCRIPT

CS 2104 : Prog. Lang. Concepts.

Functional Programming I

Lecturer : Dr. Abhik Roychoudhury

School of ComputingFrom Dr. Khoo Siau Cheng’s lecture notes

Outline

• What is Functional Programming?• Basic Expressions• Using Higher-order Functions• List Processing• Value and Type Constructions

Features of Functional Programming

• Expressions: The main construct in the language• Functions : First-class citizens of the language• Types : for specification and verification• List Processing

Computation

• Achieved via function application• Functions are mathematical functions without

side-effects.– Output is solely dependent of input.

Pure function

States

Impure function

with assignment

Outline

• What is Functional Programming?• Basic Expressions• Using Higher-order Functions• List Processing• Value and Type Constructions

Basic SML Expressions

<Exp> ::= <Constants> | <Identifiers> | <Exp1> <op> <Exp2> | | if <Exp0> then <Exp1> else <Exp2> | let {<Decl>} in <Exp> end | fn <Pattern> {<Pattern>} => <Exp> | <Exp1> <Exp2> | (<Exp1>, <Exp2> {, <Exp3>}) | <List-Exp><Constants> ::= all constants<Identifiers> ::= all identifiers<op> ::= all binary operators

If-expression, Not If-statement

if <e0> then <e1> else <e2>

if (3 > 0) then 4+x else x-4 ;

4+x

If-expression evaluates to a value.

Constructing a Linear List

<List-Exp> ::=[[<Exp> {, <Exp>}] ]| nil | <Exp> :: <Exp>

nil ; 1::nil ; 1::(2::nil);(x+2)::(y-3)::(x*3)::nil ;

Note : A list must end with nil.

Constructing a Linear List

[] ; [1] ; [1,2]; [x+2,y-3,x*3] ;

<List-Exp> ::=[[<Exp> {, <Exp>}] ]| nil | <Exp> :: <Exp>

nil ; 1::nil ; 1::(2::nil);(x+2)::(y-3)::(x*3)::nil ;

Operator :: is right associative.

head

tail

Constructing a Tuple

(1,2) ;

(1,2,True,4,False) ;

(x+2,y=3,x*3) ;

(<Exp> , <Exp> {, <Exp>})

Tuple is like a record without field names.

Giving An Expression A Name

Declaring an expression with a name enables easy reference.

val x = 3 ; val (y,z) = (x+3,x-3) ; val [a,b] = [x+2,y-3] ;

<decl> ::= val <pattern> = <exp>

Identifiers are legally declared after proper pattern matching.

val [a,b] = [x+2] ;

val (x::xs) = [1,2,3,4,5] ;

Pattern-Match a List

val (x::xs) = [1,2,3,4,5] ;

x 1xs [2,3,4,5] ;

val (x::_::y::xs) = [1,2,3,4,5] ;

x 1y 3xs [4,5] ;

Local Declaration/Definition

let {<decl>} in <exp> end

let val x = (3,4) val (a,b) = xin a + a * b end ;

15

Identifiers are statically scoped

Nested bindings of same var.

• Let val x =2 in let val x = x +1 in x*x end end

• Let val x = 2 in let val y = x +1 in y * y end end

• Let val x = 2 in (x+1)*(x+1) end

• 9

Function Declaration and Function Application

fun fac x = if (x > 0) then x * (fac (x-1)) else 1

<Decl> ::= fun <var> <para> = <exp><para> ::= <pattern> {<pattern>}

fac 2 if (2 > 0) then 2 * (fac (2-1)) else 1 2 * (fac 1) 2 * (if (1 > 0) then 1 * (fac (1-1)) else 1) 2 * (1 * (fac 0)) 2 * (1 * 1) 2

Function as EquationsA function can be defined by a set of equations.

fun fac 0 = 1| fac n = n * (fac (n-1))

<Decl> ::= fun <var> <para> = <exp> {| <var> <para> = <exp>}

fac 2 2 * (fac (2-1)) 2 * (fac 1) 2 * (1 * (fac (1-1))) 2 * (1 * (fac 0)) 2 * (1 * 1) 2

Function application is accomplished via pattern matching.

Outline

• What is Functional Programming?• Basic Expressions• Using Higher-order Functions• List Processing• Value and Type Constructions

Functions as First-Class Citizens

Lambda abstraction: A nameless functionfn <para> => <Exp>

(fn (x,y) => x + y) (2,3) 2+3 5 Definition Application

val newfn = fn (x,y) => x + y ;

newfn(2,4) + newfn(4,3)

Functions as First-Class Citizens

Passing function as argumentfun apply (f, x) = f x

apply (fac, 3) fac 3 6

apply (fn x => x*2, 3) (fn x => x*2) 3 3*2 6

Functions as First-Class Citizens

Returning function as resultfun choose (x,f,g) = if x then f else g ;

fun compose (f,g) = fn x => f (g x)

choose(a = b,fn x => x*2, fac)(4)

returns either 8 or 24

(compose (add3,fac)) 4

(fn x => add3 (fac x))(4) (add3 (fac 4)) 27

compose (f,g) is denoted as f o g

Functions as First-Class Citizens

Storing function in data structure

val flist = [ fac, fib, add3] ;

let val [f1,f2,f3] = flistin (f1 2) + (f2 3) + (f3 4)end ;

Functions as Algorithms

• A function describes a way for computation.• Self-Recursive function

fun factorial (x) = if (x <= 1) then 1 else x * factorial (x-1) ;

• Mutual-Recursive functionsfun even(0) = true | even(1) = false| even(x) = odd(x-1)and odd(x) = even(x-1) ;

Passing Arguments to a Function

How many argument does this function really take?

fun f (x,y) = x + 2 * y ;

a pair

fun g x y = x + 2 * y ;

pattern 1 pattern 2

Calling f with argument (1,2) yields 5.

Calling g with arguments 1 and 2 yields 5.

Outline

• What is Functional Programming?• Basic Expressions• Using Higher-order Functions• List Processing• Value and Type Constructions

Exploring a List

fun length [] = 0| length (x::xs) = 1 + length(xs) ;

length([10,10,10]) ==> 1 + length([10,10]) ==> 1 + 1 + length([10]) ==> 1 + 1 + 1 + length([]) ==> 1 + 1 + 1 + 0 ==> 3

Note how a list is being consumed from head to tail.

fun append([],ys) = ys| append(x::xs,ys) = x :: append(xs,ys);

append([1,2],[3]) ==> 1::append([2],[3])==> 1::2::append([],[3])==> 1::2::[3]==> [1,2,3]

Note how a new list is being produced from head to tail.

append(x,y) is denoted by x @ y.

fun rev(xs) = let fun r([],ys) = ys | r(x::xs,ys)= r(xs,x::ys)in r(xs,[])end

rev([1,2,3]) ==> r([1,2,3],[])==> r([2,3],1::[])==> r([3],2::1::[])==> r([],3::2::1::[])==> [3,2,1]

Note how lists are being produced and consumed concurrently.

Map operation

map square [1,2,3,4] ==> [square 1, square 2,.., square 4]==> [1,4,9,16]

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

(f x) :: (map f xs)

map square [1,2] ==> (square 1) :: (map square [2])==> 1 :: (square 2) :: (map square [])==> 1 :: 4 :: []== [1,4]

Map operation

Law for Map :

map f (map g list) = map (f o g) list

map f (map g [a1,..,an])= map f [g a1,..,g an]= [f (g a1),.., f (g an)]= [(f o g) a1,.., (f o g) an]= map (f o g) [a1,..an]

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

(f x) :: (map f xs)

Reduce Operation

reduce [a1,..,an] a0 = a1 (a2 (.. (an a0)))

reduce f [a1,..,an] a0 =f(a1,f(a2,f(..,f(an,a0))))

:

a1 :

a2 :

:

an []

a1

a2

an a0

reduce (op *) [2,4,6] 1 ==> 2 * (4 * (6 * 1))==> 48

reduce (fn (x,y)=>1+y) [2,4,6] 0 ==> 1 + (1 + (1 + 0))==> 3

[]

:

2 :

4 :

6

+

1 +

1 +

1 0

Outline

• What is Functional Programming?• Basic Expressions• Using Higher-order Functions• List Processing• Value and Type Constructions

Types: Classification of Values and

Their Operators

Type Values Operationsbool true,false =, <>, …int …,~1,0,1,2,… =,<>,<,+,div,…real ..,0.0,.,3.14,.. =,<>,<,+,/,…string “foo”,”\”q\””,… =,<>,…

Basic Types

Boolean Operations: e1 andalso e2 e1 orelse e2

Types in ML

• Every expression used in a program must be well-typed.– It is typable by the ML Type system.

• Declaring a type :3 : int

[1,2] : int list

• Usually, there is no need to declare the type in your program – ML infers it for you.

Structured TypesStructured Types consist of structured values.

• Structured values are built up through expressions. Eg : (2+3, square 3)• Structured types are denoted by type expressions.

<type-expr> ::= <type-name> | <type-constant> | <type-expr> * <type-expr>

| <type-expr> <type-expr> | <type-expr> list

| …

Type of a Tuple

A * B = set of ordered pairs (a,b)

Data Constructor : ( , ) as in (a,b)Type Constructor : * as in A * B

In general,(a1,a2,…,an) belongs to A1*A2*…*An.

(1,2) : int * int(3.14159, x+3,true) : real * int * bool

Type of A List

[1,2,3] : int list [3.14, 2.414] : real list[1, true, 3.14] : ??

Type Constructor : list

A in A-list refers to any types:(int*int) list : [ ], [(1,3)], [(3,3),(2,1)], …int list list : [ ], [[1,2]], [[1],[0,1,2],[2,3],…

A list = set of all lists of A -typed values.

Not well-typed!!

fac : int -> int

Function TypesDeclaring domain & co-

domain

Type Constructor : ->Data Construction via :1. Function declaration : fun f x = x + 1 ;2. Lambda abstraction : fn x => x + 1;

Value Selection via function application:f 3 4

(fn x => x + 1) 3 4

A -> B = set of all functions from A to B.

datatype Days = Mo | Tu | We | Th | Fr | Sa | Su ;

Selecting a summand via pattern matching:case d of Sa => “Go to cinema” | Su => “Extra Curriculum” | _ => “Life goes on”

Sum of Types Enumerated Types

New Type data / data constructors

Defining an integer binary tree:datatype IntTree = Leaf int |

Node of (IntTree, int, IntTree) ;

fun height (Leaf x) = 0 | height (Node(t1,n,t2))=

1 + max(height(t1),height(t2)) ;

Combining Sum and Product of Types:

Algebraic Data Types

Conclusion

• A functional program consists of an expression, not a sequence of statements.

• Higher-order functions are first-class citizen in the language.– It can be nameless

• List processing is convenient and expressive• In ML, every expression must be well-typed.• Algebraic data types empowers the language.