Presentation is loading. Please wait.

Presentation is loading. Please wait.

CSE-321 Programming Languages Introduction to Functional Programming

Similar presentations


Presentation on theme: "CSE-321 Programming Languages Introduction to Functional Programming"— Presentation transcript:

1 CSE-321 Programming Languages Introduction to Functional Programming
박성우 POSTECH March 10, 2009

2 First-Class Stamps

3 First-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

4 First-class Objects in C
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!

5 Functions = First-class Objects in SML
can be passed as an argument to a function. can be returned as a return value of a function.

6 Box Number as Output such that

7 Box Number as Output x +x

8 Box Number as Output x y y+x

9 Box Number as Output x y fn y => y+x y+x

10 Box Number as Output x y fn y => y+x y+x fn y => y+x

11 Box Number as Output x y y+x fn x => (fn y => y+x)

12 In SML Recall the following declarations are equivalent:
val incr = fn x => x + 1; fun incr x = x + 1; Then: val add = fn x => (fn y => y + x); fun add x = fn y => y + x; fun add x y = y + x; add takes only one argument, not two! In fact, every function in SML takes only one argument.

13 (fn x => (fn y => y + x)) 1 2
Adding Two Integers add 1 2 (fn x => (fn y => y + x)) 1 2 (fn y => y + 1) 2 2 + 1 3

14 Box Number as Input ( true, false)

15 Box Number as Input f fn f => (f true, f false) ( f true, f false)

16 Outline Expressions and values V Variables V Functions V Types
Recursion Datatypes Pattern matching Higher-order functions Exceptions Modules

17 Types A type specifies what kind of value a given expression evaluates to. 1 + 1 : int true andalso false : bool #”A” : char ”hello” : string (1, true) : int * bool (1, ~1, true) : int * int * bool 1.0 : real () : unit

18 Type Preservation Expression : T
Value : T An evaluation preserves the type of a given expression.

19 Example let val x = 1 val y = x + x val z = y + y in z + z end : int

20 Function Types T -> T’ type of functions:
taking arguments of type T returning values of type T’ Example: val incr = fn x => x + 1; val incr = fn : int -> int fun incr x = x + 1; val incr = fn : int -> int Explicit type annotation val incr = fn (x:int) => x + 1; val incr = fn (x:int) : int => x + 1; fun incr (x:int) = x + 1; fun incr (x:int) : int = x + 1;

21 Type of add x fn y => y+x fn x => (fn y => y+x)

22 Type of add int fn x => (fn y => y+x) fn y => y+x

23 Type of add int fn x => (fn y => y+x) int -> int

24 Type of add int int -> (int -> int) int -> int

25 What is the Type? f fn f => (f true, f false) ( f true, f false)

26 f : bool -> int ? ( true, false) f : (bool -> int) ->
int * int fn f => (f true, f false) ( f true, f false)

27 But why is it f : bool -> int ?

28 Why not f : bool -> char ?
char * char fn f => (f true, f false) ( f true, f false)

29 f : bool -> int * string ? f : bool -> unit ?
Then why not f : bool -> string ? f : bool -> int * string ? f : bool -> unit ? f : bool -> (int -> int) ? f : bool -> <crazy type> ?

30 So we need Polymorphism.

31 What is the Type of ? true, false) ( fn f => (f true, f false) f
All we know about f is that it takes booleans as arguments.

32 All we know about f is that it takes booleans as arguments.
?

33 f : bool -> ? fn f => (f true, f false) : (bool -> ?) -> ? * ?

34 f : bool -> 'a fn f => (f true, f false) : (bool -> 'a) -> 'a * 'a 'a type variable usually read as alpha means 'for any type alpha'

35 Polymorphic Types Types involving type variables 'a, 'b, 'c, ... E.g.
fn x => x : 'a -> 'a fn x => fn y => (x, y) : 'a -> 'b -> ('a * 'b) fn (x : 'a) => fn (y : 'a) => x = y : 'a -> 'a -> bool (* actually does not typecheck! *)

