29
Functional Programming, an introduction Program looks like function The contents here are from Miranda book and haskell.org

Functional Programming, an introduction

  • Upload
    ernie

  • View
    34

  • Download
    2

Embed Size (px)

DESCRIPTION

Functional Programming, an introduction. Program looks like function  The contents here are from Miranda book and haskell.org. Why use functional programming. - PowerPoint PPT Presentation

Citation preview

Page 1: Functional Programming, an introduction

Functional Programming, an introduction

Program looks like function The contents here are from

Miranda book and haskell.org

Page 2: Functional Programming, an introduction

Why use functional programming

• Substantially increased programmer productivity (Ericsson measured an improvement factor of between 9 and 25 in one set of experiments on telephony software).

• Shorter, clearer, and more maintainable code. • Fewer errors, higher reliability. • A smaller "semantic gap" between the

programmer and the language. • Shorter lead times.

Page 3: Functional Programming, an introduction

• Functional languages are superb for writing specifications which can actually be executed (and hence tested and debugged).

Page 4: Functional Programming, an introduction

What is functional programming?

• A functional program is a single expression, which is executed by evaluating the expression.

• The focus is on what is to be computed, not how it should be computed. For example:

Page 5: Functional Programming, an introduction

Some example Haskell

square x = x*xarea = square side min x y = | x<=y = x|otherwise = y

• We can run it using “min 3 4” • The result is 3

Page 6: Functional Programming, an introduction

The point is expression evaluation

• Square (3+4) square 7 7*7 49

Reduce by our definition

Can’t reduce any more. We call this a normal form, orCanonical form

Page 7: Functional Programming, an introduction

Quicksort

qsort [] = []

qsort (x:xs) = qsort elts_lt_x ++ [x] ++ qsort elts_greq_x

where

elts_lt_x = [y | y <- xs, y < x] elts_greq_x = [y | y <- xs, y >= x]

elts_lt_x is the list of all y's such that y is drawn from the list xs, and y is less than x

concat

Page 8: Functional Programming, an introduction

Our Quicksort has polymorphism

• It can compare anything that < or > can compare

Page 9: Functional Programming, an introduction

When C is better

• In applications where performance is required at any cost, or when the goal is detailed tuning of a low-level algorithm, an imperative language like C would probably be a better choice than Haskell, exactly because it provides more intimate control over the exact way in which the computation is carried out.

Page 10: Functional Programming, an introduction

Haskell types

• Basic: Int , Double and String • Lists

– Lists is a standard data type in Haskell– The nil list, or the "empty list", is written [].– 1234[ , , , ] = 1234: : : :[] . : is called

“cons”– A list can be constructed from any type ( even fu

nctions or user defined types), but all elements must be of the same type.

– list from 1 to 10 we write 1 10[ .. ] – 13 100[ , .. ] , the first two elements give the

"step" of the sequence.

Page 11: Functional Programming, an introduction

• Tuples– We can group types together into tuples. – For instance (2,4) is the tuple of the Ints 2 and

4. – Maybe you want to return two values from a

function , in Haskell you just return a tuple of two data types)

– Tuples aren't restricted to just two elements, (1,2,3) is the 3-tuple of the Ints 1,2 and 3.

– Any data type can be put inside a tuple, even the ones you define yourself.

– Contents of the tuple can be of differing types: ("Haskell", [1,2,3], 4.5).

– Note that a list is also considered a type and can thus be put inside a tuple - this works the other way as well, you can have a list of tuples.

Page 12: Functional Programming, an introduction

function

• What is a function– A function takes a set of inputs, and returns a

set of output. – A program in Haskell is just a single function.– A function in Haskell is also a value. – You can pass a function as a parameter to

another function, for instance. – A function can also be returned by another

function. You can even put a function in a list, or any other data construct.

Page 13: Functional Programming, an introduction

f a b c = a+b+c • function name, f, • and then the parameters a, b and c. • On the right hand side of the

equation comes the expression which the function will evaluate

• To call a function

g = f 1 2 3 • g a function with zero parameters

that returns the expression on the right hand side.

Page 14: Functional Programming, an introduction

• no paranthesis in function calls • Parenthesis is used for grouping only.

h = f (1+2) (2+3) (3+4)

Page 15: Functional Programming, an introduction

Partial application • f above is a function with three parameters, but that's not

the whole truth. Consider this function, which we define in terms of f

j a b = f 5 a b

• The function j takes two parameters which are added together with the integer 5.Now we will take a look at an alternate definition of this function.

i = f 5

• This function is completely equivalent with the function j above. So how can that be?

• We state that the function i is equal to the function f passed only a single parameter, 5.

• But f was supposed to take three parameters, surely this must be a programming error?

Page 16: Functional Programming, an introduction

• This is completely valid Haskell syntax. • What this means is that you apply 5 to f, the result of

this is a function that takes the two remaining parameters.

• You can think of it as f "waiting" for the rest of the parameters. Thus i will be a function of two parameters, the two parameters that f is "waiting" for.

• A nice way to think of this is that all functions are really just a function of zero or a single parameter.

• The function f a b c is the function that takes one parameter, a, and returns a function that takes the remaining two parameters, b and c.

