950 likes | 1.28k Views
Wat is functioneel programmeren?. Alles via functies. Wat is functioneel programmeren?. Alles via expressies die ge
E N D
1. Inleiding tot Functioneel Programmeren Kris Luyten en Jo Vermeulen
{kris.luyten,jo.vermeulen}@uhasselt.be
Expertise Centrum voor Digitale Media - Universiteit Hasselt
2. Wat is functioneel programmeren? Alles via functies
3. Wat is functioneel programmeren? Alles via expressies die geëvalueerd worden
4. Wat is functioneel programmeren? volgende 5 = 6
5. Wat is functioneel programmeren? volgende x = x+1
6. Wat is functioneel programmeren? volgende :: Integer -> Integer
volgende x = x+1
7. Wat is functioneel programmeren? volgende :: Integer -> Integer
volgende x = x+1
8. Wat is functioneel programmeren? fac 5 = 5 * 4 * 3 * 2 * 1
fac 4 = 4 * 3 * 2 * 1
9. Wat is functioneel programmeren? fac 5 = 5 * 4 * 3 * 2 * 1
fac 4 = 4 * 3 * 2 * 1
10. Wat is functioneel programmeren? fac 5 = 5 * (fac 4)
fac 4 = 4 * 3 * 2 * 1
11. Wat is functioneel programmeren? fac 5 = 5 * (fac 4)
fac 4 = 4 * 3 * 2 * 1
fac n = n * (n-1) * (n-2) * … * 2 * 1
fac n = n * fac (n-1)
12. Wat is functioneel programmeren? fac 5 = 5 * (fac 4)
fac 4 = 4 * 3 * 2 * 1
fac n = n * (n-1) * (n-2) * … * 2 * 1
fac :: Int -> Int
fac n = n * fac (n-1)
13. Waarom functioneel programmeren?
14. Waarom functioneel programmeren?
15. Waarom functioneel programmeren? Programmeren met functies
Geen “side effects”
Geen expliciete toekenning van waardes aan variabelen x := 4; x:= x + 9;
Gebaseerd op een goed gedefinieerde wiskundige basis (bijv. de lambda calculus)
Idempotente uitvoering van functies
Opnieuw uitvoeren geeft hetzelfde effect
16. Waarom functioneel programmeren? Programmeren met functies
Geen “side effects”
Geen expliciete toekenning van waardes aan variabelen x := 4; x:= x + 9;
Gebaseerd op een goed gedefinieerde wiskundige basis (bijv. de lambda calculus)
Idempotente uitvoering van functies
Opnieuw uitvoeren geeft hetzelfde effect Geen loops maar recursie!
Lijkt beetje op celibaat, onthouding van veel features om “cleaner” te zijn. Wat zijn nu de voordelen?Geen loops maar recursie!
Lijkt beetje op celibaat, onthouding van veel features om “cleaner” te zijn. Wat zijn nu de voordelen?
17. Waarom functioneel programmeren? Eenvoudig programmeerparadigma
Ingebouwde abstractie inclusief data abstractie (ADT)
Krachtige ondersteuning voor genericiteit, polymorfisme en overloading
18. Waarom functioneel programmeren? Correctheid
Paralleliseerbaarheid
Expressiviteit
Modulariteit
19. Waarom functioneel programmeren? Paralleliseerbaarheid 4 cores i.p.v. => ~4x sneller4 cores i.p.v. => ~4x sneller
20. Waarom functioneel programmeren? Betere modulariteit
21. Waarom functioneel programmeren? Betere modulariteit Niets meer dan “glue” om componenten aan elkaar te koppelen en code te hergebruiken.Niets meer dan “glue” om componenten aan elkaar te koppelen en code te hergebruiken.
22. Waarom functioneel programmeren? Toenemend belang in verschillende domeinen
Software engineering
Human-computer interaction
Web applicaties
Imperatieve en object-georienteerde programmeertalen (Python, Ruby, C#, Java, JavaScript, …)
23. Welke talen zijn er? Ik wil functioneel programmeren, met welke taal begin ik?
Lisp, Scheme, Guile
ML, Haskell, Ocaml, Mozart/Oz, Mercury,…
Ruby, Python,…
C, Java,…
XSLT
Talen verschillen in “zuiverheid”. Bijv. Scheme is niet side-effect free
24. Welke taal gebruiken wij? Haskell
http://www.haskell.org
Een luie en zuiver functionele programmeertaal
25. Lui? List makeList() {
List current = new List();
current.value = 1;
current.next = makeList();
return current;
}
makeList().getItem(10);
26. Lui? makeList = 1 : makeList
print makeList[10]
27. Zuiver? Geen side effects
Een functie die opgeroepen wordt met dezelfde parameters als voorheen zal gegarandeerd hetzelfde resultaat teruggeven
Houdt zich strikt aan de lambda calculus
28. Nog wat specifieke Haskell eigenschappen Case-sensitive
Functienamen starten altijd met kleine letter
Typenamen starten altijd met een grote letter
Indentatie
29. Software? GHC (compiler en interpreter)
Hugs (interpreter)
Helium (beperkte interpreter en compiler om Haskell aan te leren)
30. GHC Compiler:
Schrijf Haskell programma en bewaar in een .hs bestand
Compileer met: “ghc –o naam naam.hs”
Voer ./naam uit
Interpreter
Start ghci naam.hs
Of :load naam.hs als ghci opgestart is
Verlaat de shell met :quit
31. Hallo Wereld
32. fac
33. fac
34. fac
35. fac
36. Basis bewerkingen
37. Paren en Triples
38. Lijsten Cons == constructing
[0,1,3,5] = syntactic sugarCons == constructing
[0,1,3,5] = syntactic sugar
39. Lijsten
40. Strings “hallo” is syntactic sugar“hallo” is syntactic sugar
41. Concatenatie ++ concateneert twee lijsten
(x:xs) ++ (y:ys)
[] ++ []
x ++ y
(x:xs) ++ y
(x:xs) ++ (y:[])
: voegt een element toe vooraan een lijst
x: [a,b,c]
x:(y:xs)
(y:xs):x
Probeer de voorbeeldjes uit met ghci. Wat werkt er en wat niet?
42. length Bij name clashes, verander naam (myLength). Leg uit hoe signatures werken.Bij name clashes, verander naam (myLength). Leg uit hoe signatures werken.
43. zip
44. Signatures lezen Laatste is altijd output.Laatste is altijd output.
45. zip Hoe moet je nu die signature lezenHoe moet je nu die signature lezen
46. zip
47. foldr Pas operatie toe op de elementen van een lijst
Operaties zijn eerste klasse waardes in een functionele programmeertaal!
foldr vervangt “:” door een operatie en [] door een initieel element
foldr is rechts-associatief
Ook wel reduce (Python), inject (Ruby/Smalltalk), accumulate (C++) genoemd.
Voorbeeld van eerste klasse operaties is bv. lijst filteren met boolean functie. Anders moet telkens met for loop.Ook wel reduce (Python), inject (Ruby/Smalltalk), accumulate (C++) genoemd.
Voorbeeld van eerste klasse operaties is bv. lijst filteren met boolean functie. Anders moet telkens met for loop.
48. foldr
49. foldr
50. foldl
51. foldl
52. map
53. map
54. map
55. map
56. map
57. map
58. Quicksort in twee regels…
59. Quicksort
60. Quicksort in twee regels…
61. Quicksort in twee regels…
62. Quicksort in twee regels… Y element van xsY element van xs
63. List comprehension Backticks betekenen infix notatieBackticks betekenen infix notatie
64. List comprehension
65. List comprehension
66. List comprehension
67. Guards: switch met pattern matching Condities in de functie
Gelijkaardig met een switch statement in C
Evaluatie gebeurt na pattern matching!
68. Guards: switch met pattern matching
69. Guards: switch met pattern matching
70. Guards: switch met pattern matching
71. …iets moeilijker: priemfactorisatie
72. maar nog steeds makkelijker dan in een imperatieve taal!
73. Prelude.hs De standaard Haskell library met een schat aan voorgedefinieerde functies
http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html
Ook handig om zelf Haskell mee te leren
74. Types Karakters en Strings
Numerieke types: Integer, Float,…
Boolean: True en False
Logische en: &&, logische of: || en negatie: not
Polymorfe types “a”
Worden afgeleid door Haskell zelf
Types makkelijk uitbreidbaar dankzij type classes (behandelen we niet)
75. Types
76. Currying
77. Currying Som :: (Int,Int)->Int kan Som :: Int->Int->Int worden
“Som 5 6” is een functie, maar “Som 5” kan evengoed gebruikt worden als argument voor een andere functie (bijv. de map functie)
Functies worden beter herbruikbaar
“Partiele” functies als argument
Functies samenstellen (f en g wordt f.g)
78. Evaluatie Strategie Op welke manier wordt een expressie geevalueerd?
De manier waarop argumenten van een functie worden geevalueerd bij een functie-oproep.
Strikte versus niet-strikte evaluatie
Strikt: parameters functie wordt gevalueerd voor uitvoering functie
Niet-strikt: parameters functie worden niet geevalueerd tenzij deze gebruikt worden. Evaluatie van de parameters gebeurt dan niet noodzakelijk voor de uitvoering van de functie
79. Call-by-Value: parameter expressies worden geevalueerd en toegekend aan een variabele naam (copy!) voor uitvoering functie.
Strikte evaluatie
80. Call-by-Reference: : parameter expressies worden geevalueerd en een variabele naam verwijst naar de waarde (referentie naar geheugen!) voor uitvoering functie. Strikte evaluatie
81. Niet-strikte evaluatie Call-by-Name: iedere verwijzing naar de expressie wordt vervangen door de expressie zelf. De expressie wordt opnieuw geevalueerd bij elke gebruik ervan.
82. Niet-strikte evaluatie Call-by-Name: iedere verwijzing naar de expressie wordt vervangen door de expressie zelf. De expressie wordt opnieuw geevalueerd bij elke gebruik ervan.
83. Niet-strikte evaluatie Call-by-Need: werkt zoals call-by-name maar na de eerste evaluatie wordt die waarde verder gebruik. In pure functionele programmeertalen is het effect hetzelfde als call-by-name en wordt vaak “Lazy Evaluation” genoemd.
84. Functies samenvoegen Verschillende functies samen voegen met “.”
Uitvoer van functie wordt invoer van andere functie
“ f . g “ betekent dat de functie f na g wordt uitgevoerd met als input van f de output van g
85. Functies samenvoegen Leg uit wat het volgende stukje code doet:
86. Oefeningen set 1 (makkelijk) Schrijf de volgende functies
Omdraaien van een lijst (in: [1,2,5], uit: [5,2,1])
Roteren van een lijst (in: [1,2,3,4], uit: [4,1,2,3])
Combineer (herbruik) beide functies in een nieuwe functie roteerdraaiom (in: [1,2,3,4], uit: [1,4,3,2])
Schrijf de volgende functies die een functie toepassen
Gebruik de map functie om de functies “omdraaien” en “roteren” toe te passen op een lijst van lijsten
Schrijf een functie max:: Int->Int->Int die het maximum van twee integers teruggeeft en pas die met foldl (of foldr) toe op een constante en een lijst van integers
87. Oefeningen set 2 (makkelijk) Schrijf een functie optellen :: Int -> Int die de eenheden van een getal bij elkaar optelt. optellen 1500 = 6 optellen 123456 = 21
Schrijf een functie die graden celcius naar graden farenheit omzet. Schrijf tevens de functie die graden farenheit naar celcius omzet.
Schrijf een functie die gegeven een lijst de duplicaten uit die lijst verwijdert
88. Oefeningen set 3 (medium) Schrijf een functie die de lijst van fibonacci nummers genereert (gebruik de luie eigenschap van Haskell). Schrijf een andere functie die de eerste n elementen uitschrijft van de lijst. Laat de gebruiker n zelf ingeven.
Schrijf een functie bevat :: [Int]->[Int]->Bool die gegeven twee lijsten teruggeeft of de sequentie van elementen van de eerste lijst ook voorkomt in de tweede lijst. Bijv. bevat [1,2] [6,10,1,2.8] = True en bevat [1,8] [8,8,7] = False
89. Oefeningen set 4 (medium-moeilijk) Jolly Jumpers: een lijst getallen van lengte n noemt men jolly jumpers als het verschil tussen opeenvolgende getallen alle waardes tussen 0 en n aanneemt. Zo is de lijst 1,4,2,3 een jolly jumper omdat de verschillen tussen de opeenvolgende getallen 3,2 en 1 zijn. Schrijf een functie jjumpers :: [Int] -> Bool die True teruggeeft als de lijst een jolly jumper is.
90. Oefeningen set 4 (medium-moeilijk) Schrijf een programma dat een nummer N in leest en een lijst teruggeeft van alle Smith nummers tussen 0 en N. Hergebruik primefactors hiervoor. Een Smith getal is een getal waarvan de som van de eenheden van de priemfactorisatie gelijk is aan de som van de eenheden van het getal. Bijvoorbeeld: 378 = 2 × 3 × 3 × 3 × 7 en 3 + 7 + 8 = 2 + 3 + 3 + 3 + 7
Zorg ervoor dat er geen priemgetallen in de lijst voorkomen
Geef een lijst van alle “Smith broers”: twee opeenvolgende getallen die beide Smith getallen zijn zoals […,(94094, 94095), (94184, 94185), (94584, 94585),…]
Geef enkel Smith nummers die een palindroom zijn, zoals 454
91. Oefeningen Meer oefeningen maken?
http://www.haskell.org/haskellwiki/99_Haskell_exercises
http://www.haskell.org/haskellwiki/Blog_articles/Exercises
92. Referenties Haskell: The Craft of Functional Programming (second edition), Simon Thompson
Haskell Wikibook; http://en.wikibooks.org/wiki/Haskell
A gentle introduction to Haskell, Paul Hudak, John Peterson, Joseph Fasel; http://www.haskell.org/tutorial/
Yet Another Haskell Tutorial: http://en.wikibooks.org/wiki/Haskell/YAHT
http://www.haskell.org
Voor de beslagen programmeur: The Haskell School of Expression: Learning Functional Programming through Multimedia, Paul Hudak, http://www.haskell.org/soe/
Leuk om te weten: Wearing the hair shirt: a retrospective on Haskell, Simon Peyton Jones. http://research.microsoft.com/~simonpj/papers/haskell-retrospective/
93. Ook interessant (1)
94. Ook interessant (2)
95. Ook interessant (3)