Programmation Fonctionnelle

3 451 vues

Publié le

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

Aucun téléchargement
Vues
Nombre de vues
3 451
Sur SlideShare
0
Issues des intégrations
0
Intégrations
23
Actions
Partages
0
Téléchargements
63
Commentaires
0
J’aime
4
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Programmation Fonctionnelle

  1. 1. “Tout ce que vous avez toujours voulu savoir sur laprogrammation fonctionnelle* *sans jamais oser le demander” François Sarradin Xebia IT Architects
  2. 2. Programmation fonctionnelle Ce quon en dit...● "Bien pour la programmation concurrente"● "Moins de bugs"● To reduce cyclomatic complexity is far more important than to reduce the number of LOCs. Incidentally FP gives a great help to lower both -- @mariofusco● "Un autre point de vue sur son langage quotidien"● "Ça retourne le cerveau, pour le bien !"
  3. 3. Programmation fonctionnelle Ce quon en dit aussi...○ "Ellitiste"○ "Difficile à apprendre"○ "À ne pas mettre entre toutes les mains"○ "Purement académique"○ "Ça retourne le cerveau"
  4. 4. OK, mais... Quest-ce que laprogrammation fonctionnelle ?
  5. 5. Fonction Continuation Lazy evaluation Lambda calcul Récursion Curryfication Type algébrique Combinateur de Type system point fixe Monade Programmation Ordre Fonctionnelle supérieur Monoïde ClosureFunctor Point free map/filter/ Pattern matching fold/zip Inférence de type Transparence Catamorphisme référentielle Tail recursion
  6. 6. Au programme...● La base du style fonctionnel ○ Histoire de la programmation fonctionnelle ○ Récursion / Ordre supérieur / Déterminisme ○ Optimisation● Traitement de flux dinformations ○ Liste en programmation fonctionnelle ○ Fonctions sur listes● Conclusion● Hands On
  7. 7. Langages utilisés● Haskell (principalement)● Scala, Clojure, Erlang, etc.● Java + Guava (pour le Hands On)
  8. 8. Commençons
  9. 9. Soit la fonction factorielle "n! est le produit des entiers compris entre 1 et n"ou n! = 1 * ⋯ * n = Πi i , ∀ i ∈ [1..n]ou 0! = 1, n! = n . (n - 1)!, si n > 0.
  10. 10. Style FonctionnelImpératifint fact(int n): result = 1 for i in [1..n]: result = result * i return result (java) public int fact(int n) { if (n == 0) return 1; (clojure) else return n * fact(n-1); (defn fact [n] } (reduce * 1 (range 1 (inc n)))) (erlang) fact(0) -> 1; fact(N) -> N * fact(N - 1). (haskell) fact n = product [1..n]
  11. 11. Et aussi...Point freeComposition de fonctions + disparition des variablesContinuationFutur de la fonction en paramètreCombinateur de point fixePermet les fonctions anonymes et récursivesMonadeChaînage de traitements
  12. 12. Mais aussi des dérives...APL (A Programming Language) factorial←{ ⍺←1 ⍵=0:⍺ (⍺×⍵)∇ ⍵-1 }life←{ ↑1 ⍵∨.^3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵ }
  13. 13. Programmation fonctionnelle Principe n°1 : tout est fonction
  14. 14. Tout est fonction Au sens mathématique f(x) = 2.x x ↦ x + 42h(x, y) = ∂2 p(x, y) / ∂x2
  15. 15. Fonction Dans les langages fonctionnelsHaskellidentity x = xx -> xScaladef identity(x: Any) = x{ x: Any => x }Clojure(defn identity [x] x)(fn [x] x)
  16. 16. Fonction Avec Guavanew Function<T, R>() { @Override public R apply(T x) { return x; }}new Predicate<T>() { @Override public boolean apply(T x) { return x == null; }}
  17. 17. Programmation fonctionnelle Doù est-ce que ça vient ?
  18. 18. Fonction mathématique fin du XVIIe sièclef : x ↦ xf : x ↦ 2 . xouf(x) = 2 . x Gottfried Wilhelm von Leibniz (1646-1716)
  19. 19. Lambda-calcul 1936λx.x(λx.2*x) 7 → 2 * 7true ::= λxy.xfalse ::= λxy.yif-then-else ::= λpab.p a b0 ::= λfx.x1 ::= λfx.f x2 ::= λfx.f (f x) Alonzo Church (1903-1995)
  20. 20. LISP 1958(lambda (x) x)(f arg1 arg2 ...)(lambda (x) (* 2 x))(cons A B)(car (cons A B)) => A(cdr (cons A B)) => B John McCarthy (1927-2011)
  21. 21. Et ensuite...Lisp (1958) Scheme (1975) ISWIM (1966) Common Lisp (1984) ML (1973) Clojure (2007) Caml (1985) F# (2002) Haskell (1987) Scala (2003) APL (1964) FP (1977) J (1990) Forth (1970s) PostScript (1982) RPL (1984) Joy (2001) Prolog (1972) Erlang (1986)
  22. 22. Version "embarqué"● Langage ○ Java 8 (en 2012 ?) ○ Groovy ○ Python ○ Ruby ○ SmallTalk ○ ...● API Java ○ Guava ○ LambdaJ ○ TotallyLazy ○ FunctionalJava ○ FunkyJFunctional
  23. 23. Success stories● Banque / finance ○ Jane Street (OCaml) ○ Goldman Sachs (Erlang), CitiGroup (Clojure), ...● Réseaux sociaux ○ Twitter (Scala) ○ FourSquare (Scala/Lift) ○ Facebook (Erlang)● Télécommunication ○ Ericsson (Erlang)● Autres... ○ Microsoft (F#) ○ CouchDB, RabbitMQ (Erlang)
  24. 24. Programmation fonctionnelle Principe n°2 : récursion
  25. 25. RécursionProscrire Verboten ! def fact(n): ○ for r = 1 ○ while for i in [1..n]: ○ repeat r *= i ○ etc. return n Stateful !Boucle = fonction qui sappelle elle même fact n = if n == 0 then 1 else n * fact (n-1)
  26. 26. Récursion terminaleLappel récursif est la dernière instruction fact_t n k = if n == 0 then k else fact_t (n-1) (n*k) fact n = fact_t n 1
  27. 27. Récursion : pile dappelsfact n = if n == 0 then 1 else n * fact (n-1)-> fact(5) -> fact(4) -> fact(3) -> fact(2) -> fact(1) -> fact(0) <- 1 <- 1 * 1 = 1 <- 2 * 1 = 2 <- 3 * 2 = 6 <- 4 * 6 = 24<- 5 * 24 = 120
  28. 28. Récursion terminale : pile dappelsfact_t n k = if n == 0 then k else fact_t (n-1) (n*k)-> fact_t 5 1 -> fact_t 4 5 -> fact_t 3 20 -> fact_t 2 60 -> fact_t 1 120 -> fact_t 0 120 <- 120 <- 120 ...<- 120
  29. 29. Récursion : beware !
  30. 30. Programmation fonctionnelle Principe n°3 : ordre supérieur
  31. 31. Fonction dordre supérieur Fonction en paramètre Dérivée deriv(f, x) = d f(x) / dtApplication dune fonction sur chaque élément dune collection (Java 8 ?) Arrays.asList(1, 2, 3).map(x -> x * x)
  32. 32. Fonction dordre supérieur Fonction en sortie Additionneur (curryfier) add : x ↦ (y ↦ x + y) add_one = add 1 add_one 2 => 3 add_one 10 => 11
  33. 33. Fonction dordre supérieur ... ou les deux Composition f ∘ g : x ↦ f(g(x))
  34. 34. Ordre supérieur Apports● Généricité / Réutilisation du code● Extension du langage / DSL interne // Scala new Order to buy(100 sharesOf "IBM") maxUnitPrice 300 using premiumPricing new Order to sell(200 bondsOf "Sun") maxUnitPrice 300 using { (qty, unit) => qty * unit - 500 }
  35. 35. Programmation fonctionnelle Principe n°4 : déterminisme
  36. 36. Indépendance / Déterminisme f(x) = x + time() => NON ! f(x, t) = x + t => OUI ! ● Fonction = Opération déclarative ○ Indépendante + sans état interne + déterministeUne fonction retourne toujours la même valeur pourvu quonlui fournisse les mêmes paramètres=> Un bon point pour la programmation concurrente !=> (+) de testabilité, (-) deffet de bord
  37. 37. Immuabilité x = x + 1 => NON ! y = x + 1 => OUI ! ● Variable (fonctionnelle) = variable (mathématique) = constante (impératif) = final (Java)=> Encore un bon point pour la programmation concurrente !=> (-) deffet de bord
  38. 38. Programmation fonctionnelle Déterminisme => Optimisation
  39. 39. Optimisation Style trampolineOptimisation des fonctions récursives terminales def fact(n, k): if n == 0: return k return fact(n - 1, k * n)devient def fact(n, k): while not (n == 0): k = k * n n = n - 1 return k
  40. 40. OptimisationTransparence référentielleUne expression peut être remplacée par son résultat sanschanger le comportement du programmeMémoizationConserver en cache le résultat dune fonction selon sesparamètres
  41. 41. OptimisationFlot de contrôle non linéaireSi aucune dépendance ne les lient, 2 fonctions peuvent êtreappelées dans nimporte quel ordreÉvaluation retardéeÈvaluation selon le besoinGarbage collector-- Since 1958 --
  42. 42. Sucre syntaxiqueInférence de typeDéterminer automatiquement le type dune expression oudune fonctionPattern matchingAppliquer un traitement sur une valeur selon son "aspect"=> switch-case on steroid! value match { // Scala case 1 => ... case "hello" => ... case x:Int => ... case Symbol(a, b) => ... }
  43. 43. Programmation fonctionnelle Principe n°5 : liste
  44. 44. Liste Opérations de base (Haskell)Liste de vide []Ajouter un élément en tête 1 : [] == [1] 1 : [2, 3] == [1, 2, 3] 1 : 2 : 3 : [] == [1, 2, 3]Récupérer la tête head [1, 2, 3] == 1Récupérer la queue tail [1, 2, 3] == [2, 3]
  45. 45. Liste FinieHaskell[1,2,3,4,5] => [1, 2, 3, 4, 5][1..5] => [1, 2, 3, 4, 5][a..z] => "abcdefghijklmnopqrstuvwxyz"Scala(1 to 5) => Range(1, 2, 3, 4, 5)(a to z) => NumericRange(a, b,[...], y, z)Clojure(range 1 5) => (1 2 3 4)
  46. 46. Liste Vers linfini et au delà !Haskell[1..] => [1, 2, 3, 4, 5, ...tail [1..] => [2, 3, 4, 5, 6, ...take 3 [1..] => [1, 2, 3]take 3 (drop 5 [1..]) => [6, 7, 8]ScalaN/AClojure(range 1) => (1 2 3 4 5 6 ...
  47. 47. Et en Java + Guava Émuler les listes : iteratorIterator<Integer> oneToFiveIterator = new AbstractIterator<Integer>() { private int i = 1; @Override protected Integer computeNext() { if (i > 5) return endOfData(); else return i++; }};// évaluation retardée selon Java !
  48. 48. Et en Java + Guava Émuler les listes : iterableIterable<Integer> oneToFive = new Iterable<Integer>() { @Override public Iterator<Integer> iterator() { return oneToFiveIterator; }};assertThat(oneToFive) .containsExactly(1, 2, 3, 4, 5);
  49. 49. Et en Java + Guava Liste infinie : suite de 1Iterator<Integer> onesIterator = new AbstractIterator<Integer>() { @Override protected Integer computeNext() { return 1; }}Iterable<Integer> ones = new Iterable<Integer>() { @Override public Iterator<Integer> iterator() { return onesIterator; }}
  50. 50. Programmation fonctionnelle Opérations de traitement sur listes
  51. 51. Fonction sur liste map et filtermapApplique une transformation sur chaque élément dune liste => Guava : transform(iterable, function) Haskell map (+1) [1..5] => [2, 3, 4, 5, 6]filterConserve que les éléments satisfaisant un prédicat => Guava : filter(iterable, predicate) Haskell filter (> 3) [1..5] => [4, 5]
  52. 52. Fonction sur liste zipzipFusionne deux listes zipWith f [a1, ..., an] [b1, ..., bm] => [f(a1, b1), ..., f(an, bn)] si n < m Haskell zipWith (+) [1..5] [6..8] => [7, 9, 11]=> Pas déquivalent en Guava
  53. 53. Fonction sur liste fold/reducefoldAgrège les valeurs dune liste (somme, produit, liste, ...) foldl f a0 [b1, ..., bn] => a1 <- f(a0, b1) a2 <- f(a1, b2) ... an-1<- f(an-2, bn-1) return f(an-1, bn)=> Pas déquivalent en Guava
  54. 54. Fonction sur liste fold/reduceHaskellfoldl (+) 0 [1..5] => 15product l = foldl (*) 1 lfact n = product [1..n] = foldl (*) 1 [1..n]reverse l = foldl (flip (:)) [] lreverse [1..5] => [5, 4, 3, 2, 1]
  55. 55. En résuméLa programmation fonctionnelle, cest...
  56. 56. Particularité ● Tout est fonction ○ Fonction sur des valeurs (1er ordre) ○ Fonction sur des fonctions (ordre supérieur) ○ Indépendance / Déterminisme / Immuabilité ● Optimisations diverses ● Récursion ● Traitement sur listeEt plus encore...
  57. 57. Avantages ● Généricité / réutilisation / modularité ● Meilleure testabilité / fiabilité ● Adapter à la programmation concurrente ● ConcisionÉcrire du code avec un langage fonctionnel = écrire des spécifications formelles
  58. 58. Difficulté● Une façon de penser différente● Courbe dapprentissage ○ idiomes, patterns, best practices● Longtemps enfermée dans la communauté scientifique● Déclaratif ○ Pas de maîtrise du déroulement (plus quavec Java) ○ Bonne connaissance du compilateur/VM● Trop de concision tue la lisibilité
  59. 59. Littérature ● Miran Lipovača, Learn You a Haskell for Great Good! (LYAH). Avril 2011. http://learnyouahaskell.com/ ● Bryan OSullivan, Don Stewart, and John Goerzen, Real World Haskell (RWH). Novembre 2008. http://book.realworldhaskell.org/
  60. 60. Congrès et User Groups● International Conference on Functional Programming (ICFP), http: //www.icfpconference.org/● Commercial Users of Functional Programming (CUFP), http://cufp.org/● Scala Days● Clojure/conj● Paris Scala User Group (soirée - 1/mois)● Clojure Paris User Group (coding dojo - 1/semaine)
  61. 61. Sites webs● Haskell : http://haskell.org/ ○ API doc : http://haskell.org/ghc/docs/7.0-latest/html/libraries/index. html ○ Web console : http://tryhaskell.org/● Scala : http://www.scala-lang.org/ ○ API doc : http://www.scala-lang.org/api/current/index.html#package ○ Web console : http://www.simplyscala.com/● Clojure : http://clojure.org/ ○ API doc : http://clojure.github.com/clojure/, http://clojuredocs.org/ ○ Web console : http://try-clojure.org/
  62. 62. Hands On : ici...https://github.com/fsarradin/xke-fp

×