GUL UC3M - Introduction to functional programming
-
Upload
david-munoz-diaz -
Category
Software
-
view
653 -
download
6
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