• This function is in turn a function that also takes a single parameter, b, and returns a function that takes the last parameter, c.

• This takes a single parameter, c, and returns the function of zero parameters that returns the value of a+b+c.

Page 17: Functional Programming, an introduction

mul a b = a*b • All this function does is multiply its two parameters. We

can now use this in conjunction with partial application to define this function

double = mul 2 • We pass 2 to the function mul. • Now 2 is bound to the variable a.• This means that mul is "waiting" for the value of b. In

other words; the result of mul 2 is a function taking the second parameter and multiplying it with two.

• So since the value of the right hand side is a function of one parameter, double must also be a function of one parameter. We can write this explicitly if we wish:

double x = mul 2 x

Page 18: Functional Programming, an introduction

Type signatures• Notice that we have not written out any type signatures on

any of the functions above. • This isn't needed, Haskell will infer it automatically

mul :: Int -> Int -> Intmul a b = a*b

A function from Int to Int to Int

(Note that this definition of mul will only work on ints, whereas the version where we omitted the type signature will work for any type which as the * operator defined.)

Page 19: Functional Programming, an introduction

• Normally you consider the last part of the type signature to denote the type of the output.

• But if you take partial application into account you could just as well consider the function mul to be "a function that goes from an Int to a function that goes from Int to Int". – In other words the output of the function is another

function ("from Int to Int").

mul :: Int -> (Int -> Int)mul a b = a*b

Page 20: Functional Programming, an introduction

• The type signature of a "variable" (or a function with zero parameters) is just

a :: Stringa = "Hello"We just say that a is of type String (no arrows, unlike function).

Page 21: Functional Programming, an introduction

Higher Order Functions

• functions that take another function as a parameter • it is the whole point of Haskell

• twice :: (Int -> Int) -> Int -> Inttwice f value = f (f value)

• As we can see from the type signature this function will take a function of type "Int to Int" as a parameter, and then a value of type Int, then it will return a value of type Int.We can see from the definition that it will apply the function (which we assign the name f ), and then apply the function to the result.

Page 22: Functional Programming, an introduction

• f ( g x) • function composition• We can redefine twice like:

twice :: (Int -> Int) -> Int -> Inttwice f = f . f

• The . operater will apply the right most function to the parameter, and then the left most function to the result.

• We can use our “twice” for any function• quadruple :: Int -> Int

quadruple = twice double

Page 23: Functional Programming, an introduction

Pattern Matching and Recursion

• Let's define a recursive factorial function in Haskell:

fac :: Int -> Intfac 0 = 1fac n = fac (n-1) * n

Haskell will continue down to try to find a pattern that matches (top first).

Page 24: Functional Programming, an introduction

Matching Higher Order Function

- - - map :: (Int > Int) > [Int] > [Int] map f [] = [] map f (x:xs) = f x : map f xs

• apply a function to all elements of a list

• Try …. map double [1,2]

Page 25: Functional Programming, an introduction

• Summing elements in the listsum :: [Int] -> Intsum [] = 0sum (x:xs) = x + sum xs • We can parameterize the function which is used

on the list to combine the elements of the list.• So we'll need to pass

– the function (which was +, in the case of sum) – and the base case (which was 0 in the case of sum).

Page 26: Functional Programming, an introduction

• foldr :: (Int -> Int -> Int) -> Int -> [Int] -> Intfoldr func base [] = basefoldr func base (x:xs) = x `func` (foldr func base xs)

"fold right". • It take some function, func, and apply it to each element

and the rest of the list ("folding it", into the list), exactly like we use + in the sum function.

• The base value is the identity value of the function, for the sum function this was 0. It's the value which is returned for the empty list.

• There's a bit of new syntax here. By enclosing a function of two parameters like so `func` we can actually make that function an infix operator (like + and *). The reverse is also possible, to transform an infix operator you enclose it in paranthesis (for example you could write (+) 4 3, to add 3 and 4, just as well as 4 + 3).

Page 27: Functional Programming, an introduction

• Now let's redefine the sum function using our new foldr function.

sum :: [Int] -> Intsum = foldr (+) 0

• Let's define another function, product, using foldr

product :: [Int] -> Intproduct = foldr (*) 1

Page 28: Functional Programming, an introduction

Lambda Functions• construct a function on the fly.

\a b c -> expr

• The starting backslash is meant to look like a lambda symbol. • The a b, and c are the parameters, then there's an arrow and after that

the expression.• The advantage of this notation is that you can create unnamed

functions which can come in handy when you wish to map some operation on a list, for instance:

func xs b = map (\a -> 2*a-b) xs

• Here we create a function on the fly and send it off to the map function. So for small functions this can be very convenient.

Page 29: Functional Programming, an introduction

The where notation• What if we have a function definition that won't fit on a

single line? • We can use the where-notation to rewrite the map function

above.

map :: (Int -> Int) -> [Int] -> [Int]map f [] = []map f (x:xs) = f x : mappedwhere mapped = map f xs

• Basically you can put a where clause underneath a function and make definitions there which can be used in the function itself.

• These definitions are in the same scope as the function itself and as such it has access to the parameters of the function.