GUL UC3M - Introduction to functional programming

Post on 15-Jul-2015

653 views 6 download

Transcript of GUL UC3M - Introduction to functional programming

@voiser

Introduction to FP

“Functional programming is a style of programming which models computations as the evaluation of expressions.”

https://www.haskell.org/haskellwiki/Functional_programming

imperative style vs functional style

recipes vs expressions

http://commons.wikimedia.org/wiki/File:Turnstile_state_machine_colored.svg

def sort(array):

less = []

equal = []

greater = []

if len(array) > 1:

pivot = array[0]

for x in array:

if x < pivot:

less.append(x)

if x == pivot:

equal.append(x)

if x > pivot:

greater.append(x)

return sort(less)+equal+sort(greater)

else:

return array

http://stackoverflow.com/questions/18262306/quick-sort-with-python

def qsort1(list):

if list == []:

return []

else:

pivot = list[0]

lesser = qsort1([x for x in list[1:] if x < pivot])

greater = qsort1([x for x in list[1:] if x >= pivot])

return lesser + [pivot] + greater

http://en.literateprograms.org/Quicksort_(Python)

“Many programming languages support programming in both functional and imperative style but the syntax and facilities of a language are typically optimised for only one of these styles, and social factors like coding conventions and libraries often force the programmer towards one of the styles.”

https://www.haskell.org/haskellwiki/Functional_programming

qsort [] = []

qsort (p:xs) = qsort1 lesser ++ [p] ++ qsort1 greater

where

lesser = [ y | y <- xs, y < p ]

greater = [ y | y <- xs, y >= p ]

http://en.literateprograms.org/Quicksort_(Haskell)

first class functions*

* Also available in your favourite imperative language

interface Filter<T> {

boolean filters(T t);

}

List<T> filter(List<T> original, Filter<T> filter) {

List<T> newList = new LinkedList<T>();

for (T elem : original) {

if (filter.filters(elem)) {

newList.add(elem);

}

}

return newList;

}

List<Integer> myList = …

filter(myList, new Filter<Integer>() {

boolean filters(Integer t) {

return t > 10;

}

});

filter f xs = [x | x <- xs, f x]

filter (\x -> x > 10) myList

dealing with state, the functional way*

Response dispatch(Request req) {

if (config.blah()) {

if (config.bleh()) {

return dispatchCase1(req)

} else {

return dispatchCase2(req)

}

} else {

if (config.bleh()) {

return dispatchCase3(req)

} else {

return dispatchCase4(req)

}

}

}

Response dispatch(Request req) {

int case = config.getDispatchCase()

switch (case) {

case 1: return dispatchCase1(req)

case 2: return dispatchCase2(req)

case 3: return dispatchCase3(req)

case 4: return dispatchCase4(req)

}

}

// when more cases arrive, this code must be updated -> %&#$!!!

interface Dispatcher {

Response dispatch(Request);

}

Map[Configuration, Dispatcher] dispatchers = …

Response dispatch (Request req) {

dispatchers.get(config).dispatch(req)

}

Type Dispatcher = (Request => Response)

val dispatchers : Map[Configuration, Dispatcher] = ...

def dispatch (req : Request) = dispatchers.get(config)(req)

val dispatchers : Stack[Dispatcher] = ...

def dispatch(req : Request) = dispatchers.top()(req)

// some event arrives, starting a transitory state

val d : Dispatcher = { r : Request => ... }

dispatchers.push(d)

// the transitory state finishes, fall back to latest state

dispatchers.pull()

lazy evaluation*

def fibFrom(a: Int, b: Int): Stream[Int] = a #:: fibFrom(b, a + b)

val fibs = fibFrom(1, 1)

immutability*

* Language independent, but surprisingly, some languages encourage mutability.

class Person {

string name

int age;

boolean married;

// getters and setters

}

function getInfo(Person p) {

return p.getName()

+ “ is “

+ p.getAge()

+ “ years old and is “

+ (p.isMarried()? “married” : “not married”)

}

function update(Person p, int age, married m) {

p.setAge(age);

p.setMarried(m);

}

class Person {

final string name;

final int age;

final boolean married;

}

function getInfo(Person p) {

return p.name

+ “ is ”

+ p.age

+ “ years old and is “

+ (p.married? “married” : “not married”)

}

function update(Person p, int age, married m) {

return new Person(p.name, age, married)

}

avoid mutability with (tail) recursion*

square [] = []

square (x:xs) = x * x : square xs

Q: Is FP perfect for everything?A: No.

Q: Should I learn a new language?A: No. You can start adopting functional patterns in your current favourite language.

Q: What if I want to learn a new language?A: Well, my personal recommendation is...

gul.es@guluc3m