cs5205: foundation in programming languages
DESCRIPTION
CS5205: Foundation in Programming Languages. Basics of Functional Programming. Topics. Higher-Order Functions Formal Reasoning Abstraction vs Efficiency Bridging the Divide. Function Abstraction. - PowerPoint PPT PresentationTRANSCRIPT
CS5205 Haskell 1
CS5205: Foundation in Programming Languages
Basics ofFunctional Programming.
CS5205 Haskell 2
TopicsTopics
• Higher-Order Functions• Formal Reasoning• Abstraction vs Efficiency• Bridging the Divide
CS5205 Haskell 3
Function AbstractionFunction Abstraction
• Function abstraction is the ability to convert any expression into a function that is evaluated at a later time.
<Expr>
Normal Execution
time
p = \ () -> Expr
p ()
Delayed Execution
time
CS5205 Haskell 4
Higher-Order FunctionsHigher-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.
CS5205 Haskell 5
GenericityGenericity• 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)
CS5205 Haskell 6
Polymorphic, Higher-Order TypesPolymorphic, Higher-Order Types
sumList :: [Int] -> Int
sumList :: Num a => [a] -> a
foldr :: (a -> b -> b) -> b -> [a] -> b
CS5205 Haskell 7
Instantiating Generic FunctionsInstantiating Generic Functions
sumL2 :: Num a => [a] -> asumL2 ls = foldr (+) 0 ls
sumL2 [1, 2, 3] )
sumL2 [1.1, 3, 2.3] )
CS5205 Haskell 8
Instantiating Generic FunctionsInstantiating Generic Functions
prodL :: Num a => [a] -> aprodL ls = foldr (*) 1 ls
prodL [1, 2, 5] )
prodL [1.1, 3, 2.3] )
CS5205 Haskell 9
Instantiating Generic FunctionsInstantiating 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?
CS5205 Haskell 10
Instantiating Generic FunctionsInstantiating 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?
CS5205 Haskell 11
Pipe/ComposePipe/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:
CS5205 Haskell 12
Iterator Construct Iterator Construct
for :: Int -> Int -> (Int -> a -> a) -> a -> a
for i j f a = if i>j then aelse 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:
CS5205 Haskell 13
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
CS5205 Haskell 14
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
CS5205 Haskell 15
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!
CS5205 Haskell 16
Instance of Left FoldingInstance 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
CS5205 Haskell 17
Referential TransparencyReferential 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.
CS5205 Haskell 18
Equivalence Proof Equivalence Proof • Can we Prove : sumList xs = sumT 0 xs.
• Generalise : (sumList xs)+a = sumT a xs.
• By InductionCase : x=[] (sumList [])+a = sumT a []
0+a = aCase : 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
CS5205 Haskell 19
List ReversalList Reversal• Concatenate first element to last position.
rev [] = []rev (x:xs) = rev xs ++ [x]
rev xs = foldr … … …
What is the time complexity?
CS5205 Haskell 20
Time Complexity Time Complexity • Assume : CC(xs++ys) = length xs Derive :StepsSteps(rev(xs))
• Case [] : StepsSteps(rev([])) = 1+StepsSteps([])
= 1+0 • Case x:xs : StepsSteps(rev(x:xs))
= 1+StepsSteps(rev(xs)++[a])= 1+CC(rev(xs)++_)+StepsSteps(rev(xs))= 1+length(rev(xs)+StepsSteps(rev(xs))= 1+length(xs)+StepsSteps(rev(xs))
• Thus : CC(rev(xs)) = (length xs)^2
CS5205 Haskell 21
Iterative List ReversalIterative List Reversal• Concatenate first element to last position.
revT w [] = wrevT w (x:xs) = revT (x:w) xs
Same as:revT w xs = foldl (\ w x -> x:w) w xs
What is the time complexity?
CS5205 Haskell 22
Time Complexity Time Complexity • Derive StepsSteps(revT w xs)
• Case [] : StepsSteps(revT w []) = 1+StepsSteps(w)
= 1+0 • Case x:xs : StepsSteps(revT w (x:xs))
= 1+StepsSteps(revT (x:w) xs)= 1+StepsSteps(revT _ xs)
• Thus : CC(revT w xs) = (length xs)
CS5205 Haskell 23
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
CS5205 Haskell 24
Bridging the DivideBridging the Divide
Abstract Code/Specs
Efficient Codeor Implementation
transform orsynthesize verify
CS5205 Haskell 25
Unfold/Fold TransformationUnfold/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
CS5205 Haskell 26
Fusion Transformation Fusion Transformation • Consider:
…sum (double xs)…sum [] = 0sum 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!
CS5205 Haskell 27
Fusion Transformation Fusion Transformation • Define:
sumdb xs = sum (double xs)
• Instantiate: xs=[]sumdb [] = sum (double [])
= sum []= 0
• Instantiate: xs=x:xssumdb x:xs = sum (double x:xs)
= sum (2*x : double xs)
= 2*x + sum(double xs)= 2*x + (sumdb xs)
CS5205 Haskell 28
Iteration Transformation Iteration Transformation
• Define:sumdbT a xs = a+(sumdb xs)
• Instantiate: xs=[]sumdbT a [] = a+(sumdb [])
= a
• Instantiate: xs=x:xssumdbT a (x:xs) = a+(sumdb x:xs)
= a+(2*x + sumdb xs)= (a+2*x) + (sumdb xs)= sumdbT (a+2*x) xs
CS5205 Haskell 29
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 … ? … = ?
CS5205 Haskell 30
Strictness TransformationStrictness Transformation• Can analyse that accumulating argument of sumdb is
strict. We can force strictness using the `seq` operator.
sumdbT a [] = asumdbT a (x:xs) = sumdbT (a+2*x) xs
sumdbT a [] = asumdbT a (x:xs) = let p = a+2*x in
p `seq` sumdbT p xs
CS5205 Haskell 31
Tupling Transformation 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
CS5205 Haskell 32
Naive FibonacciNaive Fibonacci• Natural but inefficient version of fibonacci :
fib 0 = 1fib 1 = 1fib n = (fib n-1)+(fib n-2)
• Time complexity is exponential time due to presence of redundant calls.
CS5205 Haskell 33
A Call Tree of fibfib 6
fib 5 fib 4
fib 4 fib 3 fib 3 fib 2
fib 3 fib 2 fib 2 fib 1 fib 2 fib 1
Many repeated calls!
CS5205 Haskell 34
A Call Graph of fibfib 6
fib 5
fib 4
fib 3
fib 2
fib 1
No repeated call through reuse of identical calls
CS5205 Haskell 35
Tupling - Computing Two Results
Compute two calls from next two calls in hierarchy:((fib n) , (fib n-1))
((fib n-1) , (fib n-2))
CS5205 Haskell 36
Tupling Fibonacci 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)
CS5205 Haskell 37
Using the Tupled Function Using the Tupled Function
fib 0 = 1fib 1 = 1fib 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
CS5205 Haskell 38
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)
CS5205 Haskell 39
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)
CS5205 Haskell 40
OptimizationOptimization
• 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