CSE-321 Programming Languages Introduction to Functional Programming

Slides:



Advertisements
Similar presentations
More ML Compiling Techniques David Walker. Today More data structures lists More functions More modules.
Advertisements

Programming with Lists
Modern Programming Languages, 2nd ed.
ML Lists.1 Standard ML Lists. ML Lists.2 Lists  A list is a finite sequence of elements. [3,5,9] ["a", "list" ] []  Elements may appear more than once.
A First Look at ML.
A Third Look At ML 1. Outline More pattern matching Function values and anonymous functions Higher-order functions and currying Predefined higher-order.
Type Checking, Inference, & Elaboration CS153: Compilers Greg Morrisett.
F28PL1 Programming Languages Lecture 14: Standard ML 4.
CMSC 330: Organization of Programming Languages Tuples, Types, Conditionals and Recursion or “How many different OCaml topics can we cover in a single.
ML Lists.1 Standard ML Lists. ML Lists.2 Lists  A list is a finite sequence of elements. [3,5,9] ["a", "list" ] []  ML lists are immutable.  Elements.
ML Datatypes.1 Standard ML Data types. ML Datatypes.2 Concrete Datatypes  The datatype declaration creates new types  These are concrete data types,
CSE 3341/655; Part 4 55 A functional program: Collection of functions A function just computes and returns a value No side-effects In fact: No program.
Getting started with ML ML is a functional programming language. ML is statically typed: The types of literals, values, expressions and functions in a.
Functional Programming. Pure Functional Programming Computation is largely performed by applying functions to values. The value of an expression depends.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
Chapter 3 Functional Programming. Outline Introduction to functional programming Scheme: an untyped functional programming language.
Chapter ElevenModern Programming Languages1 A Fourth Look At ML.
A Fourth Look At ML Chapter ElevenModern Programming Languages, 2nd ed.1.
Introduction to ML – Part 1 Frances Spalding. Assignment 1 chive/fall05/cos441/assignments/a1.ht m
5/11/2015IT 3271 Types in ML (Ch 11) datatype bool = true | false; datatype 'element list = nil | :: of 'element * 'element list n Predefined, but not.
Introduction to ML – Part 1 Kenny Zhu. Assignment 2 chive/fall07/cos441/assignments/a2.ht m
Functional Design and Programming Lecture 1: Functional modeling, design and programming.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
Introduction to ML - Part 2 Kenny Zhu. What is next? ML has a rich set of structured values Tuples: (17, true, “stuff”) Records: {name = “george”, age.
Introduction to ML Last time: Basics: integers, Booleans, tuples,... simple functions introduction to data types This time, we continue writing an evaluator.
CSE 341 Lecture 6 exceptions; higher order functions; map, filter, reduce Ullman 5.2, 5.4 slides created by Marty Stepp
CS 2104 : Prog. Lang. Concepts. Functional Programming I Lecturer : Dr. Abhik Roychoudhury School of Computing From Dr. Khoo Siau Cheng’s lecture notes.
CS235 Languages and Automata Department of Computer Science Wellesley College Introduction to Standard ML Wednesday, September 23, 2009 Reading: Beginning.
ML Datatypes.1 Standard ML Data types. ML Datatypes.2 Concrete Datatypes  The datatype declaration creates new types  These are concrete data types,
CSE-321 Programming Languages Introduction to Functional Programming (Part II) POSTECH March 13, 2006 박성우.
Patterns in OCaml functions. Formal vs. actual parameters Here's a function definition (in C): –int add (int x, int y) { return x + y; } –x and y are.
Introduction to Functional Programming and ML CS 331 Principles of Programming Languages.
CSC 580 – Theory of Programming Languages, Spring, 2009 Week 9: Functional Languages ML and Haskell, Dr. Dale E. Parson.
Chapter 9: Functional Programming in a Typed Language.
Functional Programming With examples in F#. Pure Functional Programming Functional programming involves evaluating expressions rather than executing commands.
Cs7120 (prasad)L7-TDEF1 Type Definitions. cs7120 (prasad)L7-TDEF2 Concrete Types Primitive types ( int, bool, char, string, etc ) Type constructors (
A Second Look At ML 1. Outline Patterns Local variable definitions A sorting example 2.
F28PL1 Programming Languages Lecture 13: Standard ML 3.
A Third Look At ML Chapter NineModern Programming Languages, 2nd ed.1.
CSE-321 Programming Languages Introduction to Functional Programming POSTECH March 7, 2007 박성우.
Error Example - 65/4; ! Toplevel input: ! 65/4; ! ^^ ! Type clash: expression of type ! int ! cannot have type ! real.
Introduction to Functional Programming
Chapter SevenModern Programming Languages1 A Second Look At ML.
1 FP Foundations, Scheme In Text: Chapter Chapter 14: FP Foundations, Scheme Mathematical Functions Def: A mathematical function is a mapping of.
Haskell Chapter 5, Part II. Topics  Review/More Higher Order Functions  Lambda functions  Folds.
CSE-321 Programming Languages Introduction to Functional Programming POSTECH March 8, 2006 박성우.
CSE-321 Programming Languages Introduction to Functional Programming POSTECH 박성우.
Functional Programming
Functional Programming
Type Checking and Type Inference
Functional Programming
Principles of programming languages 12: Functional programming
Types CSCE 314 Spring 2016.
ML: a quasi-functional language with strong typing
Haskell Chapter 2.
A lightening tour in 45 minutes
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
FP Foundations, Scheme In Text: Chapter 14.
PROGRAMMING IN HASKELL
Agenda SML Docs First-Class Functions Examples Standard Basis
Agenda SML Docs First-Class Functions Examples Standard Basis
CSE 341 Section 5 Winter 2018.
CSE-321 Programming Languages Introduction to Functional Programming
Haskell Types, Classes, and Functions, Currying, and Polymorphism
CSE 341 Section 3 Nick Mooney Spring 2017.
CSE-321 Programming Languages Introduction to Functional Programming
Announcements Quiz 5 HW6 due October 23
PROGRAMMING IN HASKELL
Presentation transcript:

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#, …

Functional Language SML Standard ML ML = Meta-Language An example of programming language whose design is based on the programming language theory type theory Programming language for your assignments

Designer of SML

Familiar?

WTH?

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

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:

Functional Language SML 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: what is the value if x <> 1?

Expression Evaluation An expression “evaluates” to a value. We “evaluate” an expression to obtain a value.

Integer Evaluation 1 + 1 2 1 - 1 1 * 1 1 …

Boolean Evaluation 1 = 1 true 1 <> 1 false 1 <> 0 true …

An Integer Expression if 1 = ~1 then 10 else ~10 if false then 10 else ~10 ~10

Values as Expressions 1 ???

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

Variable Declaration - val x = 1 + 1; val x = 2 : int A variable x is “bound” to value 2. From now on, any occurrence of x is replaced by 2. - val y = x + x; val y = 4 : int

Local Declaration let val x = 1 val y = x + x val z = y + y in z + z end 8

Nested Local Declaration let val x = 1 in x + x end let val y = <expression> in y + y end let val y = let val x = 1 in x + x end in y + y end

Why “Local”? let val y = let val x = 1 in x + x end x + y okay???

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 SML <> variables in C

Then Why Variables? Any advantage in using variables at all? let val x = 1 val y = x + x val z = y + y in z + z end ((1 + 1) + (1 + 1)) + ((1 + 1) + (1 + 1)) VS. What if it takes 10 hours to evaluate 1?

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

When is the first time you learned the concept of function?

즐거운 낱말 공부 시간 함수(函數): 두 변수 x, y간에 어떤 관계가 있어 x의 변화에 따라 y가 일정한 법칙으로 변화할 때 y를 x의 함수라 함. (function) (동아 마스타 국어사전)

函 즐거운 한자 공부 시간 1. 함(함). 2. 편지(함) 3. 갑옷(함) 4. 넣을, 들일(함) 예: (書函) 서함: 책을 넣는 상자

Function = 函數 = Box Number!

Using a Box Number

Using a Box Number - Generalized … …

Function in SML = Box Number (fn x => x + 1) n =

Function Application (fn x => x + 1) n … (fn x => x + 1) n We “apply” (fn x => x + 1) to n. x is called a formal argument/parameter. n is called an actual argument/parameter.

Evaluating a Function Application … (fn x => x + 1) n n + 1

Functions in SML Nameless function fn x => x + 1; Storing a nameless function to a variable val incr = fn x => x + 1; Function declaration fun incr x = x + 1;

Function Applications incr 1 (fn x => x + 1) 1 1 + 1 2

First-Class Stamps

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 …

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!

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.

Box Number as Output … … such that

Box Number as Output x … +x …

Box Number as Output x y y+x

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

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

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

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.

(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

Box Number as Input ( true, false)

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

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

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

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

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

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;

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

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

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

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

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

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

But why is it f : bool -> int ?

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

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> ? …

So we need Polymorphism.

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.

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

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

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'

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! *)

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

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

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!

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 45 + 10 f 10 55 evaluation

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

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

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

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!

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)

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

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?

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

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

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

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

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

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

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

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 *)

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

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?

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

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

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

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

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

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

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

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

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];

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

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 ... + ¢ + ¢ + ¢ + ¢ +  ... ¢

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.

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

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

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

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 = s1 @ 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

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 = s1 @ 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 = s1 @ s2 end - Set.singleton 1 = [1]; (* Error! *)

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