KEMBAR78
Presentation of GetTogether on Functional Programming | PPS
Functional Programming
Putting the fun in programming
At least I think so
Kris.Aerts@kuleuven.be
Me, Myself & Functional Programming
• 1991: Prolog
• 1992: sociology in LLN
• 1993: Haskell
• 1994: paper of Hudak
• 1999: paper Games provide fun(ctional programming
• tasks) in Functional and declarative programming in
education, FDPE’99
• 2001: finished my PhD and started at KHLim Diepenbeek
• Teaching ICT in master in industrial sciences (ing.)
o Capable in Java, not so much in .NET
o Bit of functional programming in master
2/72
Hudak’s Paper
• Experiment in 1994
3/72
A Military Radar System Prototyped
4/72
The Results
5/72
Subjective Evaluation
6/72
Research in Functional Programming
• Dia van Tom’s inaugurale
• Lisp: 1958
• Haskell:
• Erlang
• Common Lisp: 1e
ANSI gestandaardiseerde taal met OO +
FP
7/72
Key Challenges
Programming
Languages
Computer Science
Society
More
Software
More
Software
Agoria: ’9300 unfilled ICT positions'Agoria: ’9300 unfilled ICT positions'
ProductivityProductivity ReliabilityReliability
ANP: ‘Software bugs cost
1.6 billion € a year’
ANP: ‘Software bugs cost
1.6 billion € a year’
Bug-Free
Software
Bug-Free
Software
Meeting the Challenges
Incremental Research
Mainstream languages
Fundamental Research
A different approach
to languages
Mainstream languages
Historical Evolution
imperative
languages
object
orientation
mathematics
hardware
mainstream
alternative
declarative
languages
1
1953
Fortran
1958
Cobol
1969
CAlgol
1959 1971
Smalltalk Eiffel
19851983
C++
Declarative Languages
Functional
Programming
Haskell
Logic
Programming
Prolog
Constraint
Programming
MiniZinc
Recent Developments
imperative
languages
object
orientation
mathematics
hardware
mainstream
declarative
languages
research
Anonymous Functions
λ calculus
1936
Alonzo
Church
1958
Lisp
John
McCarthy
1973
ML
Robin
Milner
1987
Haskell
Haskell
Committee
2014
Java 8
Swift
2011
C++11
Functional Languages Mainstream
2007
C#
15/72
Early Adopters
Haskell Language + GHC CompilerHaskell Language + GHC Compiler
Finance Many OthersTelecom
Productivy and Functional Programmin
• http://simontylercousins.net/does-the-language-you-use-
make-a-difference-revisited/
• The problem
17/72
Solution in C#
18/72
Solution in F#
19/72
The Numbers (1)
20/72
The Numbers (2)
21/72
The Numbers (3)
22/72
Rest of the presentation
• Some concepts of Functional Programming
o With examples in Haskell, F# and C#
23/72
Declarative Programming
What
• Derivation from ‘input’-
values to ‘output’-values
• Or expressing properties
o Often mathematically sound
• (but still fun to do ;-)
• Intelligent execution
o verifiable
How
• What machine to use
• When to use which
features of machine
• What steps to set
• Programmer considered
intelligent
o Mostly not verifiable
Describing the what instead of the how
24
Declarative Programming
What
• SQL
• Linq (mostly)
• Logic Programming
o Constraint Programming
• Functional Programming
Different mindset!
How
• Imperative programming
• Manipulation of v ariables
• What machine to use
o von Neumann architecture
• When to use which
features of machine
o Variables = registers
• What steps to set
o Order of execution
o Outer loops (for, while)
Examples
= Statements= Expressions
25
Logic Programming = Prolog (1a)
ancestor(x,y) :- parent(x,y).
ancestor(x,y) :- ancestor(x,z), parent(z,y).
femaleAncestor(x,y) :- ancestor(x,y), female(x).
?- femaleAncestor(Kris,Lars). => no
?- femaleAncestor(Celine,Lars). => yes
?- femaleAncestor(x,Lars). => Celine, Liesbet
26/72
Logic Programming = Prolog (1b)
female(Celine).
female(Liesbet).
female(Hanne).
male(Kris).
male(Lars).
parent(Celine,Kris).
parent(Kris,Lars).
parent(Liesbet,Lars).
27/72
Logic Programming = Prolog (2)
evenNumber([]).
even([_,_|T]):- evenNumber(T).
palindrome(L):- reverse(L,L).
reverse([],[]).
reverse([H|T],R):- reverse(T,T1),append(T1,[H],R).
28/72
(Pure) Functional Programming
• Much closer to “real” programming
o Logic Programming = (partial) instantation = more magic
o Functional Programming
• functions with parameters returning values
• Much like functions and/or methodes
• But
o No side effects
• Referential transparency
• An expression is a value with always the same value
• “no (hidden or far distant) state messing with things”
• Strongly typed with type inference
o “Strongly typed programs can’t go wrong”
• Polymorf: a function can have many types
29/72
Lambda calculus
• Each expression has a never-changing-value
o z = 18
o y = sin(z)
• Complex expressions are calculated by evaluating
and substituting subexpressions
o (z + sin(z))*(y+cos(y))
• Function calls behave exactly the same
o Always call by value
o Always return value
o No pointer- or out variables
30/72
Lambda Calculus (2)
• f x = g(3+x)+x
• g y = y+1
• z = 5
• f z + g z
31/72
How to express new state?
• Never
o No mutable variables! (in pure FP-languages)
• in general no side effects
o Confusing for imperative programmers
• F# allows for explicit declaration of mutable variables
• C# allows for explicit declaration of readonly (instance) variables
• But actually always
o A new state is a new value
• May be stored explicitly in a variable
• Or may be stored temporarily in memory
32/72
Explicit new values!
let y = a + b
yPlus1 = y + 1
f x = (x+y)/yPlus1
in f a + f b
No confusion between x++ and ++x etc.
33/72
Advantages of having no mutable variables
• Referential transparancy
o A reference always refers to the same value
o Mathematically sound
• Implicit parallellism
o Order of execution can be chosen, both at compile and
run time
o Synchronisation: locking issues when dependencies
• Formal reasoning
o Automated correctness and equivalence proofs
o More transparant code
o No underlying dependency from mutable states
34/72
Side Effects
Traditional Mainstream
Languages Oops,
unexpected
interference
Oops,
unexpected
interference
No Side Effects
Traditional Declarative
Languages
No Side-Effects,
No Problem
Traditional Mainstream
Languages
No Side-Effects,
No Party
Mathematical Elegance
Predictable
No Interference
✓
✓
✓
Explicit Side Effects
State-of-the-Art Declarative
Languages
Explicit Side-Effects,
No Problem
Mathematical Elegance
Predictable
Explicit Interference
✓
✓
✓
How to return many values?
• Imperative programs
o Return 1 value from function
o And others as ‘out’ parameters (using call by reference)
• OO programs using only call by value
o Define a container class for each combination of types
o Cumbersome…
• FP-languages use tuples (x,y) , (x,y,z) , (a,b,c,d), …
o Flexible in number of elements
o Flexible in composing types
38/72
Recursion = “looping” (1)
From definition to code
n! = n*(n-1)!
With base case 1! = 1
• Haskell
o fac 1 = 1
o fac n = n * fac (n-1)
• Non-recursive C#
public long fac(int n) {
long value = 1;
for (int i=2; i<=n; n++) {
value = value * i;
}
return value ;
}
39
Recursion = “looping” (2)
From definition to code
n! = n*(n-1)!
With base case 1! = 1
• F#
let rec fact x =
if x < 1 then 1
else x * fact (x - 1)
• Recursive C#
public long fac(int n) {
if (n==1) return 1;
return n * fac (n-1);
}
40
Recursion = “looping” (3)
StackOverFlow error?
•“Real” functional languages use more optimisation techniques for
recursive programs
• F#
let rec fact x =
if x < 1 then 1
else x * fact (x - 1)
• Recursive C#
public BigInteger fac(int n) {
if (n==1) return 1;
return n * fac (n-1);
}
41
Tail recursion
Taking care of useless stack frames
• Haskell
fac n = fac’ n 1
fac‘ 1 acc = acc
fac‘ n acc = fac’ (n-1) (n*acc)
• F#
let fac n = facT n 1
let rec facT n acc =
if n = 1
then acc
else facT (n-1) (n*acc)
42
Tail recursion (2)
Taking care of useless stack frames
• C#
BigInteger Factorial(int n, BigInteger product)
{
if (n < 2)
return product;
return Factorial(n - 1, n * product);
}
43
Exercises in my master class ;-)
1. Hermite sum 1/n + 1/(n-1)+…1/2+1/1
2. Mysterious function (presumption of Fermat)
o Reduce n to1 with the following steps
• Odd n => continue with 3n+1
• Even n => continue with n/2
1. Calculate numberOfDivisors and isPriem
44/72
Solutions in Haskell
herm 1 = 1
herm n = 1/n + (herm (n-1))
myst 1 = [1]
myst n | mod n 2 == 0 = n:(myst (div n 2))
| otherwise = n:(myst (3*n+1))
numberOfDivisors …
isPrime n = (numberOfDivisors n) == 2
45/72
Recursive Programming: conclusion
• Not exclusively for functional programming
• But very typical for FP
o And efficient
• Interesting pattern also for non FP-languages!
46/72
Lists in Functional Programming
• Omnipresent feature
o In most languages
o But very strong support in FP
• Especially when combined with pattern matching
• And recursive programming
• Remember basic concept of recursion:
1. Define primitive/base expression(s)
2. Reduce complex expression to more simple expression
• N reduces to n-1, n/2, …
• List reduces to list with fewer elements
47/72
Pattern matching in Haskell
fac 1 = 1
fac n = n * fac (n-1)
findValue [] y = False
findValue (x:xs) y = if x == y then True
else findValue xs y
evenElems [] = True
evenElems [x] = False
evenElems (x:y:ys) = evenElems ys
48/72
Pattern matching in F#
findValue [] y = False
findValue (x:xs) y = if x == y then True
else findValue xs y
let rec findValue list x = match list with
| [] -> False
| y::ys -> if x == y then True
else findValue x ys
49/72
Pattern Matching in C#
• Proposition for Roslyn in 8/2014
o https://roslyn.codeplex.com/discussions/560339
o http://www.infoq.com/news/2014/08/Pattern-Matching
if (expr is Type v)
{ // code using v } // try-cast
var c = Cartesian(3, 4);
if (c is Polar(var R, *))
Console.WriteLine(R);
var a = new Location(1, 2, 3); //x=1, y=2, z=3
if (a is Location(1, var y, *))
50/72
Defining (recursive) types in Haskell
• data Examenvorm = M | S | P
• data Sexe= M | V
• data Human = Mens Integer String Geslacht
• data Point = Point Integer Integer
• data GenericPoint a = Pt a a
• data Tree a = Leaf a
| Branch (Tree a) (Tree a)
• Perfect for pattern matching!
51/72
Defining (recursive) types (2)
• Comparable to structs and even classes
• data Human = Human { age :: Integer,
name :: String,
sexe :: Sexe }
• Creates automatically the following functions
o Human :: Integer -> String -> Sexe -> Human
o age :: Human -> Integer
o name :: Human -> String
o sexe :: Human -> Sexe
52/72
Insert sort in Haskell
isort [ ] = [ ]
isort (x:xs) = insert x (isort xs)
insert x [ ] = [x]
insert x (y:ys) = if (x<y) then (x:y:ys)
else y:(insert x ys)
Barely new syntax needed!
53/72
Insert sort in F#
let rec insert x l = match l with
| [] -> [x]
| y::ys -> if x <= y then x::y::ys
else y::insert x ys
and insertsort l = match l with
| [] -> []
| x::xs -> insert x (insertsort xs)
Source: http://www.codecodex.com/wiki/Insertion_sort
54/72
Insert sort in C# (non-functional)
static void InsertSort(IComparable[] array)
{
int i, j;
for (i = 1; i < array.Length; i++)
{
IComparable value = array[i];
j = i - 1;
while ((j >= 0) && (array[j].CompareTo(value) > 0))
{
array[j + 1] = array[j];
j=j-1;
}
array[j + 1] = value;
}
} 55/72
Type Classes and type inference
• Note the explicit IComparable[] array in function type
o static void InsertSort(IComparable[] array)
• In Haskell implicit and auto-detected
56/72
Polymorfic: look at the types
• Typ “:i isort” at command prompt of Haskell Interpreter
o isort :: Ord a => [a] -> [a]
• Similar
o halfList :: [a] -> [a]
o findValue :: Eq a => [a] -> a -> Bool
o fac :: (Num a, Eq a) => a -> a
57/72
Strongly typed programs can’t go wrong
• Type inference tries to find the most general type of
function
o Depending on the functions that are being used
• Programmer doesn’t need to define types
o But a type mismatch results in a compile time error
o Indicating a mistake in the reasoning
o Whenever type inference succeeds most programs run
correctly
58/72
Type inference in .NET
• More and more available
59/72
List Comprehensions in Haskell
Very declarative constructor
-- give all even numbers of a list
evens list = [x | x <- list, even x]
inBoth list1 list2 = [x | x <- list1, findValue x list2]
combine list1 list2 = [(x,y) | x <- list1, y <- list2]
60/72
List Comprehensions in Haskell
Very declarative constructor
-- give all even numbers of a list
evens list = [x | x <- list, even x]
inBoth list1 list2 = [x | x <- list1, findValue x list2]
combine list1 list2 = [(x,y) | x <- list1, y <- list2]
61/72
List Comprehensions in F#
[for x in collection do ... yield expr]
seq { for x in 0..100 do
if x*x > 3 then yield 2*x } ;;
evens list = [x | x <- list, even x]
inBoth list1 list2 = [x | x <- list1, findValue x list2]
combine list1 list2 = [(x,y) | x <- list1, y <- list2]
62/72
List Comprehensions in C#
from x in Enumerable.Range(0, 100)
where x * x > 3
select x * 2
63/72
Quicksort: even more beautiful ;-)
• Concept of quicksort
1. Take “a” element of the list: the “spil”
2. Split the list in two
1. Elements smaller than spil
2. Elements bigger than spil
3. Quicksort each sublist (recursively ;-)
4. Join the sorted lists together
64/72
Quicksort in Haskell
qsort [] = []
qsort [x] = [x]
qsort (x:xs) =
let smaller = qsort([y | y <- xs, y < x])
larger = qsort([y | y <- xs, y > x])
in smaller ++ (x:larger)
65/72
Quicksort in F#
let rec qsort:int list -> int list = function
| [] -> []
| x::xs -> let smaller = [for a in xs do if a<=x then yield a]
let larger = [for b in xs do if b>x then yield b]
qsort smaller @ [x] @ qsort larger
let rec qsort = function
| [] -> []
| x::xs -> let smaller,larger = List.partition (fun y -> y<=x) xs
qsort smaller @ [x] @ qsort larger
66/72
Higher order functions
• Functions taking other functions as parameters
• Simple list functions map & filter
o map fac [3,6,2,4]
o filter odd [1,2,3,4,5,6,7]
• More Complex list functies foldr & foldl
o Reduce a list to one value
• Using a combining function
• And a starting value
o Foldr (+) 0 [1,2,3,4,5,6]
67/72
Recursion over functions
repeatFun 0 f value = value
repeatFun n f value = repeatFun (n-1) f (f value)
bubbleSort list = repeatFun(length list) bubble list
bubble [] = []
bubble [x] = [x]
bubble (x:y:ys)
| x < y = x:(bubble (y:ys))
| otherwise = y:(bubble (x:ys))
68/72
Anonymous functions
• Lambda abstractions
69/72
Currying
• Functions of n arguments
• Are actually functions of 1 argument
o Returning a function of (n-1) argument
• Which is actually of function of 1 argument
• Returning a function of (n-2) arguments
- …
• Specialisation of functions
contains2 = contains 2
70/72
Open your mind!
• Become a Better Developer with Functional
Programming
o http://www.oscon.com/oscon2011/public/schedule/detail/
19191
Questions?
71/72
More info about the TETRA-project?
72/72
• http://www.vlambda.be/
• Contact Kris.Aerts@kuleuven.be or Tom Schrijvers
.NET-productiviteit verhogen
met een gepast gebruikt
van lambda's en F#
(en natuurlijk ook in Java ;-)
Vlaamse software vlamt met lambda’s

