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
Scala (programming language) wikipedia , lookup
Anonymous function wikipedia , lookup
Curry–Howard correspondence wikipedia , lookup
Lambda calculus definition wikipedia , lookup
Falcon (programming language) wikipedia , lookup
Closure (computer programming) wikipedia , lookup
Lambda lifting wikipedia , lookup
Intuitionistic type theory wikipedia , lookup
Programming Languages Introduction to Functional Programming 임현승 Kangwon National University These slides were originally created by Prof. Sungwoo Park at POSTECH. Programming 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, … 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 y : int = 4 14 Local Declaration let let let z + x = 1 in y = x + x in z = y + y in z 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 okay??? in 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 let let z + x = 1 in y = x + x in z = y + y in 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 함수의 사전 정의 • 함수 [function, 函數]: 변수 x와 y 사이에 x의 값이 정해지면 따라서 y값이 정해진다는 관계가 있을 때, y는 x의 함수라고 한다. (두산백과) 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 = 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 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 let let z + x = 1 in y = x + x in z = y + y in 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 val incr : # let incr val incr : = fun x -> x + 1;; int -> int = <fun> x = x + 1;; int -> int = <fun> • Explicit type annotation # let incr = fun (x:int) -> x + 1;; val incr : 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) fun 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 • Poly = many • Morphism = forms/shapes • Polymorphic function = a function that can be applied to values of different types • E.g., C++ templates, Java generics 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, ... • 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 • Iteration in C let rec sum n = if n = 0 then 0 else sum (n - 1) + n int i = 0, sum = 0; for (; i <= n; i++) sum += i; • 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 • Tail recursive sum let rec sum n = if n = 0 then 0 else sum (n - 1) + n 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 (x) Triangle - 1 (x) Circle + Triangle (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 = [] | (* defined internally *) :: of 'a * 'a list (* infix *) # # # # - 1 :: [2] :: [];; (X) [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 = [] | (* defined internally *) :: of 'a * 'a list (* 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 ::= int | bool | float | unit | ... • T1 ::= T0 -> T0 | T0 (* 1st order *) • T2 ::= T1 -> T1 | T1 (* 2nd order *) • T3 ::= T2 -> T2 | T2 (* 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 bn-1 a2 f a3... an-2 f 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 bn-1 a2 f a3... an-2 f an-1 f an 97 Summation let sum (l : int list) = (+)-> a + accum) 0 l List.fold_left (fun accum a • 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 Modules 101 Exception • 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. 102 Signaling the exception • With the raise operator • e.g., a function for taking the head of a list # let head l = match l with [] -> raise Empty_list | hd :: tl -> hd;; val head : 'a list -> 'a = <fun> # head [1;2];; - : int = 1 # head [];; Exception: Empty_list 103 Catching 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 -> print_string “Empty_list\n” val print_head_list : string list -> unit = <fun> # print_head_list [“abc”, “def”];; abc - : unit = () # print_head_list [];; Empty_list - : unit = () 104 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 105 Structures 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] • Signature – conceptually type of structures. module type SET = sig type 'a set val empty_set : 'a set val singleton : 'a -> 'a set val union : let union s1 s2 = s1 @ s2 end 'a set -> 'a set -> 'a set end 106 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 107 If you’re 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 user’s code *) # Set.singleton 1 = [1] ;; Error: This expression has type 'a list but an expression was expected of type int bst 108 Opaque Constraints • No type definition is exported (Information hiding) module Set : SET = module type SET = struct sig type 'a set = 'a list type 'a set let empty_set = [] val empty_set : 'a set let singleton x = [x] val singleton : 'a -> 'a set let union s1 s2 = s1 @ s2 val union : end 'a set -> 'a set -> 'a set end # Set.singleton 1 = [1] ;; Error: This expression has type int list but an expression was expected of type int Set.set 109 Overriding 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 @ 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 110 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 111 Code Reuse by Functors Int String Functors Float User defined type Variation points (Set elements) Reusable code (Set operations) Int Set String Set Set for user Float Set defined type Functor applications (Set implementations) 112 Generic 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 -> t -> comparison end # module Set = functor (Elt : ORDERED) -> (* 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 # module ADTSet = Set(OrderedADT) (* functor application *) ... 113 For more information on OCaml, visit: http://caml.inria.fr/pub/docs/manual-ocaml/index.html https://realworldocaml.org/ http://ocaml.org Reading Assignment • Notes on Programming Languages 1장, 2장 읽기 • If you’re comfortable with English, Read POSTECH PL Course Note Chapters 1-2 115