CS5205Haskell1 CS5205: Foundation in Programming Languages Basics of Functional Programming.

Slides:



Advertisements
Similar presentations
1 Programming Languages (CS 550) Lecture Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
Advertisements

Chapter 11 Proof by Induction. Induction and Recursion Two sides of the same coin.  Induction usually starts with small things, and then generalizes.
Comp 205: Comparative Programming Languages Higher-Order Functions Functions of functions Higher-order functions on lists Reuse Lecture notes, exercises,
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
Algorithms + L. Grewe.
CSE341: Programming Languages Lecture 6 Tail Recursion, Accumulators, Exceptions Dan Grossman Fall 2011.
Functional Design and Programming Lecture 1: Functional modeling, design and programming.
0 PROGRAMMING IN HASKELL Chapter 7 - Higher-Order Functions.
Cse536 Functional Programming Lecture #14, Nov. 10, 2004 Programming with Streams –Infinite lists v.s. Streams –Normal order evaluation –Recursive streams.
Recursive Algorithms Nelson Padua-Perez Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
Chapter 5 Polymorphic and Higher-Order Functions.
7/2/20151 Programming Languages and Compilers (CS 421) Elsa L Gunter 2112 SC, UIUC Based in part on slides by Mattox.
Cs776 (Prasad)L15strm1 Reasoning with Functional Programs Optimization by source to source transformation Well-founded induction Streams : Infinite lists.
Functional Programming Professor Yihjia Tsai Tamkang University.
CHAPTER 10 Recursion. 2 Recursive Thinking Recursion is a programming technique in which a method can call itself to solve a problem A recursive definition.
Recursion. Basic problem solving technique is to divide a problem into smaller subproblems These subproblems may also be divided into smaller subproblems.
PrasadCS7761 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language.
CHAPTER 02 Recursion Compiled by: Dr. Mohammad Omar Alhawarat.
Functional Programming Universitatea Politehnica Bucuresti Adina Magda Florea
Stephen P. Carl - CS 2421 Recursion Reading : Chapter 4.
0 REVIEW OF HASKELL A lightening tour in 45 minutes.
CS 363 Comparative Programming Languages Semantics.
Chapter Fifteen: Functional Programming Languages Lesson 12.
CSC 221: Recursion. Recursion: Definition Function that solves a problem by relying on itself to compute the correct solution for a smaller version of.
Data Structures R e c u r s i o n. Recursive Thinking Recursion is a problem-solving approach that can be used to generate simple solutions to certain.
Propositional Calculus CS 270: Mathematical Foundations of Computer Science Jeremy Johnson.
CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language.
TIVDM2Functional Programming Language Concepts 1 Concepts from Functional Programming Languages Peter Gorm Larsen.
Chapter 3 Part II Describing Syntax and Semantics.
Lee CSCE 314 TAMU 1 CSCE 314 Programming Languages Haskell: Higher-order Functions Dr. Hyunyoung Lee.
CMSC 330: Organization of Programming Languages Maps and Folds Anonymous Functions.
1/32 This Lecture Substitution model An example using the substitution model Designing recursive procedures Designing iterative procedures Proving that.
CMSC 330: Organization of Programming Languages Operational Semantics a.k.a. “WTF is Project 4, Part 3?”
First Order Haskell Neil Mitchell York University λ.
CSE 130 : Spring 2011 Programming Languages Ranjit Jhala UC San Diego Lecture 6: Higher-Order Functions.
Recursion A recursive definition is one which uses the word or concept being defined in the definition itself Example: “A computer is a machine.
0 PROGRAMMING IN HASKELL Based on lecture notes by Graham Hutton The book “Learn You a Haskell for Great Good” (and a few other sources) Odds and Ends,
CMSC 330: Organization of Programming Languages Operational Semantics.
3/8/20161 Programming Languages and Compilers (CS 421) Reza Zamani Based in part on slides by Mattox Beckman, as updated.
Haskell Chapter 5, Part II. Topics  Review/More Higher Order Functions  Lambda functions  Folds.
Cs7120 (Prasad)L1-FP-HOF1 Functional Programming Basics Correctness > Clarity > Efficiency.
Fusion Catherine Hope and Graham Hutton University of Nottingham in Less Space.
1 Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson.
Functional Programming
Higher-Order Programming: Iterative computation (CTM Section 3
Recursion.
Programming Languages and Compilers (CS 421)
A lightening tour in 45 minutes
Higher-Order Programming: Iterative computation (CTM Section 3
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
Closures and Streams cs784(Prasad) L11Clos
Programming Languages and Compilers (CS 421)
Recursive Thinking Chapter 9 introduces the technique of recursive programming. As you have seen, recursive programming involves spotting smaller occurrences.
Introduction to Functional Programming in Racket
Recursive Thinking Chapter 9 introduces the technique of recursive programming. As you have seen, recursive programming involves spotting smaller occurrences.
Important Concepts from Clojure
Proving Properties of Recursive List Functions
Important Concepts from Clojure
Propositional Calculus: Boolean Algebra and Simplification
Recursion Chapter 11.
Higher Order Functions
Higher-Order Programming: Closures, procedural abstraction, genericity, instantiation, embedding. Control abstractions: iterate, map, reduce, fold, filter.
Higher Order Functions
Introduction to Functional Programming in Racket
Important Concepts from Clojure
PROGRAMMING IN HASKELL
Review Previously in: Lots of language features: functions, lists, records, tuples, variants, pattern matching Today: No new language features New idioms.
Presentation transcript:

CS5205Haskell1 CS5205: Foundation in Programming Languages Basics of Functional Programming.

CS5205Haskell2 Topics Topics Higher-Order Functions Formal Reasoning Abstraction vs Efficiency Bridging the Divide

CS5205Haskell3 Function Abstraction Function Abstraction Function abstraction is the ability to convert any expression into a function that is evaluated at a later time. Normal Execution time p = \ () ->  Expr  p () Delayed Execution time

CS5205Haskell4 Higher-Order Functions Higher-Order Functions Higher-order programming treats functions as first-class, allowing them to be passed as parameters, returned as results or stored into data structures. This concept supports generic coding, and allows programming to be carried out at a more abstract level. Genericity can be applied to a function by letting specific operation/value in the function body to become parameters.

CS5205Haskell5 Genericity Genericity Replace specific entities (0 and +) by parameters. sumList ls = case ls of [] -> 0 x:xs -> x+(sumList xs) foldr f u ls = case ls of [] -> u x:xs -> f x (foldr f u xs)

CS5205Haskell6 Polymorphic, Higher-Order Types Polymorphic, Higher-Order Types sumList :: [Int] -> Int sumList :: Num a => [a] -> a foldr :: (a -> b -> b) -> b -> [a] -> b

CS5205Haskell7 Instantiating Generic Functions Instantiating Generic Functions sumL2 :: Num a => [a] -> a sumL2 ls = foldr (+) 0 ls sumL2 [1, 2, 3] ) sumL2 [1.1, 3, 2.3] )

