440 likes | 573 Views
Part 1 : Programming and Abstraction. Lecture 1: Functional Programming. Dr. Ir. I.S.W.B. Prasetya wishnu@cs.uu.nl A. Azurat S.Kom. ade@cs.uu.nl. Content. Functional programming style Syntax Types Tree recursion Laziness Circularity Practice.
E N D
Part 1 : Programming and Abstraction Lecture 1: Functional Programming Dr. Ir. I.S.W.B. Prasetya wishnu@cs.uu.nl A. Azurat S.Kom. ade@cs.uu.nl
Content • Functional programming style • Syntax • Types • Tree recursion • Laziness • Circularity • Practice FP is a big subject... we will only take the highlights.
Problem • Computing salary • It's not difficult • So, why do we pay lots of money to automate it !?
Programming • Programming: • Algorithmic aspect: how to solve a problem • Communication aspect: tell the computer how to do it • Algorithm intertesting • Communication annoying!(especially talking to something that only chat in 0 and 1...)Lots of language-specific detail which has nothing to do with the actual problem.
Programming • Communication with a computer is a big problem....Precision is needed formal communication with programming language.Formalism constrains communication, making it difficult production cost. • Communication in general is a big problem...Multiply errors: communication errors.
Abstraction • Real world is too complex ... our mind precieve only an abstraction of it.Abstract: not real...Blindness is power!
Thesis 1: Abstraction The key towards low cost software is to teach the compiler, not the programmer.
Functional Programming • Use function as an abstract concept of what a program is. • What do we 'abstract' away? • Pointers • Garbage collection • In-situ array • I/O • Very suitable for program transformation • Why not Java?? • Use the right tool to do the right thing
Functional Programming Languages • LISP, Scheme, Miranda, ML, Clean, Haskell • Variations: • Strongly typed, untyped • Lazy, Strict • Pure, impure • We're using HaskellSite: www.haskell.orgSophisticated compilers and other tools avaialble for free! • For education, check out Helium: www.cs.uu.nl/~afie/helium
Example del :: Int -> [Int] -> [Int] del x [ ] = [ ] del x (y:s) | x==y = del x y | otherwise = y : del x y
You can also do it with less abstraction... void del0 (*int t) {if (null t) {return()} else if (t->item == 0) {*int s = t ; t = t->next free(s) ; del0(t) ; return() ; } else {del0(t->next); return(); } } Error rate, and thus production and maintenance cost increases with the ammount of 'dirty' code you have to write.
Types • Basic types: Bool, Int, Char • Tuple: (Int,Int) • List: [Bool], [Int] • Function: Bool -> Int • Type variable a,b,c,... • Polymorphic type [a] • Self defined type • More sophisticated: • Record • IO • Array
Polymorphism a -> [a] -> [a] del :: Int -> [Int] -> [Int] del x [ ] = [ ] del x (y:s) | x==y = del x y | otherwise = y : del x y
Higher Order Function • Traditionally, a program is used to process data.data program data • Why not pass program to as data?data program dataprogram
Higher Order Function filter :: (a->Bool) -> [a] -> [a] filter p [ ] = [ ] filter p (x:s) | p x = x : filter p s | otherwise = filter p s
Higher Order Function del x s = filter p s where p y = x/=y search :: String -> String -> [String] search w txt = filter p (words txt) where p z = isPrefixOf w z
Higher Order Function map :: (a->b) -> [a] -> [b] map f [ ] = [ ] map f (x : s) = f x : map f s capitalize :: String -> String capitalize s = map toUpper s
Example, recall: capitalize s = map toUpper s Partial Parametrization (a -> b) -> ( [a] -> [b] ) map :: (a -> b) -> [a] -> [b] map toUpper map toLower . map toUpper
Abstraction Given a database of employee and a database of transactions, make a query to produce a list of all transactions made by all managers. query :: [Employee] -> [Transaction] -> [Transaction] query es ts = (concat . map find . filter isManager) es where find employee = filter p ts where p transaction = #id transaction == #id employee
Syntax Sugar • What's the point of being ellegant!?Express things naturally (intuitively) is as little words as possible. • Haskel syntax sugars: • priority and associativity • infix and sufix coercion • sectioning • list comprehension • many more....
Priority and Associativity • Write x + y * z rather than x + (y * z)x : y : s rather than x : (y : s) • Priority : 0 .. 9 see Prelude.hs • Associativity: left, right, non-assoc
Coercion and Sectioning • Infix coercion:f `map` s instead of map f s • Prefix coercion:(+) x y instead of x + y • Sectioning:(++ t) means (\s-> s ++ t)(t ++) means (\u-> t ++ u)
List Comprehension • Example: [x + 1 | x <- s, x>0] • Combo of map and filter query :: [Employee] -> [Transaction] -> [Transaction] query es ts = (concat . map find . filter isManager) es where ... query es ts = concat [find e | e <- es, isManager e]
Introducing New Types • Type abbreviation:type PersonDB = [Person] • data-type definition:data Color = Red | Green | Blue • With parameter:data Maybe a = Nothing | Just a
Recursive Data Type data List a = Empty | Cons a (List a) length :: List a -> Int length Empty = 0 length (Cons x s) = 1 + length s
10 Example: Node 10 (Leaf 0) (Leaf 20) 20 0 Representing Tree data Btree a = Node a (Btree a) (Btree a) | Leaf a
Tree Recursion data Btree a = Node a (Btree a) (Btree a) | Leaf a minT :: Btree a -> a minT (Leaf x) = x minT (Node x t u) = x `min` minT t `min` minT u
Tree Recursion replace :: a -> Btree a -> Btreea replace x (Leaf _ ) = Leaf x replace x (Node _ t u) = Node x t' u' where t' = replace x t u' = replace x u repmin t = replace (minT t) t
Debugging with the Type Checker • Exploit your type checker to debug your programs...Example:use Data Week = Monday | Tuesday | ...Type checker will reject this:if day - 1 < - 1 then ...
Debugging with the Type Checker • Representing Red/Blue tree:With Btree:Node Blue (Leaf Red) (Leaf Red) • Not all Btree is a Red/Blue treeYou'll have to implement the check yourself...
Mutual Recursion odd 0 = False odd (n+1) = even n even 0 = True even (n+1) = odd n data RedRootTree RedNode BlueRootTree BlueRootTree | RedLeaf data BlueRootTree BlueNode RedRootTree RedRootTree | BlueLeaf
Laziness... • Consider this definition:True || b = Truea || True = Truea || b = False • What happen if we evaluate this?(x>0) || find (==x) [0 .. ]
Laziness • Laziness intelligently breaks recursion:find :: (a->Bool) -> [a] -> Boolfind p [ ] = Falsefind p (x : s) = p x || find p s • Often lead to more ellegant solutions:fillSpaceRight n s = take n (s ++ repeat ' ')
Lazily Walking a Tree... • repmin:Replace all elements in a tree with its minimum. • We did it in sequence: compute minimum first, then do replacement.We explicitly program this sequence. repmin t = replace (minT t) t
Lazily Walking a Tree... repmin t = u where (u, m) = foldT t m foldT (Leaf x) m = (Leaf m, x) foldT (Node x t u) m = (Node m t' u', z) where z = x `min` mt `min` mu (t' , mt) = foldT t m (u' , mu) = foldT u m Lazy evaluation will discover the correct order of 'attributes' computation
Classes • Overloading: using the same name for different 'meaning'True == False1 == 1[1,2,3] == [ ] • Class in Haskell:Eq a where (==) :: a -> a -> Bool (/=) :: a -> a -> Bool x /= y = not (x == y)
Instances Examples: instance Eq Bool where True == True = True False == False = True _ == _ = False instance Eq a => Eq [a] where [ ] == [ ] = True (x:s) == (y:t) = (x==y) && s==t _ == _ = False
Use Eq a => a -> [a] -> [a] del :: a -> [a] -> [a] del x [ ] = [ ] del x (y:s) | x==y = del x y | otherwise = y : del x y
I/O • IO is in principle non-functional • In Haskell IO actions are actracted by the type IO aA value of this type is an IO action that produces a value of type aContains in principle no information regarding what kind of IO action it is.
Some basic IO functions • putStr :: String -> IO( ) • getChr :: IO Char • getLine :: IO String • readFile :: FilePath -> IO String • writeFile :: FilePath -> String -> IO( )
Sequencing IO actions displayCountFile :: FilePath -> IO() displayCountFile fname = do { content <- readFile fname ; n <- return (length (words content)) ; putStr (show n) }
Manipulating IO • An IO a value is a value like a any other Haskell value.You can manipulate it at will...Example:sequence (map displayCountFile fileList)
Some Haskell Syntax Rules • Case sensitive • Name of concrete type, data constructor, type constrytor begin with UPPER case character • Name of function, variable, type variable begin with lower case character • Haskell use strict identation rule ...
Type error • Be prepared to get depressed by Haskell's type errorHaskell type checker/inference is very powerful. • Type messaging system is somewhat less developed.Improvement in on the way ... e.g. the new type checker by B. Heeren (used in Helium)