Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
CSE-321 Programming Languages Introduction to Functional Programming 박성우 POSTECH Programming Paradigms • Structured programming – C, Pascal, … • Object-oriented programming – C++, Java, … • Logic programming – Prolog, … • Functional programming – SML, Haskell, Objective Caml, Lisp, Scheme, F#, … 2 Outline • • • • • • • • • • Expressions and values Variables Functions Types Recursion Datatypes Pattern matching Higher-order functions Exceptions Modules 3 Imperative 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; 4 Functional 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 <> 1? 5 Evaluation Expression Value • An expression “evaluates” to a value. • We “evaluate” an expression to obtain a value. 6 Integer Evaluation 1 + 1 2 1 - 1 0 1 * 1 1 … 7 Boolean Evaluation 1 = 1 true 1 <> 1 false 1 <> 0 true … 8 An Integer Expression if 1 = -1 then 10 else -10 if false then 10 else -10 -10 9 Values as Expressions 1 ??? 10 Outline • • • • • • • • • • Expressions and values V Variables Functions Types Recursion Datatypes Pattern matching Higher-order functions Exceptions Modules 13 Variable 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 x : int = 4 14 Local Declaration let x = 1 in let y = x + x in let x = y + y in z + z + x 8 15 Nested Local Declaration let x = 1 in x + x let y = <expression> in y + y let y = let x = 1 in x + x in y + y 16 Why “Local”? let y = let x = 1 in x + x in okay??? x + y 17 Variables are NOT variable. • The contents of a variable never change. – immutability of variables • Surprise? – That’s because you are thinking about variables in imperative programming. variables in OCaml <> variables in C 18 Then 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 VS. ((1 + 1) + (1 + 1)) + ((1 + 1) + (1 + 1)) What if it takes 10 hours to evaluate 1? 19 Outline • • • • • • • • • • Expressions and values V Variables V Functions Types Recursion Datatypes Pattern matching Higher-order functions Exceptions Modules 20 When is the first time you learned the concept of function? 21 함수의 사전 정의 • 함수(函數): 두 변수 x, y간에 어떤 관계가 있어 x의 변화에 따라 y가 일정한 법칙으로 변화할 때 y를 x의 함수라 함. (function) (동아 마스타 국어사전) 22 한자 함 •函 1. 함(함). 2. 편지(함) 3. 갑옷(함) 4. 넣을, 들일(함) 예: (書函) 서함: 책을 넣는 상자 23 Function = 函數 = Box Number! 24 Using a Box Number 25 Using a Box Number - Generalized … … 26 Function in OCaml = Box Number fun x -> x + 1 n = 27 Function Application … (fun x -> x + 1) n • We “apply” (fun x -> x + 1) to n. • x is called a formal argument/parameter. • n is called an actual argument/parameter. 28 Evaluating a Function Application … (fun x -> x + 1) n n+ 1 … 29 Functions in OCaml • Nameless function – fun x -> x + 1;; • Storing a nameless function to a variable – let incr = fun x -> x + 1;; • Function declaration – let incr x = x + 1;; 30 Function Applications incr 1 (fun x -> x + 1) 1 1 + 1 2 31 First-Class Stamps 32 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 –… 33 First-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! 34 Functions = 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. 35 Box Number as Output … … such that … … 36 Box Number as Output x … … +x 37 Box Number as Output x y y+x 38 Box Number as Output x y fun y -> y+x y+x 39 Box Number as Output x y fun y -> y+x y+x fun y -> y+x 40 Box Number as Output x y fun x -> (fun y -> y+x) fun y -> y+x y+x fun y -> y+x 41 In OCaml • Recall the following declarations are equivalent: – let incr = fun x -> x + 1;; – let incr x = x + 1;; • Then: – let add = fun x -> (fun y -> y + x); – let add x = fun y -> y + x; – let add x y = y + x; • add can take a single argument to return a function. 42 Adding Two Integers add 1 2 (fun x -> (fun y -> y + x)) 1 2 (fun y -> y + 1) 2 2 + 1 3 43 Box Number as Input ( true, false) 44 Box Number as Input f fun f -> (f true, f false) ( f true, f false) 45 Outline • • • • • • • • • • Expressions and values V Variables V Functions V Types Recursion Datatypes Pattern matching Higher-order functions Exceptions Modules 46 Types • 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 47 Type Preservation Expression : T Value : T • An evaluation preserves the type of a given expression. 48 Example let x = 1 in let y = x + x in let z = y + y in z + z : int 8 : int 49 Function Types • T -> T’ – type of functions: • taking arguments of type T • returning values of type T’ • Example: # let incr = fun val incr : int -> # let incr x = x val incr : int -> x -> x + 1;; int = <fun> + 1;; int = <fun> • Explicit type annotation # let inc = fun (x:int) -> x + 1;; val inc : int -> int = <fun> # let incr (x:int) = x + 1;; val incr : int -> int = <fun> 50 Type of add x fun x -> (fun y -> y+x) fun y -> y+x 51 Type of add int fun x -> (fun y -> y+x) fun y -> y+x 52 Type of add int fun x -> (fun y -> y+x) int -> int 53 Type of add int int -> (int -> int) int -> int 54 What is the Type? f fun f -> (f true, f false) ( f true, f false) 55 f : bool -> int ? f : (bool -> int) -> fn f => (f true, f false) int * int ( f true, f false) 56 But why is it f : bool -> int ? 57 Why not f : bool -> char ? f : (bool -> char) -> fun f -> (f true, f false) char * char ( f true, f false) 58 Then why not f : f : f : f : f : … bool bool bool bool bool -> -> -> -> -> string ? int * string ? unit ? (int -> int) ? <crazy type> ? 59 So we need Polymorphism. 60 What is the Type of f ? All we know about f is that it takes booleans as arguments. fun f -> (f true, f false) ( f true, f false) 61 All we know about f is that it takes booleans as arguments. bool f ? 62 f : bool -> ? fun f -> (f true, f false) : (bool -> ?) -> ? * ? 63 f : bool -> 'a fun f -> (f true, f false) : (bool -> 'a) -> 'a * 'a • 'a – type variable – usually read as alpha – means 'for any type alpha' 64 Polymorphic Types • Types involving type variables 'a, 'b, 'c, ... • E.g. – fun x -> x : 'a -> 'a – fun x -> fun y -> (x, y) : 'a -> 'b -> ('a * 'b) – fun (x : 'a) -> fun (y : 'a) -> x = y : 'a -> 'a -> bool 65 Outline • • • • • • • • • • Expressions and values V Variables V Functions V Types V Recursion Datatypes Pattern matching Higher-order functions Exceptions Modules 66 Recursion vs. Iteration • Recursion in OCaml let rec 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! 67 Recursion in Action let rec sum n = if n = 0 then 0 else sum (n - 1) + n call stack 0 f 0 f 1 f 9 f 10 further computation 1 + 2 ... ... f 8 0 + 1 36 + 9 45 + 10 55 evaluation 68 Funny Recursion let rec zero n = if n = 0 then 0 else zero (n - 1) call stack 0 f 0 f 1 f 9 f 10 no further computation 0 ... ... f 8 0 0 0 0 evaluation 69 Funny Recursion Optimized let rec zero n = if n = 0 then 0 else zero (n - 1) call stack 0 f 0 f 1 f 9 f 10 0 ... ... f 8 0 0 0 0 evaluation 70 Funny Recursion Further Optimized let rec zero n = if n = 0 then 0 else zero (n - 1) call stack f 10 f 9 f 8 ... f 1 f 0 0 evaluation 71 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! 72 Example • Non-tail recursive sum let rec sum n = if n = 0 then 0 else sum (n - 1) + n • Tail recursive sum let rec sum' accum k = if k = 0 then accum else sum' (accum + k) (k - 1) let sum n = sum' 0 n • Think about the invariant of sum': – given: sum' accum k – invariant: accum = n + (n - 1) + ... (k + 1) 73 Outline • • • • • • • • • • Expressions and values V Variables V Functions V Types V Recursion V Datatypes Pattern matching Higher-order functions Exceptions Modules 74 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? 75 Datatypes in OCaml type shape = Circle | Rectangle | Triangle • No flexibility – e.g. Circle + 1 Triangle - 1 Circle + Triangle (x) (x) (x) • But high safety. 76 Set type set = Empty | Many # Empty ;; - : set = Empty # Many ;; - : set = Many 77 Set with Arguments type set = Empty | Many of int # Many 5 ;; - : set = Many 5 78 Set 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) 79 Set 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)) 80 Set with Type Parameters type 'a set = Empty | Singleton of 'a | Pair of 'a * 'a # Pair (0, true);; 81 Set 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 82 Recursive Set with Type Parameters type 'a set = Empty | NonEmpty of 'a * 'a set • This is essentially the definition of datatype list. 83 Datatype list type 'a list = [] | :: of 'a * 'a list # [] ;; - : 'a list = [] # 2 :: [] ;; - : int list = [2] # [2] ;; - : int list = [2] # [1; 2] ;; - : int list = [1; 2] # 1 :: 2 :: [] ;; - : int list = [1; 2] # 1 :: (2 :: []) ;; - : int list = [1; 2] (* defined internally *) (* infix *) (* infix *) (* right associative *) 84 Datatype list type 'a list = [] | :: of 'a * 'a list (* defined internally *) (* infix *) (X) # 1 :: [2] :: [];; # [1] :: 2 :: [] ;; (X) # [1] :: [2] :: [] ;; - : int list list = [[1]; [2]] # [1] :: [[2]] ;; - : int list list = [[1]; [2]] 85 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? 86 Outline • • • • • • • • • • Expressions and values V Variables V Functions V Types V Recursion V Datatypes V Pattern matching Higher-order functions Exceptions Modules 87 Simple Pattern type shape = Circle | Rectangle | Triangle (* convertToEnum : shape -> int *) let convertToEnum (x : shape) : int = match x with Circle -> 0 | Rectangle -> 1 | Triangle -> 2 88 Pattern with Arguments type set = Empty | Many of int let size (x : set) : int = match x with Empty -> 0 | Many n -> n 89 Wildcard 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 -> true | _ -> false 90 Pattern with Type Annotation type 'a list = [] | :: of 'a * 'a list (* defined internally *) (* infix *) let rec length (x : 'a list) : int = match x with ([] : 'a list) -> 0 | (_ : 'a) :: (tail : 'a list) -> 1 + length tail 91 Outline • • • • • • • • • • Expressions and values V Variables V Functions V Types V Recursion V Datatypes V Pattern matching V Higher-order functions Exceptions Modules 92 Higher-order Functions • Take functions as arguments. • Return functions as the result. 93 Why "Higher-order"? • • • • • T0 T1 T2 T3 ... ::= ::= ::= ::= int | T0 -> T1 -> T2 -> bool T0 | T1 | T2 | | float T0 T1 T2 | (* (* (* unit | ... 1st order *) 2nd order *) higher order *) 94 Higher-order Functions in List • • • • • val val val val val exists : ('a -> bool) -> 'a list -> bool for_all : ('a -> bool) -> 'a list -> bool map : ('a -> 'b) -> 'a list -> 'b list filter : ('a -> bool) -> 'a list -> 'a list iter : ('a -> unit) -> 'a list -> unit (* print_int : int -> unit *) let print_int i = print_string ((string_of_int i) ^ "\n" );; List.iter print_int [1; 2; 3];; 95 List Fold Function - Left • fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a current result current element new result initial result elements final result • fold_left f a0 [b0; b1; b2; ...; bn-1] b0 b1 a0 f a1 f b2 ... bn-2 a2 f a3 ... an-2 f bn-1 an-1 f an 96 List Fold Function - Right • fold_right : (‘b -> ‘a -> ‘a) -> ‘b list -> ‘a -> ‘a current element current result new result elements initial result final result • fold_right f [b0; b1; b2; ...; bn-1] an b0 b1 a0 f a1 f b2 ... bn-2 a2 f a3 ... an-2 f bn-1 an-1 f an 97 Summation let sum (l : int list) = (+) a -> a + accum) 0 l List.fold_left (fun accum • fold_left (+) 0 [a0; a1; a2; ...; an-1] a0 0 + a1 ¢ + ¢ a2 ... + ¢ ... an-2 ¢ + an-1 ¢ + 98 List Reversal let reverse (l : 'a list) = List.fold_left (fun rev a -> a :: rev) [] l • Whenever you need iterations over lists, first consider fold_left and fold_right. 99 More Examples let exists f l = List.fold_left (fun a b -> a || f b) false l let for_all f l = List.fold_left (fun a b -> a && f b) true l let map f l = List.fold_right (fun a b -> f a :: b) l [] let filter f l = List.fold_right (fun a b -> if f a then a :: b else b) l [] 100 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 OCaml manual. • Modules 101 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 102 Structures and Signatures • Structure – collection of type declarations, exceptions, values, and so on. • Signature – conceptually type of structures. module Set = struct type 'a set = 'a list let empty_set = [] let singleton x = [x] let union s1 s2 = s1 @ s2 end module type SET = sig type 'a set val empty_set : 'a set val singleton : 'a -> 'a set val union : 'a set -> 'a set -> 'a set end 103 Transparent 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 @ s2 end # Set.singleton 1 = [1] ;; - : bool = true 104 Opaque Constraints • No type definition is exported. module Set : SET = struct type 'a set = 'a list let empty_set = [] let singleton x = [x] let union s1 s2 = s1 @ s2 end module type SET = sig type 'a set val empty_set : 'a set val singleton : 'a -> 'a set val union : 'a set -> 'a set -> 'a set end # Set.singleton 1 = [1] ;; Error: This expression has type 'a list but an expression was expected of type int Set.set 105 Overriding Opaque Constraints • Use the with keyword. 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 @ s2 end module type SET = sig type 'a set val empty_set : 'a set val singleton : 'a -> 'a set val union : 'a set -> 'a set -> 'a set end # Set.singleton 1 = [1] ;; - : bool = true 106 Functors • Functions on structures – takes a structure as an argument – returns a structure as the result structure structure • The most powerful tool for structuring programs • See Assignment #3. 107 For more information on OCAML, visit: http://caml.inria.fr/pub/docs/manual-ocaml-4.01/ https://realworldocaml.org/