CS5205Haskell8 Instantiating Generic Functions Instantiating Generic Functions prodL :: Num a => [a] -> a prodL ls = foldr (*) 1 ls prodL [1, 2, 5] ) prodL [1.1, 3, 2.3] )

CS5205Haskell9 Instantiating Generic Functions Instantiating Generic Functions map :: (a -> b) -> [a] -> [b] map f [] = [] map f (x:xs)= (f x) : (map f xs) map f xs = foldr … … … xs Can you express map in terms of foldr ?

CS5205Haskell10 Instantiating Generic Functions Instantiating Generic Functions filter :: (a -> Bool) -> [a] -> [a] filter f [] = [] filter f (x:xs) = if (f x) then x : (filter f xs) else filter f xs Filtering a list of elements with a predicate. filter f xs = foldr … … … xs Can we express filter in terms of foldr ?

CS5205Haskell11 Pipe/Compose Pipe/Compose compose :: (b -> c) -> (a -> b) -> a -> c compose f g = \ x -> f (g x) g | f= compose f g cmd1 | cmd2 Similar to Unix pipe command:

CS5205Haskell12 Iterator Construct Iterator Construct for :: Int -> Int -> (Int -> a -> a) -> a -> a for i j f a = if i>j then a else for (i+1) j (f i a) for :: Num b, Ord b => b -> b -> (b -> a -> a) -> a -> a In Haskell, type class help give a more generic type:

