“Tout ce que vous avez  toujours voulu savoir sur laprogrammation fonctionnelle*     *sans jamais oser le demander”       ...
Programmation fonctionnelle                       Ce quon en dit...●   "Bien pour la programmation concurrente"●   "Moins ...
Programmation fonctionnelle                    Ce quon en dit aussi...○ "Ellitiste"○ "Difficile à apprendre"○   "À ne pas ...
OK, mais...      Quest-ce que laprogrammation fonctionnelle ?
Fonction       Continuation                                           Lazy evaluation       Lambda calcul  Récursion      ...
Au programme...● La base du style fonctionnel   ○ Histoire de la programmation fonctionnelle   ○ Récursion / Ordre supérie...
Langages utilisés● Haskell (principalement)● Scala, Clojure, Erlang, etc.● Java + Guava (pour le Hands On)
Commençons
Soit la fonction factorielle          "n! est le produit des entiers compris entre 1 et n"ou     n!    = 1 * ⋯ * n        ...
Style                           FonctionnelImpératifint fact(int n):    result = 1    for i in [1..n]:        result = res...
Et aussi...Point freeComposition de fonctions + disparition des variablesContinuationFutur de la fonction en paramètreComb...
Mais aussi des dérives...APL (A Programming Language)                    factorial←{                        ⍺←1           ...
Programmation fonctionnelle     Principe n°1 : tout est fonction
Tout est fonction    Au sens mathématique        f(x) = 2.x       x ↦ x + 42h(x, y) = ∂2 p(x, y) / ∂x2
Fonction             Dans les langages fonctionnelsHaskellidentity x = xx -> xScaladef identity(x: Any) = x{ x: Any => x }...
Fonction                   Avec Guavanew Function<T, R>() {    @Override    public R apply(T x) {        return x;    }}ne...
Programmation fonctionnelle      Doù est-ce que ça vient ?
Fonction mathématique                     fin du XVIIe sièclef : x ↦ xf : x ↦ 2 . xouf(x) = 2 . x                         ...
Lambda-calcul                     1936λx.x(λx.2*x) 7 → 2 * 7true ::= λxy.xfalse ::= λxy.yif-then-else ::= λpab.p a b0 ::= ...
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 ...
Et ensuite...Lisp (1958)   Scheme (1975)                     ISWIM (1966)   Common Lisp (1984)                  ML (1973) ...
Version "embarqué"● Langage   ○ Java 8 (en 2012 ?)   ○ Groovy   ○ Python   ○ Ruby   ○ SmallTalk   ○ ...● API Java   ○ Guav...
Success stories● Banque / finance   ○ Jane Street (OCaml)   ○ Goldman Sachs (Erlang), CitiGroup (Clojure), ...● Réseaux so...
Programmation fonctionnelle       Principe n°2 : récursion
RécursionProscrire   Verboten !            def fact(n):   ○ for                             r = 1   ○ while               ...
Récursion terminaleLappel récursif est la dernière instruction   fact_t n k = if n == 0                       then k      ...
Récursion : pile dappelsfact n = if n == 0            then 1            else n * fact (n-1)-> fact(5)  -> fact(4)    -> fa...
Récursion terminale : pile dappelsfact_t n k = if n == 0             then k             else fact_t (n-1) (n*k)-> fact_t 5...
Récursion : beware !
Programmation fonctionnelle     Principe n°3 : ordre supérieur
Fonction dordre supérieur                 Fonction en paramètre                      Dérivée                deriv(f, x) = ...
Fonction dordre supérieur       Fonction en sortie   Additionneur (curryfier)     add : x ↦ (y ↦ x + y)     add_one = add ...
Fonction dordre supérieur         ... ou les deux        Composition       f ∘ g : x ↦ f(g(x))
Ordre supérieur                         Apports● Généricité / Réutilisation du code● Extension du langage / DSL interne  /...
Programmation fonctionnelle      Principe n°4 : déterminisme
Indépendance / Déterminisme       f(x) = x + time()              =>    NON !       f(x, t) = x + t                =>    OU...
Immuabilité             x = x + 1         =>    NON !             y = x + 1         =>    OUI ! ● Variable (fonctionnelle)...
Programmation fonctionnelle   Déterminisme => Optimisation
Optimisation                        Style trampolineOptimisation des fonctions récursives terminales   def fact(n, k):    ...
OptimisationTransparence référentielleUne expression peut être remplacée par son résultat sanschanger le comportement du p...
OptimisationFlot de contrôle non linéaireSi aucune dépendance ne les lient, 2 fonctions peuvent êtreappelées dans nimporte...
Sucre syntaxiqueInférence de typeDéterminer automatiquement le type dune expression oudune fonctionPattern matchingAppliqu...
Programmation fonctionnelle        Principe n°5 : liste
Liste                Opérations de base (Haskell)Liste de vide    []Ajouter un élément en tête   1 : []              == [1...
Liste                           FinieHaskell[1,2,3,4,5]       => [1, 2, 3, 4, 5][1..5]            => [1, 2, 3, 4, 5][a..z]...
Liste                  Vers linfini et au delà !Haskell[1..]          => [1, 2, 3, 4, 5, ...tail [1..]     => [2, 3, 4, 5,...
Et en Java + Guava             Émuler les listes : iteratorIterator<Integer> oneToFiveIterator  = new AbstractIterator<Int...
Et en Java + Guava              Émuler les listes : iterableIterable<Integer> oneToFive  = new Iterable<Integer>() {     @...
Et en Java + Guava              Liste infinie : suite de 1Iterator<Integer> onesIterator  = new AbstractIterator<Integer>(...
Programmation fonctionnelle    Opérations de traitement sur listes
Fonction sur liste                         map et filtermapApplique une transformation sur chaque élément dune liste   => ...
Fonction sur liste                                    zipzipFusionne deux listes   zipWith f [a1, ..., an] [b1, ..., bm] =...
Fonction sur liste                               fold/reducefoldAgrège les valeurs dune liste (somme, produit, liste, ...)...
Fonction sur liste                   fold/reduceHaskellfoldl (+) 0 [1..5] => 15product l = foldl (*) 1 lfact n = product [...
En résuméLa programmation fonctionnelle, cest...
Particularité ● Tout est fonction    ○ Fonction sur des valeurs (1er ordre)    ○ Fonction sur des fonctions (ordre supérie...
Avantages ● Généricité / réutilisation / modularité ● Meilleure testabilité / fiabilité ● Adapter à la programmation concu...
Difficulté● Une façon de penser différente● Courbe dapprentissage   ○ idiomes, patterns, best practices● Longtemps enfermé...
Littérature ● Miran Lipovača, Learn You a Haskell for Great Good! (LYAH). Avril   2011. http://learnyouahaskell.com/ ● Bry...
Congrès et User Groups● International Conference on Functional Programming (ICFP), http:  //www.icfpconference.org/● Comme...
Sites webs● Haskell : http://haskell.org/   ○ API doc : http://haskell.org/ghc/docs/7.0-latest/html/libraries/index.     h...
Hands On : ici...https://github.com/fsarradin/xke-fp
Prochain SlideShare
Chargement dans…5
×

Programmation Fonctionnelle

3 644 vues

Publié le

Publié dans : Technologie
1 commentaire
6 j’aime
Statistiques
Remarques
Aucun téléchargement
Vues
Nombre de vues
3 644
Sur SlideShare
0
Issues des intégrations
0
Intégrations
24
Actions
Partages
0
Téléchargements
70
Commentaires
1
J’aime
6
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

×