Presentation of GetTogether on Functional Programming

  • 1.
    Functional Programming Putting thefun in programming At least I think so Kris.Aerts@kuleuven.be
  • 2.
    Me, Myself &Functional Programming • 1991: Prolog • 1992: sociology in LLN • 1993: Haskell • 1994: paper of Hudak • 1999: paper Games provide fun(ctional programming • tasks) in Functional and declarative programming in education, FDPE’99 • 2001: finished my PhD and started at KHLim Diepenbeek • Teaching ICT in master in industrial sciences (ing.) o Capable in Java, not so much in .NET o Bit of functional programming in master 2/72
  • 3.
  • 4.
    A Military RadarSystem Prototyped 4/72
  • 5.
  • 6.
  • 7.
    Research in FunctionalProgramming • Dia van Tom’s inaugurale • Lisp: 1958 • Haskell: • Erlang • Common Lisp: 1e ANSI gestandaardiseerde taal met OO + FP 7/72
  • 8.
    Key Challenges Programming Languages Computer Science Society More Software More Software Agoria:’9300 unfilled ICT positions'Agoria: ’9300 unfilled ICT positions' ProductivityProductivity ReliabilityReliability ANP: ‘Software bugs cost 1.6 billion € a year’ ANP: ‘Software bugs cost 1.6 billion € a year’ Bug-Free Software Bug-Free Software
  • 9.
    Meeting the Challenges IncrementalResearch Mainstream languages Fundamental Research A different approach to languages Mainstream languages
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
    Early Adopters Haskell Language+ GHC CompilerHaskell Language + GHC Compiler Finance Many OthersTelecom
  • 16.
    Productivy and FunctionalProgrammin • http://simontylercousins.net/does-the-language-you-use- make-a-difference-revisited/ • The problem 17/72
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
    Rest of thepresentation • Some concepts of Functional Programming o With examples in Haskell, F# and C# 23/72
  • 23.
    Declarative Programming What • Derivationfrom ‘input’- values to ‘output’-values • Or expressing properties o Often mathematically sound • (but still fun to do ;-) • Intelligent execution o verifiable How • What machine to use • When to use which features of machine • What steps to set • Programmer considered intelligent o Mostly not verifiable Describing the what instead of the how 24
  • 24.
    Declarative Programming What • SQL •Linq (mostly) • Logic Programming o Constraint Programming • Functional Programming Different mindset! How • Imperative programming • Manipulation of v ariables • What machine to use o von Neumann architecture • When to use which features of machine o Variables = registers • What steps to set o Order of execution o Outer loops (for, while) Examples = Statements= Expressions 25
  • 25.
    Logic Programming =Prolog (1a) ancestor(x,y) :- parent(x,y). ancestor(x,y) :- ancestor(x,z), parent(z,y). femaleAncestor(x,y) :- ancestor(x,y), female(x). ?- femaleAncestor(Kris,Lars). => no ?- femaleAncestor(Celine,Lars). => yes ?- femaleAncestor(x,Lars). => Celine, Liesbet 26/72
  • 26.
    Logic Programming =Prolog (1b) female(Celine). female(Liesbet). female(Hanne). male(Kris). male(Lars). parent(Celine,Kris). parent(Kris,Lars). parent(Liesbet,Lars). 27/72
  • 27.
    Logic Programming =Prolog (2) evenNumber([]). even([_,_|T]):- evenNumber(T). palindrome(L):- reverse(L,L). reverse([],[]). reverse([H|T],R):- reverse(T,T1),append(T1,[H],R). 28/72
  • 28.
    (Pure) Functional Programming •Much closer to “real” programming o Logic Programming = (partial) instantation = more magic o Functional Programming • functions with parameters returning values • Much like functions and/or methodes • But o No side effects • Referential transparency • An expression is a value with always the same value • “no (hidden or far distant) state messing with things” • Strongly typed with type inference o “Strongly typed programs can’t go wrong” • Polymorf: a function can have many types 29/72
  • 29.
    Lambda calculus • Eachexpression has a never-changing-value o z = 18 o y = sin(z) • Complex expressions are calculated by evaluating and substituting subexpressions o (z + sin(z))*(y+cos(y)) • Function calls behave exactly the same o Always call by value o Always return value o No pointer- or out variables 30/72
  • 30.
    Lambda Calculus (2) •f x = g(3+x)+x • g y = y+1 • z = 5 • f z + g z 31/72
  • 31.
    How to expressnew state? • Never o No mutable variables! (in pure FP-languages) • in general no side effects o Confusing for imperative programmers • F# allows for explicit declaration of mutable variables • C# allows for explicit declaration of readonly (instance) variables • But actually always o A new state is a new value • May be stored explicitly in a variable • Or may be stored temporarily in memory 32/72
  • 32.
    Explicit new values! lety = a + b yPlus1 = y + 1 f x = (x+y)/yPlus1 in f a + f b No confusion between x++ and ++x etc. 33/72
  • 33.
    Advantages of havingno mutable variables • Referential transparancy o A reference always refers to the same value o Mathematically sound • Implicit parallellism o Order of execution can be chosen, both at compile and run time o Synchronisation: locking issues when dependencies • Formal reasoning o Automated correctness and equivalence proofs o More transparant code o No underlying dependency from mutable states 34/72
  • 34.
    Side Effects Traditional Mainstream LanguagesOops, unexpected interference Oops, unexpected interference
  • 35.
    No Side Effects TraditionalDeclarative Languages No Side-Effects, No Problem Traditional Mainstream Languages No Side-Effects, No Party Mathematical Elegance Predictable No Interference ✓ ✓ ✓
  • 36.
    Explicit Side Effects State-of-the-ArtDeclarative Languages Explicit Side-Effects, No Problem Mathematical Elegance Predictable Explicit Interference ✓ ✓ ✓
  • 37.
    How to returnmany values? • Imperative programs o Return 1 value from function o And others as ‘out’ parameters (using call by reference) • OO programs using only call by value o Define a container class for each combination of types o Cumbersome… • FP-languages use tuples (x,y) , (x,y,z) , (a,b,c,d), … o Flexible in number of elements o Flexible in composing types 38/72
  • 38.
    Recursion = “looping”(1) From definition to code n! = n*(n-1)! With base case 1! = 1 • Haskell o fac 1 = 1 o fac n = n * fac (n-1) • Non-recursive C# public long fac(int n) { long value = 1; for (int i=2; i<=n; n++) { value = value * i; } return value ; } 39
  • 39.
    Recursion = “looping”(2) From definition to code n! = n*(n-1)! With base case 1! = 1 • F# let rec fact x = if x < 1 then 1 else x * fact (x - 1) • Recursive C# public long fac(int n) { if (n==1) return 1; return n * fac (n-1); } 40
  • 40.
    Recursion = “looping”(3) StackOverFlow error? •“Real” functional languages use more optimisation techniques for recursive programs • F# let rec fact x = if x < 1 then 1 else x * fact (x - 1) • Recursive C# public BigInteger fac(int n) { if (n==1) return 1; return n * fac (n-1); } 41
  • 41.
    Tail recursion Taking careof useless stack frames • Haskell fac n = fac’ n 1 fac‘ 1 acc = acc fac‘ n acc = fac’ (n-1) (n*acc) • F# let fac n = facT n 1 let rec facT n acc = if n = 1 then acc else facT (n-1) (n*acc) 42
  • 42.
    Tail recursion (2) Takingcare of useless stack frames • C# BigInteger Factorial(int n, BigInteger product) { if (n < 2) return product; return Factorial(n - 1, n * product); } 43
  • 43.
    Exercises in mymaster class ;-) 1. Hermite sum 1/n + 1/(n-1)+…1/2+1/1 2. Mysterious function (presumption of Fermat) o Reduce n to1 with the following steps • Odd n => continue with 3n+1 • Even n => continue with n/2 1. Calculate numberOfDivisors and isPriem 44/72
  • 44.
    Solutions in Haskell herm1 = 1 herm n = 1/n + (herm (n-1)) myst 1 = [1] myst n | mod n 2 == 0 = n:(myst (div n 2)) | otherwise = n:(myst (3*n+1)) numberOfDivisors … isPrime n = (numberOfDivisors n) == 2 45/72
  • 45.
    Recursive Programming: conclusion •Not exclusively for functional programming • But very typical for FP o And efficient • Interesting pattern also for non FP-languages! 46/72
  • 46.
    Lists in FunctionalProgramming • Omnipresent feature o In most languages o But very strong support in FP • Especially when combined with pattern matching • And recursive programming • Remember basic concept of recursion: 1. Define primitive/base expression(s) 2. Reduce complex expression to more simple expression • N reduces to n-1, n/2, … • List reduces to list with fewer elements 47/72
  • 47.
    Pattern matching inHaskell fac 1 = 1 fac n = n * fac (n-1) findValue [] y = False findValue (x:xs) y = if x == y then True else findValue xs y evenElems [] = True evenElems [x] = False evenElems (x:y:ys) = evenElems ys 48/72
  • 48.
    Pattern matching inF# findValue [] y = False findValue (x:xs) y = if x == y then True else findValue xs y let rec findValue list x = match list with | [] -> False | y::ys -> if x == y then True else findValue x ys 49/72
  • 49.
    Pattern Matching inC# • Proposition for Roslyn in 8/2014 o https://roslyn.codeplex.com/discussions/560339 o http://www.infoq.com/news/2014/08/Pattern-Matching if (expr is Type v) { // code using v } // try-cast var c = Cartesian(3, 4); if (c is Polar(var R, *)) Console.WriteLine(R); var a = new Location(1, 2, 3); //x=1, y=2, z=3 if (a is Location(1, var y, *)) 50/72
  • 50.
    Defining (recursive) typesin Haskell • data Examenvorm = M | S | P • data Sexe= M | V • data Human = Mens Integer String Geslacht • data Point = Point Integer Integer • data GenericPoint a = Pt a a • data Tree a = Leaf a | Branch (Tree a) (Tree a) • Perfect for pattern matching! 51/72
  • 51.
    Defining (recursive) types(2) • Comparable to structs and even classes • data Human = Human { age :: Integer, name :: String, sexe :: Sexe } • Creates automatically the following functions o Human :: Integer -> String -> Sexe -> Human o age :: Human -> Integer o name :: Human -> String o sexe :: Human -> Sexe 52/72
  • 52.
    Insert sort inHaskell isort [ ] = [ ] isort (x:xs) = insert x (isort xs) insert x [ ] = [x] insert x (y:ys) = if (x<y) then (x:y:ys) else y:(insert x ys) Barely new syntax needed! 53/72
  • 53.
    Insert sort inF# let rec insert x l = match l with | [] -> [x] | y::ys -> if x <= y then x::y::ys else y::insert x ys and insertsort l = match l with | [] -> [] | x::xs -> insert x (insertsort xs) Source: http://www.codecodex.com/wiki/Insertion_sort 54/72
  • 54.
    Insert sort inC# (non-functional) static void InsertSort(IComparable[] array) { int i, j; for (i = 1; i < array.Length; i++) { IComparable value = array[i]; j = i - 1; while ((j >= 0) && (array[j].CompareTo(value) > 0)) { array[j + 1] = array[j]; j=j-1; } array[j + 1] = value; } } 55/72
  • 55.
    Type Classes andtype inference • Note the explicit IComparable[] array in function type o static void InsertSort(IComparable[] array) • In Haskell implicit and auto-detected 56/72
  • 56.
    Polymorfic: look atthe types • Typ “:i isort” at command prompt of Haskell Interpreter o isort :: Ord a => [a] -> [a] • Similar o halfList :: [a] -> [a] o findValue :: Eq a => [a] -> a -> Bool o fac :: (Num a, Eq a) => a -> a 57/72
  • 57.
    Strongly typed programscan’t go wrong • Type inference tries to find the most general type of function o Depending on the functions that are being used • Programmer doesn’t need to define types o But a type mismatch results in a compile time error o Indicating a mistake in the reasoning o Whenever type inference succeeds most programs run correctly 58/72
  • 58.
    Type inference in.NET • More and more available 59/72
  • 59.
    List Comprehensions inHaskell Very declarative constructor -- give all even numbers of a list evens list = [x | x <- list, even x] inBoth list1 list2 = [x | x <- list1, findValue x list2] combine list1 list2 = [(x,y) | x <- list1, y <- list2] 60/72
  • 60.
    List Comprehensions inHaskell Very declarative constructor -- give all even numbers of a list evens list = [x | x <- list, even x] inBoth list1 list2 = [x | x <- list1, findValue x list2] combine list1 list2 = [(x,y) | x <- list1, y <- list2] 61/72
  • 61.
    List Comprehensions inF# [for x in collection do ... yield expr] seq { for x in 0..100 do if x*x > 3 then yield 2*x } ;; evens list = [x | x <- list, even x] inBoth list1 list2 = [x | x <- list1, findValue x list2] combine list1 list2 = [(x,y) | x <- list1, y <- list2] 62/72
  • 62.
    List Comprehensions inC# from x in Enumerable.Range(0, 100) where x * x > 3 select x * 2 63/72
  • 63.
    Quicksort: even morebeautiful ;-) • Concept of quicksort 1. Take “a” element of the list: the “spil” 2. Split the list in two 1. Elements smaller than spil 2. Elements bigger than spil 3. Quicksort each sublist (recursively ;-) 4. Join the sorted lists together 64/72
  • 64.
    Quicksort in Haskell qsort[] = [] qsort [x] = [x] qsort (x:xs) = let smaller = qsort([y | y <- xs, y < x]) larger = qsort([y | y <- xs, y > x]) in smaller ++ (x:larger) 65/72
  • 65.
    Quicksort in F# letrec qsort:int list -> int list = function | [] -> [] | x::xs -> let smaller = [for a in xs do if a<=x then yield a] let larger = [for b in xs do if b>x then yield b] qsort smaller @ [x] @ qsort larger let rec qsort = function | [] -> [] | x::xs -> let smaller,larger = List.partition (fun y -> y<=x) xs qsort smaller @ [x] @ qsort larger 66/72
  • 66.
    Higher order functions •Functions taking other functions as parameters • Simple list functions map & filter o map fac [3,6,2,4] o filter odd [1,2,3,4,5,6,7] • More Complex list functies foldr & foldl o Reduce a list to one value • Using a combining function • And a starting value o Foldr (+) 0 [1,2,3,4,5,6] 67/72
  • 67.
    Recursion over functions repeatFun0 f value = value repeatFun n f value = repeatFun (n-1) f (f value) bubbleSort list = repeatFun(length list) bubble list bubble [] = [] bubble [x] = [x] bubble (x:y:ys) | x < y = x:(bubble (y:ys)) | otherwise = y:(bubble (x:ys)) 68/72
  • 68.
  • 69.
    Currying • Functions ofn arguments • Are actually functions of 1 argument o Returning a function of (n-1) argument • Which is actually of function of 1 argument • Returning a function of (n-2) arguments - … • Specialisation of functions contains2 = contains 2 70/72
  • 70.
    Open your mind! •Become a Better Developer with Functional Programming o http://www.oscon.com/oscon2011/public/schedule/detail/ 19191 Questions? 71/72
  • 71.
    More info aboutthe TETRA-project? 72/72 • http://www.vlambda.be/ • Contact Kris.Aerts@kuleuven.be or Tom Schrijvers .NET-productiviteit verhogen met een gepast gebruikt van lambda's en F# (en natuurlijk ook in Java ;-) Vlaamse software vlamt met lambda’s