CS5205Haskell13 Right Folding Right Folding foldr f u [x1,x2,..,xn]  f x1 (foldr f u [x2..xn])  f x1 (f x2 (fold f u [x3..xn]))  f x1 (f x2 (… (fold f u [xn]) …))  f x1 (f x2 (… (f xn u) …))) associate to right

CS5205Haskell14 Left Folding – Tail Recursion Left Folding – Tail Recursion Accumulate result in a parameter: foldl f u ls = case ls of [] -> u x:xs -> foldl f (f u x) xs What is the type of foldl ? Can we compute factorial using it? based on accumulation

CS5205Haskell15 Left Folding Left Folding foldl f u [x1,x2,..,xn]  foldl f (f u x1) [x2..xn]  foldl f (f (f u x1) x2) [x3..xn]))  foldl f (f … (f (f u x1) x2)… xn) []  f (… (f (f u x1) x2) …) xn left is here!

CS5205Haskell16 Instance of Left Folding Instance of Left Folding Summing a list by accumulation. sumT acc ls = case ls of [] -> 0 x:xs -> sumT (x+acc) xs sumList ls = sumT 0 ls sumT acc ls = foldl (+) acc ls

CS5205Haskell17 Referential Transparency Referential Transparency An expression is referentially transparent if it can always be replaced by an equivalent expression with the same value and effect. Allows reasoning based on components. Useful for: simplifying algorithm proving correctness optimization + parallelization Pure functions are referentially transparent, as relied on in mathematical reasoning.

CS5205Haskell18 Equivalence Proof Equivalence Proof Can we Prove : sumList xs = sumT 0 xs. Generalise : (sumList xs)+a = sumT a xs. By Induction Case : x=[] (sumList [])+a = sumT a [] 0+a= a Case : x=x:xs (sumList x:xs)+a = sumT a (x:xs) x+(sumList xs)+a = sumT (x+a) xs (sumList xs)+(x+a) = sumT (x+a) xs // apply induction hypothesis

CS5205Haskell19 List Reversal List Reversal Concatenate first element to last position. rev [] = [] rev (x:xs) = rev xs ++ [x] rev xs = foldr … … … What is the time complexity?

