SlideShare ist ein Scribd-Unternehmen logo
1 von 62
Downloaden Sie, um offline zu lesen
“Tout ce que vous avez
  toujours voulu savoir sur la
programmation fonctionnelle*
     *sans jamais oser le demander”




                                  François Sarradin

                                          Xebia IT
                                         Architects
Programmation fonctionnelle
                       Ce qu'on 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 qu'on en dit aussi...

○ "Ellitiste"

○ "Difficile à apprendre"

○   "À ne pas mettre entre toutes les mains"

○   "Purement académique"

○   "Ça retourne le cerveau"
OK, mais...

      Qu'est-ce que la
programmation 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
                                                    Closure
Functor       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 d'informations
   ○ 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
                           Fonctionnel

Impératif
int 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 free
Composition de fonctions + disparition des variables

Continuation
Futur de la fonction en paramètre

Combinateur de point fixe
Permet les fonctions anonymes et récursives

Monade
Chaî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 + 42

h(x, y) = ∂2 p(x, y) / ∂x2
Fonction
             Dans les langages fonctionnels


Haskell
identity x = x
x -> x

Scala
def identity(x: Any) = x
{ x: Any => x }

Clojure
(defn identity [x] x)
(fn [x] x)
Fonction
                   Avec Guava


new 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
      D'où est-ce que ça vient ?
Fonction mathématique
                     fin du XVIIe siècle




f : x ↦ x

f : x ↦ 2 . x

ou

f(x) = 2 . x
                                           Gottfried Wilhelm
                                           von Leibniz
                                           (1646-1716)
Lambda-calcul
                     1936



λx.x
(λx.2*x) 7 → 2 * 7

true ::= λxy.x
false ::= λxy.y
if-then-else ::= λpab.p a b

0 ::= λfx.x
1 ::= λfx.f x
2 ::= λ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écursion


Proscrire   Verboten !            def fact(n):
   ○ for                             r = 1
   ○ while                           for i in [1..n]:
   ○ repeat                             r *= i
   ○ etc.                            return n
               Stateful !



Boucle = fonction qui s'appelle elle même
     fact n = if n == 0
                 then 1
                 else n * fact (n-1)
Récursion terminale


L'appel 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 d'appels
fact 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 d'appels

fact_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 d'ordre supérieur
                 Fonction en paramètre




                      Dérivée
                deriv(f, x) = d f(x) / dt


Application d'une fonction sur chaque élément d'une
                collection (Java 8 ?)
  Arrays.asList(1, 2, 3).map(x -> x * x)
Fonction d'ordre 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 d'ordre 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éterministe

Une fonction retourne toujours la même valeur pourvu qu'on
lui fournisse les mêmes paramètres

=> Un bon point pour la programmation concurrente !
=> (+) de testabilité, (-) d'effet 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 !
=> (-) d'effet de bord
Programmation fonctionnelle
   Déterminisme => Optimisation
Optimisation
                        Style trampoline


Optimisation 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
Optimisation


Transparence référentielle
Une expression peut être remplacée par son résultat sans
changer le comportement du programme

Mémoization
Conserver en cache le résultat d'une fonction selon ses
paramètres
Optimisation


Flot de contrôle non linéaire
Si aucune dépendance ne les lient, 2 fonctions peuvent être
appelées dans n'importe quel ordre

Évaluation retardée
Èvaluation selon le besoin

Garbage collector
-- Since 1958 --
Sucre syntaxique


Inférence de type
Déterminer automatiquement le type d'une expression ou
d'une fonction

Pattern matching
Appliquer 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] == 1

Récupérer la queue
  tail [1, 2, 3] == [2, 3]
Liste
                           Finie


