Programmation fonctionnelle

459 vues

Publié le

...par Raphaël Javaux, le 25 mars 2015.

Copie pour permettre le téléchargement L'original se trouve ici : https://docs.google.com/presentation/d/1A87M-e3u1uXlsQddGsI60EZXHVqiehaNy_SCfj7hUeQ/pub?start=false&loop=false&delayms=3000&slide=id.p

Publié dans : Logiciels
0 commentaire
1 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Nombre de vues
459
Sur SlideShare
0
Issues des intégrations
0
Intégrations
7
Actions
Partages
0
Téléchargements
29
Commentaires
0
J’aime
1
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Programmation fonctionnelle

  1. 1. La programmation fonctionnelle En 45 minutes Raphael Javaux
  2. 2. Plan ● Kesako ? ● Haskell ○ “An advanced purely-functional programming language” ● Stuff ● Real world stuff ● Aller plus loin
  3. 3. Plan ● Kesako ? ● Haskell ○ “An advanced purely-functional programming language” ● Stuff ● Real world stuff ● Aller plus loin
  4. 4. >>> xs = [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> map(lambda x: x * x, xs) [1, 4, 9, 16, 25, 36, 49, 64, 81] Kesako ? λ ?
  5. 5. >>> xs = [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> map(lambda x: x * x, xs) [1, 4, 9, 16, 25, 36, 49, 64, 81] Kesako ? λ ? Pas vraiment ...
  6. 6. Kesako ? « La programmation fonctionnelle est un style de programmation qui met l'accent sur l'évaluation d’ expressions, plutôt que sur l'exécution de commandes. » Graham Hutton
  7. 7. Kesako ? Les programmes impératifs sont des séquences d’instructions void estPair(int x) { if (x % 2 == 0) printf("x est pair !n"); else printf("x est impair !n"); } Temps Fais ça puis ça puis ça ...
  8. 8. Kesako ? La programmation fonctionnelle retire cette notion de temps.
  9. 9. “The world's most popular functional language”
  10. 10. Kesako ? Comment ? Une fonction ou une expression accepte des données en entrée et en retourne de nouvelles. Mais ne modifie aucun état global, ni aucun de ses arguments.
  11. 11. Kesako ? Comment ? ● Pas de modification des données ○ Pour modifier une donnée, on en crée une nouvelle copie ● Pas d’effet de bord ○ Pas de modification de variables globales ○ Pas d’entrée/sortie
  12. 12. Kesako ? struct rect_t { int x, y, width, height; } void move(rect_t *rect, int dx, int dy) { rect->x += dx; rect->y += dy; } struct rect_t { int x, y, width, height; } rect_t move(rect_t rect, int dx, int dy) { return { .x = rect.x + dx, .y = rect.y + dy, .width = rect.width, .height = rect.height }; } Impératif Fonctionnel
  13. 13. Kesako ? rect_t my_rectangle() { rect_t rect = { .x = 0, .y = 0, .width = 100, .height = 100 }; move(&rect, 10, 10); return rect; } rect_t my_rectangle() { rect_t rect = { .x = 0, .y = 0, .width = 100, .height = 100 }; return move(rect, 10, 10); } Impératif Fonctionnel
  14. 14. Kesako ? ● Les fonctions sont : ○ déterministes ○ plus facilement testables ○ thread-safes ○ plus modulables ○ plus réutilisables ● Code plus facilement lisible ● Moins d’erreurs ● Optimisations ● Performances ○ Mais pas toujours ... ● Pas d’entrées/sorties Avantages Désavantages
  15. 15. Récursion ? Impératif Fonctionnel int sum_n(int n) { int sum = 0; for (int i = 1; i <= n; i++) sum += i; return sum; } Modification de variable
  16. 16. Récursion int sum_n(int n) { int sum = 0; for (int i = 1; i <= n; i++) sum += i; return sum; } int sum_n(int n) { if (n <= 0) return 0; else return n + sum_n(n - 1); } Impératif Fonctionnel int sum_n(int n) { int sum = 0; for (int i = 1; i <= n; i++) sum += i; return sum; } Modification de variable
  17. 17. Plan ● Kesako ? ● Haskell ○ “An advanced purely-functional programming language” ● Stuff ● Real world stuff ● Aller plus loin
  18. 18. Haskell - Syntaxe -- Tous les opérateurs sont des fonctions (+) :: Int -> Int -> Int -- Les fonctions sont des valeurs add :: Int -> Int -> Int add = + -- Une fonction a 2 arguments est une -- fonction à 1 argument qui retourne -- une fonction à 1 argument ! next :: Int -> Int next = add 1 -- Ou directement next = + 1 two = next 1 -- Equivalent à “add 1 1” pi :: Double pi = 3.1416 square :: Int -> Int square x = x * x -- Pas de parenthèse pour les appels de -- fonctions four :: Int four = square 2 -- Pattern matching isFive 5 = True isFive x = False -- Récursion sumN n = if n <= 0 then 0 else n + sumN (n - 1)
  19. 19. Haskell - Listes -- Liste vide empty :: [Int] empty = [] -- ":" permet d'ajouter un élément au début de la liste (:) :: Int -> [Int] -> [Int] one :: [Int] one = 1 : empty xs :: [Int] xs = 1 : 2 : 3 : 4 : 5 : [] -- Equivalent à : xs = [ 1, 2, 3, 4, 5 ] -- Pattern matching sur ":" et "[]" length :: [Int] -> Int length [] = 0 length (y : ys) = 1 + length ys -- Concaténation de deux listes avec "++" (++) :: [Int] -> [Int] -> [Int] [] ++ zs = zs (y : ys) ++ zs = y : (ys ++ zs) -- Donne les premiers éléments d'une liste take n [] = [] take 0 ys = [] take n (y : ys) = y : take (n - 1) ys xs = : 1 2: 3: 4: 5: []
  20. 20. Plan ● Kesako ? ● Haskell ○ “An advanced purely-functional programming language” ● Stuff ● Real world stuff ● Aller plus loin
  21. 21. Stuff - Higher-order functions -- Les fonctions peuvent elles-mêmes -- recevoir des fonctions en argument : map :: (Int -> Int) -> [Int] -> [Int] map f [] = [] map f (x : xs) = f x : map f xs filter :: (Int -> Bool) -> [Int] -> [Int] filter p [] = [] filter p (x : xs) = if p x then x : filter p xs else filter p xs >>> map square [ 1, 2, 3, 4, 5 ] [ 1, 4, 9, 16, 25 ] >>> filter (> 3) [ 10, 2, 3, 5, 0, 7 ] [ 10, 5, 7 ]
  22. 22. Stuff - Quick Sort ! qsort [ 5, 2, 3, 10, 0, 7 ] qsort [ 2, 3, 0 ] ++ [ 5 ] ++ qsort [ 7, 10 ] qsort [ 0 ] ++ [ 2 ] ++ qsort [ 3 ] qsort [] ++ [ 7 ] ++ qsort [ 10 ] [] ++ [ 0 ] ++ [] [] ++ [ 3 ] ++ [] [] ++ [ 10 ] ++ []
  23. 23. qsort [ 5, 2, 3, 10, 0, 7 ] qsort [ 2, 3, 0 ] ++ [ 5 ] ++ qsort [ 7, 10 ] qsort [ 0 ] ++ [ 2 ] ++ qsort [ 3 ] qsort [] ++ [ 5 ] ++ qsort [ 10 ] [] ++ [ 0 ] ++ [] [] ++ [ 3 ] ++ [] [] ++ [ 10 ] ++ [] Stuff - Quick Sort ! qsort :: [Int] -> [Int] qsort [] = [] qsort (x : xs) = qsort lesser ++ [ x ] ++ qsort greater where lesser = filter (<= x) xs greater = filter (> x) xs
  24. 24. Stuff - Quick Sort ! >>> qsort oneMillion 5.05 secs
  25. 25. Stuff - Quick Sort ! >>> qsort oneMillion 5.05 secs >>> take 100 (qsort oneMillion)
  26. 26. Stuff - Haskell is lazy >>> qsort oneMillion 5.05 secs >>> take 100 (qsort oneMillion) 0.48 secs WTF ?!!?
  27. 27. Stuff - Haskell is lazy ● Haskell est un langage à évaluation « paresseuse » ○ Une donnée calculée que lorsqu’elle est accèdée pour la première fois ● Chaque noeud d’une liste est une donnée : 1 2: []
  28. 28. Stuff - Haskell is lazy take 3 (qsort [ 5, 2, 3, 10, 0, 7 ]) qsort [ 2, 3, 0 ] ++ [ 5 ] ++ qsort [ 7, 10 ] qsort [ 0 ] ++ [ 2 ] ++ qsort [ 3 ] qsort [] ++ [ 5 ] ++ qsort [ 10 ] [] ++ [ 0 ] ++ [] [] ++ [ 3 ] ++ [] [] ++ [ 10 ] ++ [] ● Haskell est un langage à évaluation « paresseuse » ○ Une donnée calculée que lorsqu’elle est accèdée pour la première fois ● Chaque noeud d’une liste est une donnée : 1 2: []
  29. 29. Plan ● Kesako ? ● Haskell ○ “An advanced purely-functional programming language” ● Stuff ● Real world stuff ● Aller plus loin
  30. 30. Real world stuff - Entrées sorties IO Fonctionnel
  31. 31. Real world stuff - Entrées et sorties -- Les fonctions ayant des effets de bords retournent “ IO a ”, -- où “ a ” est la valeur retournée. -- “ () ” est l'équivalent de “ void ”. putStrLn :: Text -> IO () readFile :: FilePath -> IO Text writeFile :: FilePath -> Text -> IO () getArgs :: IO [Text]
  32. 32. Real world stuff - Entrées et sorties -- “ do ” permet de séquencer des fonctions à effets de bord -- comme dans un langage impératif. -- “ <- ” permet de récupérer le résutat d’une “ IO ”. main :: IO () main = do [ path ] <- getArgs c <- readFile path putStrLn c
  33. 33. Real world stuff - Grep $ grep "Maître" le_corbeau_et_le_renard.txt Maître Corbeau, sur un arbre perché, Maître Renard, par l’odeur alléché,
  34. 34. Real world stuff - Grep lines :: Text -> [Text] unlines :: [Text] -> Text isInfixOf :: Text -> Text -> Bool grep :: Text -> Text -> Text grep pattern text = unlines matches where ls = lines text matches = filter (isInfixOf pattern) ls main = do [pattern, path] <- getArgs text <- readFile path putStrLn (grep pattern text)
  35. 35. Real world stuff - Grep $ du -h de_bello_gallico.txt 144K de_bello_gallico.txt $ grep "Belg" de_bello_gallico.txt [ 26 lignes ... ] 0.003 secs (1 868 870 cycles CPU) $ ./GrepHS "Belg" de_bello_gallico.txt [ 26 lignes ... ] 0.008 secs (6 603 153 cycles CPU, GC : 1.4%) - Mem. max. : 1 MB
  36. 36. Real world stuff - Grep $ du -h de_bello_gallico_large.txt 141M de_bello_gallico_large.txt $ grep "Belg" de_bello_gallico_large.txt [ 26 000 lignes ... ] 0.0988 secs (326 516 484 cycles CPU) $ ./GrepHS "Belg" de_bello_gallico_large.txt [ 26 000 lignes ... ] 1.632 secs (5 973 858 671 cycles CPU, GC : 0.5 %) - Mem. max. : 1 MB
  37. 37. Real world stuff - Haskell lazy again ! $ du -h de_bello_gallico_large.txt 141M de_bello_gallico_large.txt $ grep "Belg" de_bello_gallico_large.txt [ 26 000 lignes ... ] 0.0988 secs (326 516 484 cycles CPU) $ ./GrepHS "Belg" de_bello_gallico_large.txt [ 26 000 lignes ... ] 1.632 secs (5 973 858 671 cycles CPU, GC : 0.5 %) - Mem. max. : 1 MB WTF ?!!?? text <- readFile path putStrLn (grep pattern text)
  38. 38. Real world stuff - Haskell lazy again ! text = [] : alléchénLui tint à peu près ce langage :n"Hé ! bonjour, Monsieur du Corbeau.nQue vous êtes joli : êtes le Phenix des hôtes de ces bois.nÀ ces mots le Corbeau ne se sent pas de joie :nEt pour montrer : ! que vous me semblez beau !nSans mentir, si votre ramagenSe rapporte à votre plumage,nVous : sa belle voix,nIl ouvre un large bec, laisse tomber sa proie.nLe Renard s’en saisit, et dit : Mon bon : un fromage sans doute.nLe Corbeau honteux et confusnJura, qu’on ne l’y prendrait plus. : Monsieur,nApprenez que tout flatteurnVit aux dépens de celui qui l’écoute.nCette leçon vaut bien Maître Corbeau sur un arbre perché,nTenait en son bec un fromage.nMaître Renard par l’odeur:
  39. 39. Plan ● Kesako ? ● Haskell ○ “An advanced purely-functional programming language” ● Stuff ● Real world stuff ● Aller plus loin
  40. 40. Aller plus loin - Pourquoi ? ● Programmer ... ○ … plus modulable ○ … plus réutilisable ○ … plus rigoureusement ● Monstrueusement efficace pour ... ○ … la programmation parallèle et concurrente ○ … le backend et les réseaux ● De plus en plus de langages tendent vers le paradigme
  41. 41. Aller plus loin - Langages Fonctionnel O rienté objet Im pératif LISPs
  42. 42. Aller plus loin - Langages Fonctionnel O rienté objet Im pératif LISPs Microsoft .NET Java VM Réseaux et haute disponibilité Très bas niveau
  43. 43. Aller plus loin - Langages Fonctionnel O rienté objet Im pératif LISPs
  44. 44. Moyenne sur 13 benchmarks Source : http://benchmarksgame.alioth.debian.org/u64q/which-programs-are-fastest.html
  45. 45. Benchmark des context-switchs. Source : http://benchmarksgame.alioth.debian.org/u64q/performance.php?test=threadring

×