36 Equality Types Motivation Equality (=) is not defined on every type.
E.g. comparing two functions for equality? Type variables with equality ''a, ''b, ''c, ... ''a means 'for any type alpha for which equality is defined' fn (x : ''a) => fn (y : ''a) => x = y : ''a -> ''a -> bool

37 Outline Expressions and values V Variables V Functions V Types V
Recursion Datatypes Pattern matching Higher-order functions Exceptions Modules

38 Recursion vs. Iteration
Recursion in SML fun sum n = if n = 0 then 0 else sum (n - 1) + n Iteration in C int i, sum; for (i = 0, sum = 0; i <= n; i++) sum += n; Recursion is not an awkward tool if you are used to functional programming. Recursion seems elegant but inefficient!

39 Recursion in Action fun sum n = if n = 0 then 0 else sum (n - 1) + n
call stack f 0 0 + 1 further computation f 1 1 + 2 ... ... f 8 36 + 9 f 9 f 10 55 evaluation

40 Funny Recursion fun zero n = if n = 0 then 0 else zero (n - 1)
call stack f 10 f 9 f 8 ... f 1 f 0 no further computation evaluation

41 Funny Recursion Optimized
fun zero n = if n = 0 then 0 else zero (n - 1) call stack f 0 f 1 ... ... f 8 f 9 f 10 evaluation

42 Funny Recursion Further Optimized
fun zero n = if n = 0 then 0 else zero (n - 1) call stack f 10 f 9 f 8 ... f 1 f 0 evaluation

43 Tail 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!

44 Example Non-tail recursive sum
fun sum n = if n = 0 then 0 else sum (n - 1) + n Tail recursive sum fun sum' accum k = if k = 0 then accum else sum' (accum + k) (k - 1) fun sum n = sum' 0 n Think about the invariant of sum: given: sum' accum k invariant: accum = n + (n - 1) (k + 1)

45 Outline Expressions and values V Variables V Functions V Types V
Recursion V Datatypes Pattern matching Higher-order functions Exceptions Modules

46 Enumeration 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?

47 Datatypes in SML datatype shape = Circle | Rectangle | Triangle
No flexibility e.g. Circle (x) Triangle - 1 (x) Circle + Triangle (x) But high safety.

48 Set datatype set = Empty | Many - Empty; val it = Empty : set - Many;
val it = Many : set

49 Set with Arguments datatype set = Empty | Many of int - Many 5;
val it = Many 5 : set

50 Set with Type Parameters
datatype 'a set = Empty | Singleton of 'a | Pair of 'a * 'a - Singleton 0; val it = Singleton 0 : int set - Pair (0, 1); val it = Pair (0, 1) : int set

51 Set with Type Parameters
datatype 'a set = Empty | Singleton of 'a | Pair of 'a * 'a - Pair (Singleton 0, Pair (0, 1)) val it = Pair (Singleton 0, Pair (0, 1)) : int set set

52 Set with Type Parameters
datatype 'a set = Empty | Singleton of 'a | Pair of 'a * 'a - Pair (0, true); stdIn: Error: operator and operand don't agree [literal] operator domain: int * int operand: int * bool in expression: Pair (0,true)

53 Recursive Set with Type Parameters
datatype 'a set = Empty | NonEmpty of 'a * 'a set This is essentially the definition of datatype list.

54 Datatype list datatype 'a list = nil | :: of 'a * 'a list - nil;
val it = [] : 'a list - 2 :: nil; (* :: infix *) val it = [2] : int list - 1 :: (2 :: nil); val it = [1,2] : int list - 1 :: 2 :: nil; (* :: right associative *)

55 Datatype list datatype 'a list = nil | :: of 'a * 'a list
val it = [[1],[2]] : int list list - [1] :: [[2]]; (X) (X)

56 Using 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?

57 Outline Expressions and values V Variables V Functions V Types V
Recursion V Datatypes V Pattern matching Higher-order functions Exceptions Modules

58 Simple Pattern datatype shape = Circle | Rectangle | Triangle
(* convertToEnum : shape -> int *) fun convertToEnum (x : shape) : int = case x of Circle => 0 | Rectangle => 1 | Triangle => 2

