Title: Introduction to Functional Programming
1Introduction to Functional Programming
Programming Languages
???
- Kangwon National University
These slides were originally created by Prof.
Sungwoo Park at POSTECH.
2Programming Paradigms
- Paradigm In science, a paradigm describes
distinct concepts or thought patterns in some
scientific discipline. - Main programming paradigms
- Imperative programming C, Pascal,
- Logic programming Prolog,
- Functional programming SML, Haskell, OCaml,
Lisp, Scheme, F, - Orthogonal concept
- Object-oriented programming C, Java, OCaml,
3Outline
- Expressions and values
- Variables
- Functions
- Types
- Recursion
- Datatypes
- Pattern matching
- Higher-order functions
- Exceptions
- Modules
4Imperative Language C
- A program consists of commands.
- command do something
- Nothing wrong
- if (x 1) then
- x x 1
- else
- x x - 1
- Nothing wrong either
- if (x 1) then
- x x 1
5Functional Language OCaml
- A program consists of expressions.
- expression obtain a value
- Nothing wrong
- if (x 1) then
- x 1
- else
- x - 1
- But this does not make sense
- if (x 1) then
- x 1
- what is the value if x ltgt 1?
6Evaluation
Expression
Value
- An expression evaluates to a value.
- We evaluate an expression to obtain a value.
7Integer Evaluation
1 1
2
1 - 1
0
1 1
1
8Boolean Evaluation
1 1
true
1 ltgt 1
false
1 ltgt 0
true
9An Integer Expression
if 1 -1 then 10 else -10
if false then 10 else -10
-10
10Values as Expressions
1
???
11Everything is an Expression!
if 1 -1 then 10 else -10
- 1
- -1
- 1 -1
- 10
- -10
- if 1 -1 then 10 else -10
12Actually Not Everything
if 1 -1 then 10 else -10
- Ill-formed expressions
- if 1 -1 then 10 (x)
- if 1 1 then 10 else -10 (x)
13Outline
- Expressions and values V
- Variables
- Functions
- Types
- Recursion
- Datatypes
- Pattern matching
- Higher-order functions
- Exceptions
- Modules
14Variable Declaration
- - let x 1 1
- val x int 2
- A variable x is bound to value 2.
- From now on, any occurrence of x is replaced by
2. - - let y x x
- val y int 4
15Local Declaration
let x 1 in let y x x in let z y y in z
z
8
16Nested Local Declaration
let x 1 in x x
let y ltexpressiongt in y y
let y let x 1 in x x in y y
17Why Local?
let y let x 1 in x x
in x y
okay???
18Variables are NOT variable.
- The contents of a variable never change.
- immutability of variables
- Surprise?
- Thats because you are thinking about variables
in imperative programming. - variables in OCaml ltgt variables in C
19Then Why Variables?
- Any advantage in using variables at all?
let x 1 in let y x x in let z y y in z
z
((1 1) (1 1)) ((1 1) (1 1))
VS.
What if it takes 10 hours to evaluate 1?
20Outline
- Expressions and values V
- Variables V
- Functions
- Types
- Recursion
- Datatypes
- Pattern matching
- Higher-order functions
- Exceptions
- Modules
21- When is the first time you learned the concept of
function?
22??? ?? ??
- ?? function, ?? ?? x? y ??? x? ?? ???? ??? y??
????? ??? ?? ?, y? x? ???? ??. - (????)
23?? ?
- ?
- 1. ?(?).
- 2. ??(?)
- 3. ??(?)
- 4. ??, ??(?)
- ?
- (??) ?? ?? ?? ??
24Function ?? Box Number!
25Using a Box Number
26Using a Box Number - Generalized
27Function in OCaml Box Number
fun x -gt x 1
28Function Application
(fun x -gt x 1)n
- We apply (fun x -gt x 1) to n.
- x is called a formal argument/parameter.
- n is called an actual argument/parameter.
29Evaluating a Function Application
(fun x -gt x 1)n
n 1
30Functions in OCaml
- Nameless function
- fun x -gt x 1
- Storing a nameless function to a variable
- let incr fun x -gt x 1
- Function declaration
- let incr x x 1
31Function Applications
incr 1
(fun x -gt x 1) 1
1 1
2
32First-Class Stamps
33First-Class Objects
- First-class objects primitive objects
- can be stored in a variable.
- can be passed as an argument to a function.
- can be returned as a return value of a function.
- Examples
- integers
- booleans
- characters
- floating-point numbers
34First-Class Objects in C
- First-class objects
- integers
- characters
- floating-point numbers
- pointers
- structures
-
- Functions?
- Function pointers are first-class objects.
- But functions are not.
- Why? You cannot create new functions on the fly!
35Functions First-Class Objects in OCaml
- Functions
- can be passed as an argument to a function.
- can be returned as a return value of a function.
36Box Number as Output
such that
37Box Number as Output
x
x
38Box Number as Output
x
y
yx
39Box Number as Output
x
y
fun y -gt yx
yx
40Box Number as Output
x
y
fun y -gt yx
yx
fun y -gt yx
41Box Number as Output
x
y
fun x -gt (fun y -gt yx)
fun y -gt yx
yx
fun y -gt yx
42In OCaml
- Recall the following declarations are equivalent
- let incr fun x -gt x 1
- let incr x x 1
- Then
- let add fun x -gt (fun y -gt y x)
- let add x fun y -gt y x
- let add x y y x
- add can take a single argument to return a
function.
43Adding Two Integers
add 1 2
(fun x -gt (fun y -gt y x)) 1 2
(fun y -gt y 1) 2
2 1
3
44Box Number as Input
true,
false)
(
45Box Number as Input
f
fun f -gt (f true, f false)
true,
false)
(
f
f
46Outline
- Expressions and values V
- Variables V
- Functions V
- Types
- Recursion
- Datatypes
- Pattern matching
- Higher-order functions
- Exceptions
- Modules
47Types
- A type specifies what kind of value a given
expression evaluates to. - 1 1 int
- true false bool
- A char
- hello string
- (1, true) int bool
- (1, -1, true) int int bool
- 1.0 float
- () unit
48Type Preservation
Expression T
Value T
- An evaluation preserves the type of a given
expression.
49Example
let x 1 in let y x x in let z y y in z
z
int
8 int
50Function Types
- T -gt T
- type of functions
- taking arguments of type T
- returning values of type T
- Example
- let incr fun x -gt x 1
- val incr int -gt int ltfungt
- let incr x x 1
- val incr int -gt int ltfungt
- Explicit type annotation
- let incr fun (xint) -gt x 1
- val incr int -gt int ltfungt
- let incr (xint) x 1
- val incr int -gt int ltfungt
51Type of add
52Type of add
int
fun x -gt (fun y -gt yx)
fun y -gt yx
53Type of add
int
fun x -gt (fun y -gt yx)
int -gt int
54Type of add
int
int -gt (int -gt int)
int -gt int
55What is the Type?
f
fun f -gt(f true,f false)
true,
false)
(
f
f
56f bool -gt int ?
f
(bool -gt int) -gt int int
fun f -gt(f true,f false)
true,
false)
(
f
f
57But why is it f bool -gt int ?
58Why not f bool -gt char ?
f
(bool -gt char) -gt char char
fun f -gt(f true,f false)
true,
false)
(
f
f
59Then why not f bool -gt string ? f bool -gt
int string ? f bool -gt unit ? f bool -gt
(int -gt int) ? f bool -gt ltcrazy typegt ?
60So We Need Polymorphism
- Poly many
- Morphism forms/shapes
- Polymorphic function a function that can be
applied to values of different types - E.g., C templates, Java generics
61What is the Type of ?
All we know about f is that it takes booleans
as arguments.
62All we know about f is that it takes booleans
as arguments.
bool
?
63f bool -gt ?
fun f -gt (f true, f false) (bool -gt ?)
-gt ? ?
64f bool -gt 'a
fun f -gt (f true, f false) (bool -gt 'a) -gt
'a 'a
- 'a
- type variable
- usually read as alpha
- means 'for any type alpha'
65Polymorphic Types
- Types involving type variables 'a, 'b, ...
- E.g.
- fun x -gt x
- 'a -gt 'a
- fun x -gt fun y -gt (x, y)
- 'a -gt 'b -gt ('a 'b)
- fun (x 'a) -gt fun (y 'a) -gt x y
- 'a -gt 'a -gt bool
66Outline
- Expressions and values V
- Variables V
- Functions V
- Types V
- Recursion
- Datatypes
- Pattern matching
- Higher-order functions
- Exceptions
- Modules
67Recursion vs. Iteration
- Recursion in OCaml
- let rec sum n if n 0 then 0else sum (n - 1)
n
- Iteration in C
- int i 0, sum 0for ( i lt n i) sum
i
- Recursion is not an awkward tool if you are used
to functional programming. - Recursion seems elegant but inefficient!
68Recursion in Action
- let rec sum n if n 0 then 0else sum (n - 1)
n
call stack
0
further computation
...
...
f 10
evaluation
69Funny Recursion
- let rec zero n if n 0 then 0else zero (n - 1)
call stack
no further computation
evaluation
70Funny Recursion Optimized
let rec zero n if n 0 then 0else zero (n - 1)
call stack
0
0
...
...
f 10
evaluation
71Funny Recursion Further Optimized
let rec zero n if n 0 then 0else zero (n - 1)
call stack
f 10
...
0
evaluation
72Tail Recursive Function
- A tail recursive function f
- A recursive call to f is the last step in
evaluating the function body. - That is, no more computation remains after
calling f itself. - A tail recursive call needs no stack!
- A tail recursive call is as efficient as
iteration!
73Example
- Tail recursive sum
- let rec sum' accum k if k 0 then accumelse
- sum' (accum k) (k - 1)
- let sum n sum' 0 n
- Non-tail recursive sum
- let rec sum n if n 0 then 0else sum (n - 1)
n
- Think about the invariant of sum'
- given
- sum' accum k
- invariant
- accum n (n - 1) ... (k 1)
74Outline
- Expressions and values V
- Variables V
- Functions V
- Types V
- Recursion V
- Datatypes
- Pattern matching
- Higher-order functions
- Exceptions
- Modules
75Enumeration Types in C
- enum shape Circle, Rectangle, Triangle
- Great flexibility
- e.g.
- Circle 1 Rectangle
- Triangle - 1 Rectangle
- (Circle Triangle) / 2 Rectangle
- But is this good or bad?
76Datatypes in OCaml
- type shape Circle Rectangle Triangle
- No flexibility
- e.g.
- Circle 1 (x)
- Triangle - 1 (x)
- Circle Triangle (x)
- But high safety.
77Set
- type set
- Empty
- Many
- Empty
- - set Empty
- Many
- - set Many
78Set with Arguments
- type set
- Empty
- Many of int
- Many 5
- - set Many 5
79Set with Type Parameters
- type 'a set
- Empty
- Singleton of 'a
- Pair of 'a 'a
-
- Singleton 0
- - int set Singleton 0
- Pair (0, 1)
- - int set Pair (0, 1)
80Set with Type Parameters
- type 'a set
- Empty
- Singleton of 'a
- Pair of 'a 'a
-
- Pair (Singleton 0, Pair (0, 1))
- - int set set Pair (Singleton 0, Pair (0,
1))
81Set with Type Parameters
- type 'a set
- Empty
- Singleton of 'a
- Pair of 'a 'a
-
- Pair (0, true)
82Set with Type Parameters
- type 'a set
- Empty
- Singleton of 'a
- Pair of 'a 'a
-
- Pair (0, true)
- Error This expression has type bool but an
expression was expected of type int
83Recursive Set with Type Parameters
- type 'a set
- Empty
- NonEmpty of 'a 'a set
- This is essentially the definition of datatype
list.
84Datatype list
- type 'a list
- ( defined internally )
- of 'a 'a list ( infix )
-
- - 'a list
- 2 ( infix )
- - int list 2
- 2
- - int list 2
- 1 2
- - int list 1 2
- 1 2 ( right associative )
- int list 1 2
- 1 (2 )
- - int list 1 2
85Datatype list
- type 'a list
- ( defined internally )
- of 'a 'a list ( infix )
- 1 2
- 1 2
- 1 2
- - int list list 1 2
- 1 2
- - int list list 1 2
(X)
(X)
86Using Datatypes
- We know how to create values of various
datatypes - shape
- set
- int set
- int list
- ...
- But how do we use them in programming?
- What is the point of creating datatype values
that are never used?
87Outline
- Expressions and values V
- Variables V
- Functions V
- Types V
- Recursion V
- Datatypes V
- Pattern matching
- Higher-order functions
- Exceptions
- Modules
88Simple Pattern
- type shape Circle Rectangle Triangle
- ( convertToEnum shape -gt int )
- let convertToEnum (x shape) int
- match x with
- Circle -gt 0
- Rectangle -gt 1
- Triangle -gt 2
89Pattern with Arguments
- type set
- Empty
- Many of int
- let size (x set) int
- match x with
- Empty -gt 0
- Many n -gt n
90Wildcard Pattern _ "don't care"
- type 'a set
- Empty
- Singleton of 'a
- Pair of 'a 'a
- let isEmpty (x 'a set) bool
- match x with
- Empty -gt true
- _ -gt false
91Pattern with Type Annotation
- type 'a list
- ( defined internally )
- of 'a 'a list ( infix )
- let rec length (x 'a list) int
- match x with
- ( 'a list) -gt 0
- (_ 'a) (tail 'a list) -gt
- 1 length tail
92Outline
- Expressions and values V
- Variables V
- Functions V
- Types V
- Recursion V
- Datatypes V
- Pattern matching V
- Higher-order functions
- Exceptions
- Modules
93Higher-order Functions
- Take functions as arguments.
- Return functions as the result.
94Why "Higher-order"?
- T0 int bool float unit ...
- T1 T0 -gt T0 T0 ( 1st order )
- T2 T1 -gt T1 T1 ( 2nd order )
- T3 T2 -gt T2 T2 ( higher order )
- ...
95Higher-Order Functions in List
- val exists ('a -gt bool) -gt 'a list -gt bool
- val for_all ('a -gt bool) -gt 'a list -gt bool
- val map ('a -gt 'b) -gt 'a list -gt 'b list
- val filter ('a -gt bool) -gt 'a list -gt 'a list
- val iter ('a -gt unit) -gt 'a list -gt unit
- ( print_int int -gt unit )
- let print_int i
- print_string ((string_of_int i) "\n" )
- List.iter print_int 1 2 3
96List Fold Function - Left
- fold_left ('a -gt 'b -gt 'a) -gt 'a -gt 'b list -gt
'a -
- fold_left f a0 b0 b1 b2 ... bn-1
current result
current element
new result
initial result
elements
final result
...
a0
an-2
...
97List Fold Function - Right
- fold_right (b -gt a -gt a) -gt b list -gt a -gt
a - fold_right f b0 b1 b2 ... bn-1 an
current result
current element
new result
initial result
elements
final result
b2
b0
b1
bn-1
bn-2
...
an
98Summation
- let sum (l int list)
- List.fold_left (fun accum a -gt a accum) 0 l
- fold_left () 0 a0 a1 a2 ... an-1
()
a0
a1
an-1
a2
an-2
...
0
...
99List Reversal
- let reverse (l 'a list)
- List.fold_left (fun rev a -gt a rev) l
- Whenever you need iterations over lists, first
consider fold_left and fold_right.
100More Examples
- let exists f l
- List.fold_left (fun a b -gt a f b) false l
- let for_all f l
- List.fold_left (fun a b -gt a f b) true l
- let map f l
- List.fold_right (fun a b -gt f a b) l
- let filter f l
- List.fold_right (fun a b -gt if f a then a b
else b) l
101Outline
- Expressions and values V
- Variables V
- Functions V
- Types V
- Recursion V
- Datatypes V
- Pattern matching V
- Higher-order functions V
- Exceptions
- Modules
102Exception
- To signal and handle exceptional conditions
- Non-local control structures (e.g., goto in C)
- Exception declaration
- exception Empty_list
- exception Empty_list
- Exceptions are used throughout the standard
library to signal cases where the library
functions cannot complete normally.
103Signaling the exception
- With the raise operator
- e.g., a function for taking the head of a list
- let head l
- match l with
- -gt raise Empty_list
- hd tl -gt hd
- val head 'a list -gt 'a ltfungt
- head 12
- - int 1
- head
- Exception Empty_list
104Catching the exception
- Exceptions can be trapped with the try with
construct. - The with part is a regular pattern-matching on
the exception value. - let print_head_list l
- try print_string (head l \n)
- with Empty_list -gt print_string Empty_list\n
- val print_head_list string list -gt unit ltfungt
- print_head_list abc, def
- abc
- - unit ()
- print_head_list
- Empty_list
- - unit ()
105Outline
- Expressions and values V
- Variables V
- Functions V
- Types V
- Recursion V
- Datatypes V
- Pattern matching V
- Higher-order functions V
- Exceptions V
- Modules
106Structures and Signatures
- Structure
- collection of type declarations, exceptions,
values, and so on. - Structures a program and provides a new namespace
- module Set
- struct
- type 'a set 'a list
- let empty_set
- let singleton x x
- let union s1 s2 s1 _at_ s2
- end
- Signature
- conceptually type of structures.
- module type SET
- sig
- type 'a set
- val empty_set 'a set
- val singleton 'a -gt 'a set
- val union
- 'a set -gt 'a set -gt 'a set
- end
107Transparent Constraints
- Type definition is exported to the outside.
- module Set
- struct
- type 'a set 'a list
- let empty_set
- let singleton x x
- let union s1 s2 s1 _at_ s2
- end
- Set.singleton 1 1
- - bool true
108If youre a library developer
- What if you later improve your implementation
using a binary search tree instead of a list? - module Set ( your library code )
- struct
- type 'a set 'a bst
- let empty_set ...
- let singleton x ...
- ...
- End
- ( library users code )
- Set.singleton 1 1
- Error This expression has type 'a list but an
expression was expected of type int bst
109Opaque Constraints
- module Set SET
- struct
- type 'a set 'a list
- let empty_set
- let singleton x x
- let union s1 s2 s1 _at_ s2
- end
- Set.singleton 1 1
- Error This expression has type int list but an
expression was expected of type int Set.set
- module type SET
- sig
- type 'a set
- val empty_set 'a set
- val singleton 'a -gt 'a set
- val union
- 'a set -gt 'a set -gt 'a set
- end
- No type definition is exported (Information
hiding)
110Overriding Opaque Constraints
- Use the with keyword.
- Furthermore, only definitions specified in the
signature are exported to outside.
- module Set
- SET with
- type 'a set 'a list
- struct
- type 'a set 'a list
- let empty_set
- let temp x x
- let singleton x temp x
- let union s1 s2 s1 _at_ s2
- end
- Set.singleton 1 1
- - bool true
- module type SET
- sig
- type 'a set
- val empty_set 'a set
- val singleton 'a -gt 'a set
- val union
- 'a set -gt 'a set -gt 'a set
- end
111Functors
- Functions on structures
- takes a structure as an argument
- returns a structure as the result
- The most powerful tool for structuring programs
structure
structure
112Code Reuse by Functors
Variation points (Set elements)
Int
String
Float
User defined type
Reusable code (Set operations)
Functors
Set for user defined type
Int Set
String Set
Float Set
Functor applications (Set implementations)
113Generic Set Functor
- Code reuse using a functor
- Ex. Different set implementations w.r.t. the type
of set elements - type comparison LESS Equal Greater
- module type ORDERED sig
- type t
- val compare t -gt t -gt comparison
- end
- module Set
- functor (Elt ORDERED) -gt (
functor declaration ) - struct
- type elem Elt.t
- type set elem list
- let empty
- ...
- end
- module OrderedString struct type t string
... end - module StringSet Set(OrderedString) (
functor application ) - module OrderedADT struct type t
user_defined_t ... end
114For more information on OCaml, visithttp//caml
.inria.fr/pub/docs/manual-ocaml/index.htmlhttps
//realworldocaml.org/http//ocaml.org
115Reading Assignment
- Notes on Programming Languages 1?, 2? ??
- If youre comfortable with English, Read
POSTECH PL Course Note Chapters 1-2