Presentation of GetTogether on Functional Programming
Post on 16-Apr-2017
220 Views
Preview:
Transcript
Functional ProgrammingPutting 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 .NETo 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
ProgrammingLanguages
Computer Science
Society
MoreSoftware
Agoria: ’9300 unfilled ICT positions'
Productivity Reliability
8
ANP: ‘Software bugs cost1.6 billion € a year’
Bug-Free Software
Meeting the ChallengesIncremental ResearchMainstream languages
Fundamental Research
A different approachto languages
Mainstream languages
9
Historical Evolution
imperativelanguages
objectorientation
mathematics
hardware
mainstream
alternative
declarativelanguages
10
1953Fortran
1958Cobol
1969CAlgol
1959 1971Smalltalk Eiffel
19851983C++
Declarative LanguagesFunctionalProgramming
Haskell
LogicProgramming
Prolog
ConstraintProgrammingMiniZinc
11
Recent Developments
imperativelanguages
objectorientation
mathematics
hardware
mainstream
declarativelanguages
research
12
Anonymous Functions
λ calculus1936
AlonzoChurch
1958Lisp
JohnMcCarthy
1973ML
RobinMilner
1987Haskell
HaskellCommittee
2014Java 8
Swift2011
C++11
Functional Languages Mainstream
2007C#
14
15/72
Early AdoptersHaskell Language + GHC Compiler
Finance Many OthersTelecom
16
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 executiono verifiable
How• What machine to use• When to use which
features of machine• What steps to set
• Programmer considered intelligento 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 useo von Neumann architecture
• When to use which features of machineo Variables = registers
• What steps to seto Order of executiono 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 magico Functional Programming
• functions with parameters returning values• Much like functions and/or methodes
• Buto 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 inferenceo “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 = 18o y = sin(z)
• Complex expressions are calculated by evaluating and substituting subexpressionso (z + sin(z))*(y+cos(y))
• Function calls behave exactly the sameo Always call by valueo Always return valueo 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 alwayso 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)/yPlus1in 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 valueo Mathematically sound
• Implicit parallellismo Order of execution can be chosen, both at compile and run
timeo Synchronisation: locking issues when dependencies
• Formal reasoningo Automated correctness and equivalence proofso More transparant codeo No underlying dependency from mutable states
34/72
Side EffectsTraditional MainstreamLanguages Oops,
unexpectedinterference
35
No Side EffectsTraditional DeclarativeLanguages
No Side-Effects,No Problem
Traditional MainstreamLanguages
No Side-Effects,No Party
Mathematical Elegance
Predictable
No Interference
✓✓✓
36
Explicit Side EffectsState-of-the-Art DeclarativeLanguages
Explicit Side-Effects,No Problem
Mathematical Elegance
Predictable
Explicit Interference
✓✓✓
37
How to return many values?• Imperative programs
o Return 1 value from functiono And others as ‘out’ parameters (using call by reference)
• OO programs using only call by valueo Define a container class for each combination of typeso Cumbersome…
• FP-languages use tuples (x,y) , (x,y,z) , (a,b,c,d), …o Flexible in number of elementso Flexible in composing types
38/72
Recursion = “looping” (1)
From definition to coden! = n*(n-1)!
With base case 1! = 1
• Haskell
o fac 1 = 1o 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 coden! = 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 = accfac‘ 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
3. Calculate numberOfDivisors and isPriem
44/72
Solutions in Haskellherm 1 = 1herm 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 languageso 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 Haskellfac 1 = 1fac n = n * fac (n-1)
findValue [] y = FalsefindValue (x:xs) y = if x == y then True
else findValue xs y
evenElems [] = TrueevenElems [x] = FalseevenElems (x:y:ys) = evenElems ys
48/72
Pattern matching in F#findValue [] y = FalsefindValue (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/560339o 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=3if (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 functionso Human :: Integer -> String -> Sexe -> Humano age :: Human -> Integero name :: Human -> Stringo sexe :: Human -> Sexe
52/72
Insert sort in Haskellisort [ ] = [ ]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]
• Similaro halfList :: [a] -> [a]o findValue :: Eq a => [a] -> a -> Boolo 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
functiono Depending on the functions that are being used
• Programmer doesn’t need to define typeso But a type mismatch results in a compile time erroro Indicating a mistake in the reasoningo Whenever type inference succeeds most programs run
correctly
58/72
Type inference in .NET• More and more available
59/72
List Comprehensions in HaskellVery declarative constructor
-- give all even numbers of a listevens 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 HaskellVery declarative constructor
-- give all even numbers of a listevens 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 spil2. Elements bigger than spil
3. Quicksort each sublist (recursively ;-)4. Join the sorted lists together
64/72
Quicksort in Haskellqsort [] = []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 & filtero map fac [3,6,2,4]o filter odd [1,2,3,4,5,6,7]
• More Complex list functies foldr & foldlo 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 = valuerepeatFun n f value = repeatFun (n-1) f (f value)
bubbleSort list = repeatFun(length list) bubble listbubble [] = []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 functionscontains2 = contains 2
70/72
Open your mind!• Become a Better Developer with Functional
Programmingo 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
top related