Programmation Fonctionnelle
Upcoming SlideShare
Loading in...5
×
 

Programmation Fonctionnelle

on

  • 2,873 views

 

Statistics

Views

Total Views
2,873
Views on SlideShare
2,865
Embed Views
8

Actions

Likes
2
Downloads
36
Comments
0

2 Embeds 8

http://www.linkedin.com 6
https://www.linkedin.com 2

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-NonCommercial-NoDerivs LicenseCC Attribution-NonCommercial-NoDerivs LicenseCC Attribution-NonCommercial-NoDerivs License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Programmation Fonctionnelle Programmation Fonctionnelle Presentation Transcript

  • “Tout ce que vous avez toujours voulu savoir sur laprogrammation fonctionnelle* *sans jamais oser le demander” François Sarradin Xebia IT Architects
  • 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 !"
  • Programmation fonctionnelle Ce quon en dit aussi...○ "Ellitiste"○ "Difficile à apprendre"○ "À ne pas mettre entre toutes les mains"○ "Purement académique"○ "Ça retourne le cerveau"
  • OK, mais... Quest-ce que laprogrammation fonctionnelle ?
  • 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
  • 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
  • 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 = Πi i , ∀ i ∈ [1..n]ou 0! = 1, n! = n . (n - 1)!, si n > 0.
  • 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]
  • 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
  • Mais aussi des dérives...APL (A Programming Language) factorial←{ ⍺←1 ⍵=0:⍺ (⍺×⍵)∇ ⍵-1 }life←{ ↑1 ⍵∨.^3 4=+/,¯1 0 1∘.⊖¯1 0 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 }Clojure(defn identity [x] x)(fn [x] x)
  • 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; }}
  • Programmation fonctionnelle Doù est-ce que ça vient ?
  • Fonction mathématique fin du XVIIe sièclef : x ↦ xf : x ↦ 2 . xouf(x) = 2 . x Gottfried Wilhelm von Leibniz (1646-1716)
  • 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)
  • 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)
  • 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)
  • Version "embarqué"● Langage ○ Java 8 (en 2012 ?) ○ Groovy ○ Python ○ Ruby ○ SmallTalk ○ ...● API Java ○ Guava ○ LambdaJ ○ TotallyLazy ○ FunctionalJava ○ FunkyJFunctional
  • 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)
  • Programmation fonctionnelle Principe n°2 : récursion
  • 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)
  • 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
  • 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
  • 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
  • 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) = d f(x) / dtApplication dune fonction sur chaque élément dune collection (Java 8 ?) Arrays.asList(1, 2, 3).map(x -> x * x)
  • 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
  • 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 // 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 }
  • Programmation fonctionnelle Principe n°4 : déterminisme
  • 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
  • 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
  • Programmation fonctionnelle Déterminisme => Optimisation
  • 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
  • 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
  • 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 --
  • 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) => ... }
  • Programmation fonctionnelle Principe n°5 : liste
  • 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]
  • 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)
  • 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 ...
  • 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 !
  • 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);
  • 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; }}
  • Programmation fonctionnelle Opérations de traitement sur listes
  • 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]
  • 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
  • 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
  • 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]
  • En résuméLa programmation fonctionnelle, cest...
  • 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...
  • 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
  • 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é
  • 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/
  • 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)
  • 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/
  • Hands On : ici...https://github.com/fsarradin/xke-fp