59 Pattern with Arguments
datatype set = Empty | Many of int fun size (x : set) : int = case x of Empty => 0 | Many n => n

60 Wildcard Pattern _ : "don't care"
datatype 'a set = Empty | Singleton of 'a | Pair of 'a * 'a fun isEmpty (x : 'a set) : bool = case x of Empty => true | _ => false

61 Pattern with Type Annotation
datatype 'a list = nil | :: of 'a * 'a list fun length (x : 'a list) : int = case x of (nil : 'a list) => 0 | (_ : 'a) :: (tail : 'a list) => 1 + length tail

62 Outline Expressions and values V Variables V Functions V Types V
Recursion V Datatypes V Pattern matching V Higher-order functions Exceptions Modules

63 Higher-order Functions
Take functions as arguments. Return functions as the result.

64 Why "Higher-order"? T0 ::= int | bool | real | unit | ...
T1 ::= T0 -> T0 | T (* 1st order *) T2 ::= T1 -> T1 | T1 (* 2nd order *) T3 ::= T2 -> T2 | T (* higher order *) ...

65 Higher-order Functions in List
val exists : ('a -> bool) -> 'a list -> bool val all : ('a -> bool) -> 'a list -> bool val map : ('a -> 'b) -> 'a list -> 'b list val filter : ('a -> bool) -> 'a list -> 'a list val app : ('a -> unit) -> 'a list -> unit (* printInt : int -> unit *) fun printInt i = TextIO.print ((Int.toString i) ^ "\n" ); List.app printInt [1, 2, 3];

66 List Fold Function foldl : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b foldr : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b foldl f b0 [a0, a1, a2, ..., an-1] a0 a1 a2 an-2 an-1 ... f b1 f b2 f b3 f bn-1 f bn b0 ... bn-2

67 Summation fun sum (l : int list) =
List.foldl (fn (a, accum) => a + accum) 0 l foldl op+ 0 [a0, a1, a2, ..., an-1] op+ a0 a1 a2 an-2 an-1 ... + + + + + ...

68 List Reversal fun reverse (l : 'a list) =
List.foldl (fn (a, rev) => a :: rev) nil l List.foldl op:: nil l Whenever you need iterations over lists, first consider foldl and foldr.

69 More Examples List.exists f l =
List.foldl (fn (a, b) => b orelse f a) false l List.all f l = List.foldl (fn (a, b) => b andalso f a) true l List.app f l = List.foldl (fn (a, _) => f a) () l List.map f l = List.foldr (fn (a, b) => f a :: b) nil l List.filter f l = List.foldr (fn (a, b) => if f a then a :: b else b) nil l

70 Outline Expressions and values V Variables V Functions V Types V
Recursion V Datatypes V Pattern matching V Higher-order functions V Exceptions exception: please see the course notes. Modules

71 Outline Expressions and values V Variables V Functions V Types V
Recursion V Datatypes V Pattern matching V Higher-order functions V Exceptions V Modules

72 Structures and Signatures
collection of type declarations, exceptions, values, and so on. structure Set = struct type 'a set = 'a list val emptySet = nil fun singleton x = [x] fun union s1 s2 = s2 end Signature conceptually type of structures. signature SET = sig type 'a set val emptySet : 'a set val singleton : 'a -> 'a set val union : 'a set -> 'a set -> 'a set end

73 Structures + Signatures
Transparent constraint Type definition is exported to the outside. structure Set : SET = struct type 'a set = 'a list val emptySet = nil fun singleton x = [x] fun union s1 s2 = s2 end - Set.singleton 1 = [1]; val it = true : bool Opaque constraint No type definition is exported. structure Set :> SET = struct type 'a set = 'a list val emptySet = nil fun singleton x = [x] fun union s1 s2 = s2 end - Set.singleton 1 = [1]; (* Error! *)

74 Functors Functions on structures takes a structure as an argument
returns a structure as the result structure structure

75 Make-up Lectures March 2009 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7


Download ppt "CSE-321 Programming Languages Introduction to Functional Programming"

Similar presentations


Ads by Google