CS5205Haskell20 Time Complexity Time Complexity CAssume : C(xs++ys) = length xs Steps Derive :Steps(rev(xs)) Case [] : StepsSteps Steps(rev([])) = 1+Steps([]) = 1+0 Case x:xs : Steps Steps(rev(x:xs)) Steps = 1+Steps(rev(xs)++[a]) CSteps = 1+C(rev(xs)++_)+Steps(rev(xs)) Steps = 1+length(rev(xs)+Steps(rev(xs)) Steps = 1+length(xs)+Steps(rev(xs)) CThus : C(rev(xs)) = (length xs)^2

CS5205Haskell21 Iterative List Reversal Iterative List Reversal Concatenate first element to last position. revT w [] = w revT w (x:xs) = revT (x:w) xs Same as: revT w xs = foldl (\ w x -> x:w) w xs What is the time complexity?

CS5205Haskell22 Time Complexity Time Complexity Steps Derive Steps(revT w xs) Case [] : StepsSteps Steps(revT w []) = 1+Steps(w) = 1+0 Case x:xs : Steps Steps(revT w (x:xs)) Steps = 1+Steps(revT (x:w) xs) Steps = 1+Steps(revT _ xs) CThus : C(revT w xs) = (length xs)

CS5205Haskell23 Abstraction vs Efficiency Abstraction vs Efficiency Abstraction  helps with programmers’ productivity Efficiency  helps machine execution. Tension between abstraction and efficiency Abstract program stress on ‘what’ rather than ‘how’ typically uses simpler (maybe naïve) algorithm Efficient program optimised implementation use of clever programming techniques

CS5205Haskell24 Bridging the Divide Bridging the Divide Abstract Code/Specs Efficient Code or Implementation transform or synthesize verify

CS5205Haskell25 Unfold/Fold Transformation Unfold/Fold Transformation DEFINE - new function definition UNFOLD – replace a call by its body FOLD – replace an expression matching the RHS of a definition by its corresponding call INSTANTIATE – provide special cases of a given equation. ABSTRACT – introduce a tuple of expressions LAW – application of valid lemma, e.g. associativity

CS5205Haskell26 Fusion Transformation Fusion Transformation Consider: …sum (double xs)… sum []= 0 sum x:xs = x+(sum xs) double [] = [] double x:xs = 2*x : (double xs) Computation reuses smaller functions to build larger ones but may result in unnecessary intermediate structures. They can cause space overheads. Solution : Fuse the code together!

CS5205Haskell27 Fusion Transformation Fusion Transformation Define: sumdb xs = sum (double xs) Instantiate: xs=[] sumdb [] = sum (double []) = sum [] = 0 Instantiate: xs=x:xs sumdb x:xs = sum (double x:xs) = sum (2*x : double xs) = 2*x + sum(double xs) = 2*x + (sumdb xs)

CS5205Haskell28 Iteration Transformation Define: sumdbT a xs = a+(sumdb xs) Instantiate: xs=[] sumdbT a [] = a+(sumdb []) = a Instantiate: xs=x:xs sumdbT a (x:xs) = a+(sumdb x:xs) = a+(2*x + sumdb xs) = (a+2*x) + (sumdb xs) = sumdbT (a+2*x) xs

CS5205Haskell29 Laziness vs Strictness Laziness vs Strictness Laziness increase expressiveness, allowing infinite data structures, by not evaluating each subexpression until it is really needed. However, there is a performance penalty (both space and time), as the suspended computation has to be stored as a closure and then invoked subsequently. If you always need some of the parameters, we might as well evaluate their corresponding arguments first. Question : When is an argument to a function needed (strict)? Using ? to denote non-termination. f … ? … = ?

CS5205Haskell30 Strictness Transformation Strictness Transformation Can analyse that accumulating argument of sumdb is strict. We can force strictness using the `seq` operator. sumdbT a []= a sumdbT a (x:xs) = sumdbT (a+2*x) xs sumdbT a []= a sumdbT a (x:xs) = let p = a+2*x in p `seq` sumdbT p xs

CS5205Haskell31 Tupling Transformation Average of a List : average xs = sum xs / length xs Define : both xs = (sum xs, length xs ) Instantiate : both [] = (sum [], length [] ) = (0,0) Instantiate : both x:xs = (sum x:xs, length x:xs ) = (x+sum xs, 1+length xs) = let (u,v)= (sum xs,length xs) in (x+u, 1+v) = let (u,v)= both xs in u/v

CS5205Haskell32 Naive Fibonacci Naive Fibonacci Natural but inefficient version of fibonacci : fib 0 = 1 fib 1 = 1 fib n = (fib n-1)+(fib n-2) Time complexity is exponential time due to presence of redundant calls.

CS5205Haskell33 A Call Tree of fib fib 6 fib 5 fib 4 fib 3 fib 2 fib 3fib 2 fib 1fib 2fib 1 Many repeated calls!

CS5205Haskell34 A Call Graph of fib fib 6 fib 5 fib 4 fib 3 fib 2 fib 1 No repeated call through reuse of identical calls

CS5205Haskell35 Tupling - Computing Two Results Compute two calls from next two calls in hierarchy: ((fib n), (fib n-1)) ((fib n-1), (fib n-2))

CS5205Haskell36 Tupling Fibonacci Define : fibtup n = (fib n+1, fib n ) Instantiate : fibtup 0 = (fib 1, fib 0 ) = (1,1) Instantiate : fibtup n+1 = (fib n+2, fib n+1 ) = ((fib n+1)+(fib n), fib n+1) = let (u,v)= (fib n+1, fib n) in (u+v, u) = let (u,v)= fibtup n in (u+v, u)

CS5205Haskell37 Using the Tupled Function fib 0 = 1 fib 1 = 1 fib n = fib n-1 + fib n-2 = let (u,v) = (fib n-1,fib n-2) in u+v = let (u,v) = fibtup (n-2) in u+v

CS5205Haskell38 Linear Recursion fib 6 fib 5 fib 4 fib 3 fib 2 fib 1 fibtup 0 = (1,1) fibtup (n+1) = let (u,v)= fibtup n in (u+v,u)

CS5205Haskell39 To Iteration fib 6 fib 5 fib 4 fib 3 fib 2 fib 1 fibT 0 u v = (u,v) fibT (n+1) u v = fibT n (u+v,u)

CS5205Haskell40 Optimization Optimization Should be done only if critical. Should be automated where possible, for e,g. as part of compilation. Manual optimization by human should preferably be carefully checked or verified