Haskell
[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 l'infini 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]

Scala
N/A

Clojure
(range 1)      => (1 2 3 4 5 6 ...
Et en Java + Guava
             Émuler les listes : iterator

Iterator<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 : iterable

Iterable<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 1

Iterator<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 filter


map
Applique une transformation sur chaque élément d'une liste
   => Guava : transform(iterable, function)

   Haskell
   map (+1) [1..5] => [2, 3, 4, 5, 6]

filter
Conserve que les éléments satisfaisant un prédicat
  => Guava : filter(iterable, predicate)

   Haskell
   filter (> 3) [1..5] => [4, 5]
Fonction sur liste
                                    zip


zip
Fusionne 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/reduce


fold
Agrège les valeurs d'une 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/reduce


Haskell
foldl (+) 0 [1..5] => 15

product l = foldl (*) 1 l
fact n = product [1..n] = foldl (*) 1 [1..n]

reverse l = foldl (flip (:)) [] l
reverse [1..5] => [5, 4, 3, 2, 1]
En résumé
La programmation fonctionnelle, c'est...
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 liste

Et 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 d'apprentissage
   ○ idiomes, patterns, best practices

● Longtemps enfermée dans la communauté scientifique

● Déclaratif
   ○ Pas de maîtrise du déroulement (plus qu'avec 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 O'Sullivan, 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

Weitere ähnliche Inhalte

Was ist angesagt?

Mise en oeuvre des framework de machines et deep learning v1
Mise en oeuvre des framework de machines et deep learning v1 Mise en oeuvre des framework de machines et deep learning v1
Mise en oeuvre des framework de machines et deep learning v1
ENSET, Université Hassan II Casablanca
 
T1 corrections-qcm
T1 corrections-qcmT1 corrections-qcm
T1 corrections-qcm
infcom
 
Chapitre 4-Apprentissage non supervisé (1) (1).pdf
Chapitre 4-Apprentissage non supervisé (1) (1).pdfChapitre 4-Apprentissage non supervisé (1) (1).pdf
Chapitre 4-Apprentissage non supervisé (1) (1).pdf
ZizoAziz
 

Was ist angesagt? (20)

Cours Piles et files en utilisant lesl istes chainées Prof. KHALIFA MANSOURI
Cours Piles et files en utilisant lesl istes chainées Prof. KHALIFA MANSOURI Cours Piles et files en utilisant lesl istes chainées Prof. KHALIFA MANSOURI
Cours Piles et files en utilisant lesl istes chainées Prof. KHALIFA MANSOURI
 
Mise en oeuvre des framework de machines et deep learning v1
Mise en oeuvre des framework de machines et deep learning v1 Mise en oeuvre des framework de machines et deep learning v1
Mise en oeuvre des framework de machines et deep learning v1
 
La programmation modulaire en Python
La programmation modulaire en PythonLa programmation modulaire en Python
La programmation modulaire en Python
 
Tp java ee.pptx
Tp java ee.pptxTp java ee.pptx
Tp java ee.pptx
 
Knn
KnnKnn
Knn
 
Python avancé : Gestion d'erreurs et mécanisme d'exception
Python avancé : Gestion d'erreurs et mécanisme d'exceptionPython avancé : Gestion d'erreurs et mécanisme d'exception
Python avancé : Gestion d'erreurs et mécanisme d'exception
 
arbres de decision.ppt
arbres de decision.pptarbres de decision.ppt
arbres de decision.ppt
 
clustering
clusteringclustering
clustering
 
Théorie de l’apprentissage et SVM : présentation rapide et premières idées da...
Théorie de l’apprentissage et SVM : présentation rapide et premières idées da...Théorie de l’apprentissage et SVM : présentation rapide et premières idées da...
Théorie de l’apprentissage et SVM : présentation rapide et premières idées da...
 
T1 corrections-qcm
T1 corrections-qcmT1 corrections-qcm
T1 corrections-qcm
 
Introduction à scala
Introduction à scalaIntroduction à scala
Introduction à scala
 
Polymorphisme
PolymorphismePolymorphisme
Polymorphisme
 
LES JOINTURES
LES JOINTURESLES JOINTURES
LES JOINTURES
 
[232] TensorRT를 활용한 딥러닝 Inference 최적화
[232] TensorRT를 활용한 딥러닝 Inference 최적화[232] TensorRT를 활용한 딥러닝 Inference 최적화
[232] TensorRT를 활용한 딥러닝 Inference 최적화
 
Examen sybase - Administration base de donnees
Examen sybase - Administration base de donneesExamen sybase - Administration base de donnees
Examen sybase - Administration base de donnees
 
Prise en main de Jhipster
Prise en main de JhipsterPrise en main de Jhipster
Prise en main de Jhipster
 
Chapitre 4-Apprentissage non supervisé (1) (1).pdf
Chapitre 4-Apprentissage non supervisé (1) (1).pdfChapitre 4-Apprentissage non supervisé (1) (1).pdf
Chapitre 4-Apprentissage non supervisé (1) (1).pdf
 
Chp6 - De UML vers C++
Chp6 - De UML vers C++Chp6 - De UML vers C++
Chp6 - De UML vers C++
 
Cours les Listes doublement chainées Prof. KHALIFA MANSOURI
Cours les Listes doublement chainées Prof. KHALIFA MANSOURI Cours les Listes doublement chainées Prof. KHALIFA MANSOURI
Cours les Listes doublement chainées Prof. KHALIFA MANSOURI
 
Introduction to Keras
Introduction to KerasIntroduction to Keras
Introduction to Keras
 

Andere mochten auch

Cours algorithme
Cours algorithmeCours algorithme
Cours algorithme
badr zaimi
 
Devoirs Algorithme + correction pour 4 si
Devoirs Algorithme + correction pour 4 siDevoirs Algorithme + correction pour 4 si
Devoirs Algorithme + correction pour 4 si
Narûtö Bàl'Sèm
 
exercices-corriges-dalgorithmique
exercices-corriges-dalgorithmiqueexercices-corriges-dalgorithmique
exercices-corriges-dalgorithmique
fast xp
 

Andere mochten auch (17)

Programmation fonctionnelle
Programmation fonctionnelleProgrammation fonctionnelle
Programmation fonctionnelle
 
Scala : programmation fonctionnelle
Scala : programmation fonctionnelleScala : programmation fonctionnelle
Scala : programmation fonctionnelle
 
La programmation fonctionnelle en javascript / PF
La programmation fonctionnelle en javascript / PFLa programmation fonctionnelle en javascript / PF
La programmation fonctionnelle en javascript / PF
 
Audacity
AudacityAudacity
Audacity
 
Cours algorithme
Cours algorithmeCours algorithme
Cours algorithme
 
Arthrose et arthrite
Arthrose et arthriteArthrose et arthrite
Arthrose et arthrite
 
Electricité
ElectricitéElectricité
Electricité
 
Devoirs Algorithme + correction pour 4 si
Devoirs Algorithme + correction pour 4 siDevoirs Algorithme + correction pour 4 si
Devoirs Algorithme + correction pour 4 si
 
Correction
CorrectionCorrection
Correction
 
Thinking Functionally with Clojure
Thinking Functionally with ClojureThinking Functionally with Clojure
Thinking Functionally with Clojure
 
Programmation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScriptProgrammation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScript
 
Comprendre la programmation fonctionnelle, Blend Web Mix le 02/11/2016
Comprendre la programmation fonctionnelle, Blend Web Mix le 02/11/2016Comprendre la programmation fonctionnelle, Blend Web Mix le 02/11/2016
Comprendre la programmation fonctionnelle, Blend Web Mix le 02/11/2016
 
Introduction à la programmation fonctionnelle
Introduction à la programmation fonctionnelle Introduction à la programmation fonctionnelle
Introduction à la programmation fonctionnelle
 
Programmation fonctionnelle
Programmation fonctionnelleProgrammation fonctionnelle
Programmation fonctionnelle
 
exercices-corriges-dalgorithmique
exercices-corriges-dalgorithmiqueexercices-corriges-dalgorithmique
exercices-corriges-dalgorithmique
 
Serie2
Serie2Serie2
Serie2
 
Travaux dirigés 1: algorithme & structures de données (corrigés)
Travaux dirigés 1: algorithme & structures de données (corrigés)Travaux dirigés 1: algorithme & structures de données (corrigés)
Travaux dirigés 1: algorithme & structures de données (corrigés)
 

Ähnlich wie Programmation Fonctionnelle

Seance 3- Programmation en langage C
Seance 3- Programmation en langage C Seance 3- Programmation en langage C
Seance 3- Programmation en langage C
Fahad Golra
 
INF120 - Algo DUT SRC1 - Cours 2 (2012)
INF120 - Algo DUT SRC1 - Cours 2 (2012)INF120 - Algo DUT SRC1 - Cours 2 (2012)
INF120 - Algo DUT SRC1 - Cours 2 (2012)
PGambette
 
Algorithmes d'approximation
Algorithmes d'approximationAlgorithmes d'approximation
Algorithmes d'approximation
mohamed_SAYARI
 
mis
mismis
mis
ISIG
 

Ähnlich wie Programmation Fonctionnelle (20)

Récursivité
RécursivitéRécursivité
Récursivité
 
Mathématiques et Python
Mathématiques et PythonMathématiques et Python
Mathématiques et Python
 
Algorithmique Amp Programmation (R Sum
Algorithmique  Amp  Programmation (R SumAlgorithmique  Amp  Programmation (R Sum
Algorithmique Amp Programmation (R Sum
 
Seance 3- Programmation en langage C
Seance 3- Programmation en langage C Seance 3- Programmation en langage C
Seance 3- Programmation en langage C
 
Cours JavaScript
Cours JavaScriptCours JavaScript
Cours JavaScript
 
Algorithmique programmation2018
Algorithmique programmation2018Algorithmique programmation2018
Algorithmique programmation2018
 
ALF 11 - WebAssembly
ALF 11 - WebAssemblyALF 11 - WebAssembly
ALF 11 - WebAssembly
 
Mix it 2011 - Clojure
Mix it 2011 - ClojureMix it 2011 - Clojure
Mix it 2011 - Clojure
 
INF120 - Algo DUT SRC1 - Cours 2 (2012)
INF120 - Algo DUT SRC1 - Cours 2 (2012)INF120 - Algo DUT SRC1 - Cours 2 (2012)
INF120 - Algo DUT SRC1 - Cours 2 (2012)
 
Introduction Clojure - Geneva JUG - Octobre 2012
Introduction Clojure - Geneva JUG - Octobre 2012Introduction Clojure - Geneva JUG - Octobre 2012
Introduction Clojure - Geneva JUG - Octobre 2012
 
20080610 04 - Explorations visuelles de programmes
20080610 04 - Explorations visuelles de programmes20080610 04 - Explorations visuelles de programmes
20080610 04 - Explorations visuelles de programmes
 
Algorithmes d'approximation
Algorithmes d'approximationAlgorithmes d'approximation
Algorithmes d'approximation
 
ALF 11 - Diagramme de flux de contrôle et WebAssembly
ALF 11 - Diagramme de flux de contrôle et WebAssemblyALF 11 - Diagramme de flux de contrôle et WebAssembly
ALF 11 - Diagramme de flux de contrôle et WebAssembly
 
ALF 11 - Diagrame de flux de controlle
ALF 11 - Diagrame de flux de controlleALF 11 - Diagrame de flux de controlle
ALF 11 - Diagrame de flux de controlle
 
cours algorithme
cours algorithmecours algorithme
cours algorithme
 
Traitement des données massives (INF442, A4)
Traitement des données massives (INF442, A4)Traitement des données massives (INF442, A4)
Traitement des données massives (INF442, A4)
 
TP3: Comportement Temps Réel de l'Agent Perception
TP3: Comportement Temps Réel de l'Agent PerceptionTP3: Comportement Temps Réel de l'Agent Perception
TP3: Comportement Temps Réel de l'Agent Perception
 
08_Abstraction.pdf
08_Abstraction.pdf08_Abstraction.pdf
08_Abstraction.pdf
 
mis
mismis
mis
 
Algorithmes récursifs : une introduction pragmatique pour un enseignement au ...
Algorithmes récursifs : une introduction pragmatique pour un enseignement au ...Algorithmes récursifs : une introduction pragmatique pour un enseignement au ...
Algorithmes récursifs : une introduction pragmatique pour un enseignement au ...
 

Mehr von François Sarradin

Mehr von François Sarradin (6)

Java (8) eXperiments - DevoxxFR 2016
Java (8) eXperiments - DevoxxFR 2016Java (8) eXperiments - DevoxxFR 2016
Java (8) eXperiments - DevoxxFR 2016
 
Java8 eXperiment - Normandy JUG
Java8 eXperiment - Normandy JUGJava8 eXperiment - Normandy JUG
Java8 eXperiment - Normandy JUG
 
FLATMAP ZAT SHIT : les monades expliquées aux geeks (Devoxx France 2013)
FLATMAP ZAT SHIT : les monades expliquées aux geeks (Devoxx France 2013)FLATMAP ZAT SHIT : les monades expliquées aux geeks (Devoxx France 2013)
FLATMAP ZAT SHIT : les monades expliquées aux geeks (Devoxx France 2013)
 
Scala vs java 8
Scala vs java 8Scala vs java 8
Scala vs java 8
 
Java 8 Lambda
Java 8 LambdaJava 8 Lambda
Java 8 Lambda
 
JavaScript Core
JavaScript CoreJavaScript Core
JavaScript Core
 

Programmation Fonctionnelle

  • 1. “Tout ce que vous avez toujours voulu savoir sur la programmation fonctionnelle* *sans jamais oser le demander” François Sarradin Xebia IT Architects
  • 2. Programmation fonctionnelle Ce qu'on 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. Programmation fonctionnelle Ce qu'on en dit aussi... ○ "Ellitiste" ○ "Difficile à apprendre" ○ "À ne pas mettre entre toutes les mains" ○ "Purement académique" ○ "Ça retourne le cerveau"
  • 4. OK, mais... Qu'est-ce que la programmation fonctionnelle ?
  • 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 Closure Functor Point free map/filter/ Pattern matching fold/zip Inférence de type Transparence Catamorphisme référentielle Tail recursion
  • 6. Au programme... ● La base du style fonctionnel ○ Histoire de la programmation fonctionnelle ○ Récursion / Ordre supérieur / Déterminisme ○ Optimisation ● Traitement de flux d'informations ○ Liste en programmation fonctionnelle ○ Fonctions sur listes ● Conclusion ● Hands On
  • 7. Langages utilisés ● Haskell (principalement) ● Scala, Clojure, Erlang, etc. ● Java + Guava (pour le Hands On)
  • 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. Style Fonctionnel Impératif int 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. Et aussi... Point free Composition de fonctions + disparition des variables Continuation Futur de la fonction en paramètre Combinateur de point fixe Permet les fonctions anonymes et récursives Monade Chaînage de traitements
  • 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. Programmation fonctionnelle Principe n°1 : tout est fonction
  • 14. Tout est fonction Au sens mathématique f(x) = 2.x x ↦ x + 42 h(x, y) = ∂2 p(x, y) / ∂x2
  • 15. Fonction Dans les langages fonctionnels Haskell identity x = x x -> x Scala def identity(x: Any) = x { x: Any => x } Clojure (defn identity [x] x) (fn [x] x)
  • 16. Fonction Avec Guava new Function<T, R>() { @Override public R apply(T x) { return x; } } new Predicate<T>() { @Override public boolean apply(T x) { return x == null; } }
  • 17. Programmation fonctionnelle D'où est-ce que ça vient ?
  • 18. Fonction mathématique fin du XVIIe siècle f : x ↦ x f : x ↦ 2 . x ou f(x) = 2 . x Gottfried Wilhelm von Leibniz (1646-1716)
  • 19. Lambda-calcul 1936 λx.x (λx.2*x) 7 → 2 * 7 true ::= λxy.x false ::= λxy.y if-then-else ::= λpab.p a b 0 ::= λfx.x 1 ::= λfx.f x 2 ::= λfx.f (f x) Alonzo Church (1903-1995)
  • 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. 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. Version "embarqué" ● Langage ○ Java 8 (en 2012 ?) ○ Groovy ○ Python ○ Ruby ○ SmallTalk ○ ... ● API Java ○ Guava ○ LambdaJ ○ TotallyLazy ○ FunctionalJava ○ FunkyJFunctional
  • 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. Programmation fonctionnelle Principe n°2 : récursion
  • 25. Récursion Proscrire Verboten ! def fact(n): ○ for r = 1 ○ while for i in [1..n]: ○ repeat r *= i ○ etc. return n Stateful ! Boucle = fonction qui s'appelle elle même fact n = if n == 0 then 1 else n * fact (n-1)
  • 26. Récursion terminale L'appel 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. Récursion : pile d'appels fact 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. Récursion terminale : pile d'appels fact_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
  • 30. Programmation fonctionnelle Principe n°3 : ordre supérieur
  • 31. Fonction d'ordre supérieur Fonction en paramètre Dérivée deriv(f, x) = d f(x) / dt Application d'une fonction sur chaque élément d'une collection (Java 8 ?) Arrays.asList(1, 2, 3).map(x -> x * x)
  • 32. Fonction d'ordre 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. Fonction d'ordre supérieur ... ou les deux Composition f ∘ g : x ↦ f(g(x))
  • 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. Programmation fonctionnelle Principe n°4 : déterminisme
  • 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éterministe Une fonction retourne toujours la même valeur pourvu qu'on lui fournisse les mêmes paramètres => Un bon point pour la programmation concurrente ! => (+) de testabilité, (-) d'effet de bord
  • 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 ! => (-) d'effet de bord
  • 38. Programmation fonctionnelle Déterminisme => Optimisation
  • 39. Optimisation Style trampoline Optimisation 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. Optimisation Transparence référentielle Une expression peut être remplacée par son résultat sans changer le comportement du programme Mémoization Conserver en cache le résultat d'une fonction selon ses paramètres
  • 41. Optimisation Flot de contrôle non linéaire Si aucune dépendance ne les lient, 2 fonctions peuvent être appelées dans n'importe quel ordre Évaluation retardée Èvaluation selon le besoin Garbage collector -- Since 1958 --
  • 42. Sucre syntaxique Inférence de type Déterminer automatiquement le type d'une expression ou d'une fonction Pattern matching Appliquer 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. Programmation fonctionnelle Principe n°5 : liste
  • 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] == 1 Récupérer la queue tail [1, 2, 3] == [2, 3]
  • 45. Liste Finie Haskell [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. Liste Vers l'infini 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] Scala N/A Clojure (range 1) => (1 2 3 4 5 6 ...
  • 47. Et en Java + Guava Émuler les listes : iterator Iterator<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. Et en Java + Guava Émuler les listes : iterable Iterable<Integer> oneToFive = new Iterable<Integer>() { @Override public Iterator<Integer> iterator() { return oneToFiveIterator; } }; assertThat(oneToFive) .containsExactly(1, 2, 3, 4, 5);
  • 49. Et en Java + Guava Liste infinie : suite de 1 Iterator<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. Programmation fonctionnelle Opérations de traitement sur listes
  • 51. Fonction sur liste map et filter map Applique une transformation sur chaque élément d'une liste => Guava : transform(iterable, function) Haskell map (+1) [1..5] => [2, 3, 4, 5, 6] filter Conserve que les éléments satisfaisant un prédicat => Guava : filter(iterable, predicate) Haskell filter (> 3) [1..5] => [4, 5]
  • 52. Fonction sur liste zip zip Fusionne 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. Fonction sur liste fold/reduce fold Agrège les valeurs d'une 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. Fonction sur liste fold/reduce Haskell foldl (+) 0 [1..5] => 15 product l = foldl (*) 1 l fact n = product [1..n] = foldl (*) 1 [1..n] reverse l = foldl (flip (:)) [] l reverse [1..5] => [5, 4, 3, 2, 1]
  • 55. En résumé La programmation fonctionnelle, c'est...
  • 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 liste Et plus encore...
  • 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. Difficulté ● Une façon de penser différente ● Courbe d'apprentissage ○ idiomes, patterns, best practices ● Longtemps enfermée dans la communauté scientifique ● Déclaratif ○ Pas de maîtrise du déroulement (plus qu'avec Java) ○ Bonne connaissance du compilateur/VM ● Trop de concision tue la lisibilité
  • 59. Littérature ● Miran Lipovača, Learn You a Haskell for Great Good! (LYAH). Avril 2011. http://learnyouahaskell.com/ ● Bryan O'Sullivan, Don Stewart, and John Goerzen, Real World Haskell (RWH). Novembre 2008. http://book.realworldhaskell.org/
  • 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. 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. Hands On : ici... https://github.com/fsarradin/xke-fp