SlideShare une entreprise Scribd logo
1  sur  38
Télécharger pour lire hors ligne
WTF ?
(What's the Fold)

principes de programmation

fonctionnelle, expliqués simplement

Olivier Croisier
SPEAKER

Olivier Croisier
JavaSpecialist™
Consultant @Zenika
Formateur
Speaker
Blogger

TheCodersBreakfast.net

@OlivierCroisier

olivier@thecodersbreakfast.net

github.com/OlivierCroisier
FOLD ?

Programmation fonctionnelle
Haskell, Scala... ?
Difficile ?
Vocabulaire
Functor, Applicative, Monoid, Monad, Arrow...
map(), filter()... fold()
FOLD ?

Définition en Haskell
foldl :: (a → b → a) → a → [b] → a

… Pas de panique !
FOLD ?

Exercice 1
Soit une liste d'entiers
→ Les additionner
List<Integer> nums = Arrays.asList(1,2,3,4,5);
FOLD ?

Exercice 1
Soit une liste d'entiers
→ Les additionner
List<Integer> nums = Arrays.asList(1,2,3,4,5);
public Integer sum(List<Integer> nums) {
Integer sum = 0;
for (Integer num : nums) {
sum = sum + num;
}
return sum;
}
FOLD ?

Exercice 2
Soit une liste d'entiers
→ Les multiplier
List<Integer> nums = Arrays.asList(1,2,3,4,5);
FOLD ?

Exercice 2
Soit une liste d'entiers
→ Les multiplier
List<Integer> nums = Arrays.asList(1,2,3,4,5);
public Integer product(List<Integer> nums) {
Integer product = 1;
for (Integer num : nums) {
product = product * num;
}
return product;
}
FOLD ?

Pattern commun
Accumulateur ← valeur initiale
Boucle sur la liste
Opération (accumulateur, élément)

public Integer foo(List<Integer> nums) {
Integer accu = <init>;
for (Integer num : nums) {
accu = accu <op> num;
}
return accu;
}
FOLD ?
Type de l'accumulateur
Type des éléments de la liste

public <A, E> A fold (BiFunction<A, E, A> op,
A init,
List<E> list) {
A accu = init;
for (E num : list) {
accu = op.apply(accu, num);
}
return accu;
}
FOLD ?
BiFunction<Integer,Integer,Integer> plus =
new BiFunction<>() {
public Integer apply(Integer accu, Integer elem) {
return accu + elem;
}
};
BiFunction<Integer,Integer,Integer> mult =
new BiFunction<>() {
public Integer apply(Integer accu, Integer elem) {
return accu * elem;
}
};
Integer sum
= fold (plus, 0, nums);
Integer product = fold (mult, 1, nums);
FOLD ?

Java 8 : Expressions Lambda
(args) -> expression

BiFunction<Int,Int,Int>
BiFunction<Int,Int,Int>

plus
mult

=
=

(a,e)
(a,e)

Integer
Integer

sum
product

=
=

fold
fold

(plus,
(mult,

0,
1,

Integer
Integer

sum
product

=
=

fold
fold

((a,e)->a+e,
((a,e)->a*e,

->
->

a+e;
a*e;

nums);
nums);

0,
1,

nums);
nums);
FOLD ?

Java 8 : Références de méthodes
Class::staticFunction
Integer sum = fold (Integer::plus, 0, nums);
public class MathUtil {
public static Integer mult(Integer x,Integer y) {
return x * y;
}
}
Integer prod = fold (MathUtil::mult, 1, nums);
FOLD ?

Définition en Haskell
foldl :: (a → b → a) → a → [b] → a

fonction

(a,b) → a

accumulateur

de type a

résultat

liste<b>
PRINCIPES

Définition

“

En programmation fonctionnelle, l'opération fold
(ou reduce) est une famille de fonctions d'ordre
supérieur qui traitent une structure de données
dans un certain ordre pour produire un résultat.
– http://www.haskell.org/haskellwiki/Fold
PRINCIPES

Avantages
Mécanisme très générique
Fonction d'ordre supérieur
Encapsulation de l'itération
Expressivité ("quoi" vs "comment")
Optimisation des opérations associatives
Famille de fonctions
foldl, foldr, foldl1, foldr1
scanl, scanr, scanl1, scanr1
PRINCIPES

Fold left - foldl
accumulateur

0 + 1

[1,2,3,4,5]

1 + 2

[1,2,3,4,5]

3 + 3

[1,2,3,4,5]

6 + 4
10 + 5
15

[1,2,3,4,5]
[1,2,3,4,5]
PRINCIPES

Fold right - foldr
itération

inversée !

accumulateur

[1,2,3,4,5]

5 + 0

[1,2,3,4,5]

4 + 5

[1,2,3,4,5]
[1,2,3,4,5]
[1,2,3,4,5]

3 + 9
2 + 12
1 + 14
15
PRINCIPES

Fold left vs Fold right
Opérations non commutatives
(soustraction, division...)
foldl
foldr

(-)
(-)

0
0

[1..5]
[1..5]

quiz !

Performances
Plus efficace d'ajouter en tête des listes
→ foldr : élément à gauche, liste à droite
PRINCIPES

Autres folds
foldl1, foldr1
Même principe que foldl et foldr
Accumulateur ← 1° élément de la liste
foldl (+) 0 [1..5]
foldl1 (+) X [1..5]
valeur initiale implicite
PRINCIPES

Autres folds
scanl, scanr
scanl1, scanr1
Même principe
Renvoient toutes les valeurs intermédiaires
scanl (+) 0 [1..5]
[0,1,3,6,10,15]
scanr (+) 0 [1..5]
[15,14,12,9,5,0]
USAGES

Folds complexes
Fold sert de base à beaucoup d'algorithmes
impliquant le parcours d'une liste
Le résultat peut être une valeur unique ("reduce")
ou une autre liste !
Dépend de l'accumulateur et de l'opération
On peut effectuer une opération complexe
par composition de fonctions simples
f(g(x)) ↔ (f ⋅ g)(x)
USAGES

Fonction map
Applique une fonction f à chaque élément
[1,2,3,4,5] → [f(1),f(2),f(3),f(4),f(5)]

Implémentation avec foldr
Accumulateur ← liste cible vide
Pour chaque élément e :
- Calculer f(e)
- Ajouter f(e) à la liste cible

fonction

composée
USAGES

Fonction map
"cons"

fonction f

result = foldr ((:).(*2)) [] [1..5]

composition de
fonctions

- application de f

- puis ajout à la liste
USAGES

Fonction map
List<Integer> accu = new ArrayList<>();
BiFunction<List<Integer>,Integer,List<Integer>> op =
(l,e) -> {
l.add(0, e * 2);
return l;
};
List<Int> result = foldr(op, accu, nums);
USAGES

Fonction filter
Sélectionne uniquement les éléments qui
répondent à un prédicat p
[1,2,3,4,5] –-(garder si >3)--> [4,5]

Implémentation avec foldr
Accumulateur ← liste cible vide
Pour chaque élément e :
- Vérifier p(e)
- Si p(e), ajouter e à la liste cible

fonction

composée
USAGES

Fonction filter
ajout de l'élément à
l'accumulateur

let op e list = if e
then
else

> 3
(e:list)
list

result = foldr op [] [1..5]
USAGES

Fonction filter
List<Integer> accu = new LinkedList<>();
BiFunction<List<Integer>,Integer,List<Integer>> op =
(l, e) -> {
if (e > 3) l.add(0,e);
return l;
};
List<Int> result = foldr(op, accu, nums);
USAGES

Fonction count
Compte le nombre d'éléments dans la liste
[1,2,3,4,5] → 5

Implémentation avec foldl
Accumulateur ← 0
Pour chaque élément e :
- Incrémenter l'accumulateur
USAGES

Fonction count
count = foldl (a e → a+1) 0 [1..5]
Integer result = foldl((a,e)->a+1, 0, nums)
USAGES

Fonction max
Renvoie le plus grand élément de la liste
[1,2,3,4,5] → 5

Implémentation avec foldl
Accumulateur ← 0
Pour chaque élément e :
- Si e > accumulateur, alors accumulateur = e
USAGES

Fonction max
let op e m = if e
then
else

> m
e
m

result = foldl op 0 [1..5]
Integer max = foldl((e,m)-> e>m?e:m, 0, nums);
IMPLEMENTATIONS

Java 8
Notion de Stream (java.util.stream.Stream)
Pipeline de transformation
Spécialisé par type (IntStream…)
Implémente reduce (foldl restreint à 1 type)
T reduce( T identity,
BinaryOperator<T> reducer );
List<Integer> nums = Arrays.asList(1,2,3,4,5);
int sum = nums.stream()
.reduce(0, Integer::sum);
IMPLEMENTATIONS

Javascript
Sur les tableaux
reduce (foldl) et reduceRight (foldr)
array.reduce
(func,
array.reduceRight(func,

initval)
initval)

var nums = new Array(1,2,3,4,5);
var sum = nums.reduce(
function(a,e) {return a+e;},
0);
IMPLEMENTATIONS

Scala
Sur les listes et tableaux
foldLeft (/:) et foldRight (:)
List.foldLeft (initval)(func)
List.foldRight(initval)(func)
val nums = Array(1, 2, 3, 4, 5)
val sum = nums.foldLeft(0)(_+_)
val sum = (0 /: list)(_+_)
IMPLEMENTATIONS

Groovy
Sur les listes
list.inject (foldl)
nums = [1,2,3,4];
sum = nums.inject(0) { a,e -> a+e }
CONCLUSION

Alors, What's The Fold ?
Un principe simple, puissant et générique
Socle pour d'autre opérations
map, filter, count...
Déjà présent dans vos langages
reduce, inject, foldLeft...
Apprenez à le reconnaître !
questions ?

Contenu connexe

Tendances (7)

Monitoring d'applications/environnements PHP: APM et Pinba
Monitoring d'applications/environnements PHP: APM et PinbaMonitoring d'applications/environnements PHP: APM et Pinba
Monitoring d'applications/environnements PHP: APM et Pinba
 
ALF 3 - Expressions régulières et Lexer
ALF 3 - Expressions régulières et Lexer ALF 3 - Expressions régulières et Lexer
ALF 3 - Expressions régulières et Lexer
 
ALF 10 - Convention d'appel de fonction
ALF 10 - Convention d'appel de fonctionALF 10 - Convention d'appel de fonction
ALF 10 - Convention d'appel de fonction
 
ALF 11 - WebAssembly
ALF 11 - WebAssemblyALF 11 - WebAssembly
ALF 11 - WebAssembly
 
Theme 9
Theme 9Theme 9
Theme 9
 
Algorithm et structure de donnée
Algorithm et structure de donnéeAlgorithm et structure de donnée
Algorithm et structure de donnée
 
ALF 8 - Generation du code
ALF 8 - Generation du codeALF 8 - Generation du code
ALF 8 - Generation du code
 

En vedette

Better Product Definition with Lean UX and Design Thinking
Better Product Definition with Lean UX and Design ThinkingBetter Product Definition with Lean UX and Design Thinking
Better Product Definition with Lean UX and Design Thinking
Jeff Gothelf
 

En vedette (20)

UX STRAT USA: Leah Buley, "The Role of UX / CX in Business"
UX STRAT USA: Leah Buley, "The Role of UX / CX in Business"UX STRAT USA: Leah Buley, "The Role of UX / CX in Business"
UX STRAT USA: Leah Buley, "The Role of UX / CX in Business"
 
NightClazz Build Tools & Continuous Delivery Avancé
NightClazz Build Tools & Continuous Delivery AvancéNightClazz Build Tools & Continuous Delivery Avancé
NightClazz Build Tools & Continuous Delivery Avancé
 
Séminaire en ligne - Email Kinetic - 30 Mai 2017
Séminaire en ligne - Email Kinetic - 30 Mai 2017Séminaire en ligne - Email Kinetic - 30 Mai 2017
Séminaire en ligne - Email Kinetic - 30 Mai 2017
 
Http2
Http2Http2
Http2
 
Better Product Definition with Lean UX and Design Thinking
Better Product Definition with Lean UX and Design ThinkingBetter Product Definition with Lean UX and Design Thinking
Better Product Definition with Lean UX and Design Thinking
 
Perf ug comment ne plus rajouter de ram a vos jvm sans savoir pourquoi
Perf ug   comment ne plus rajouter de ram a vos jvm sans savoir pourquoiPerf ug   comment ne plus rajouter de ram a vos jvm sans savoir pourquoi
Perf ug comment ne plus rajouter de ram a vos jvm sans savoir pourquoi
 
Http2 right now
Http2 right nowHttp2 right now
Http2 right now
 
Monitoring Compteur EDF avec node.js
Monitoring Compteur EDF avec node.jsMonitoring Compteur EDF avec node.js
Monitoring Compteur EDF avec node.js
 
Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016
 
Microbox : Ma toolbox microservices - Julien Roy
Microbox : Ma toolbox microservices - Julien RoyMicrobox : Ma toolbox microservices - Julien Roy
Microbox : Ma toolbox microservices - Julien Roy
 
Conference MicroServices101 - 1ere partie
Conference MicroServices101 - 1ere partieConference MicroServices101 - 1ere partie
Conference MicroServices101 - 1ere partie
 
Introduction to HTTP/2
Introduction to HTTP/2Introduction to HTTP/2
Introduction to HTTP/2
 
JAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) Bridge
 
Business intelligence v0.3
Business intelligence v0.3Business intelligence v0.3
Business intelligence v0.3
 
JavaFX et le JDK9
JavaFX et le JDK9JavaFX et le JDK9
JavaFX et le JDK9
 
HTTP2 : ce qui va changer par Julien Landuré
HTTP2 : ce qui va changer par Julien LanduréHTTP2 : ce qui va changer par Julien Landuré
HTTP2 : ce qui va changer par Julien Landuré
 
Agile Wake Up #1 du 01/12/2015 : L'agilité à grande échelle
Agile Wake Up #1 du 01/12/2015 : L'agilité à grande échelleAgile Wake Up #1 du 01/12/2015 : L'agilité à grande échelle
Agile Wake Up #1 du 01/12/2015 : L'agilité à grande échelle
 
NightClazz Java 8 Decouverte
NightClazz Java 8 DecouverteNightClazz Java 8 Decouverte
NightClazz Java 8 Decouverte
 
What HTTP/2.0 Will Do For You
What HTTP/2.0 Will Do For YouWhat HTTP/2.0 Will Do For You
What HTTP/2.0 Will Do For You
 
Http2 les impacts dans le web
Http2 les impacts dans le webHttp2 les impacts dans le web
Http2 les impacts dans le web
 

Similaire à WTF - What's The Fold - Bordeaux JUG 2013

Coffee script
Coffee scriptCoffee script
Coffee script
antho1404
 
Atelier Python 2eme partie par Achraf Kacimi El Hassani
Atelier Python 2eme partie par Achraf Kacimi El HassaniAtelier Python 2eme partie par Achraf Kacimi El Hassani
Atelier Python 2eme partie par Achraf Kacimi El Hassani
Shellmates
 

Similaire à WTF - What's The Fold - Bordeaux JUG 2013 (20)

La programmation fonctionnelle avec le langage OCaml
La programmation fonctionnelle avec le langage OCamlLa programmation fonctionnelle avec le langage OCaml
La programmation fonctionnelle avec le langage OCaml
 
Quickie Incanter/Clojure à Devoxx France 2012
Quickie Incanter/Clojure à Devoxx France 2012Quickie Incanter/Clojure à Devoxx France 2012
Quickie Incanter/Clojure à Devoxx France 2012
 
Introduction à scala
Introduction à scalaIntroduction à scala
Introduction à scala
 
Theme 7
Theme 7Theme 7
Theme 7
 
5- understandinggJava_Collections_v4.pdf
5- understandinggJava_Collections_v4.pdf5- understandinggJava_Collections_v4.pdf
5- understandinggJava_Collections_v4.pdf
 
Introduction Clojure - Geneva JUG - Octobre 2012
Introduction Clojure - Geneva JUG - Octobre 2012Introduction Clojure - Geneva JUG - Octobre 2012
Introduction Clojure - Geneva JUG - Octobre 2012
 
Scala : programmation fonctionnelle
Scala : programmation fonctionnelleScala : programmation fonctionnelle
Scala : programmation fonctionnelle
 
Ce bon vieux propel
Ce bon vieux propelCe bon vieux propel
Ce bon vieux propel
 
Coffee script
Coffee scriptCoffee script
Coffee script
 
Exploiter php 5
Exploiter php 5Exploiter php 5
Exploiter php 5
 
Ns python 2
Ns python 2Ns python 2
Ns python 2
 
Introduction à Python
Introduction à PythonIntroduction à Python
Introduction à Python
 
Chapitre8: Collections et Enumerations En Java
Chapitre8: Collections et Enumerations En JavaChapitre8: Collections et Enumerations En Java
Chapitre8: Collections et Enumerations En Java
 
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
 
Python chapitre 4.pdf
Python chapitre 4.pdfPython chapitre 4.pdf
Python chapitre 4.pdf
 
coursAlgo_V6.ppt
coursAlgo_V6.pptcoursAlgo_V6.ppt
coursAlgo_V6.ppt
 
Chapitre 1 rappel
Chapitre 1   rappelChapitre 1   rappel
Chapitre 1 rappel
 
Atelier Python 2eme partie par Achraf Kacimi El Hassani
Atelier Python 2eme partie par Achraf Kacimi El HassaniAtelier Python 2eme partie par Achraf Kacimi El Hassani
Atelier Python 2eme partie par Achraf Kacimi El Hassani
 
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
 
Mathématiques et Python
Mathématiques et PythonMathématiques et Python
Mathématiques et Python
 

Plus de Zenika

Agile Wake Up #1 du 01/12/2015 : Scrum Master's Diary par Arnaud Villenave
Agile Wake Up #1 du 01/12/2015 : Scrum Master's Diary par Arnaud VillenaveAgile Wake Up #1 du 01/12/2015 : Scrum Master's Diary par Arnaud Villenave
Agile Wake Up #1 du 01/12/2015 : Scrum Master's Diary par Arnaud Villenave
Zenika
 

Plus de Zenika (20)

Datascience & IoT
Datascience & IoTDatascience & IoT
Datascience & IoT
 
Matinale Agile Wake Up #4 : les tests et l'agilité
Matinale Agile Wake Up #4 : les tests et l'agilitéMatinale Agile Wake Up #4 : les tests et l'agilité
Matinale Agile Wake Up #4 : les tests et l'agilité
 
Agile Wake Up #3 : Lean UX
Agile Wake Up #3 : Lean UXAgile Wake Up #3 : Lean UX
Agile Wake Up #3 : Lean UX
 
Agile Wake Up #3 : La transformation Agile de Kisio Digital
Agile Wake Up #3 : La transformation Agile de Kisio DigitalAgile Wake Up #3 : La transformation Agile de Kisio Digital
Agile Wake Up #3 : La transformation Agile de Kisio Digital
 
Agile Wake Up #3 : la contractualisation Agile
Agile Wake Up #3 : la contractualisation AgileAgile Wake Up #3 : la contractualisation Agile
Agile Wake Up #3 : la contractualisation Agile
 
Zenika matinale spark-zeppelin_ml
Zenika matinale spark-zeppelin_mlZenika matinale spark-zeppelin_ml
Zenika matinale spark-zeppelin_ml
 
Docker du mythe à la réalité
Docker du mythe à la réalitéDocker du mythe à la réalité
Docker du mythe à la réalité
 
Motivation 3.0 : sens, autonomie et maîtrise.
Motivation 3.0 : sens, autonomie et maîtrise.Motivation 3.0 : sens, autonomie et maîtrise.
Motivation 3.0 : sens, autonomie et maîtrise.
 
Matinale React
Matinale ReactMatinale React
Matinale React
 
NigthClazz Spark - Machine Learning / Introduction à Spark et Zeppelin
NigthClazz Spark - Machine Learning / Introduction à Spark et ZeppelinNigthClazz Spark - Machine Learning / Introduction à Spark et Zeppelin
NigthClazz Spark - Machine Learning / Introduction à Spark et Zeppelin
 
NightClazz Spark / Machine Learning
NightClazz Spark / Machine LearningNightClazz Spark / Machine Learning
NightClazz Spark / Machine Learning
 
Agile Wake Up #1 du 01/12/2015 : L'agilité au service des projets Orange Fran...
Agile Wake Up #1 du 01/12/2015 : L'agilité au service des projets Orange Fran...Agile Wake Up #1 du 01/12/2015 : L'agilité au service des projets Orange Fran...
Agile Wake Up #1 du 01/12/2015 : L'agilité au service des projets Orange Fran...
 
Agile Wake Up #1 du 01/12/2015 : Scrum Master's Diary par Arnaud Villenave
Agile Wake Up #1 du 01/12/2015 : Scrum Master's Diary par Arnaud VillenaveAgile Wake Up #1 du 01/12/2015 : Scrum Master's Diary par Arnaud Villenave
Agile Wake Up #1 du 01/12/2015 : Scrum Master's Diary par Arnaud Villenave
 
Entreprise libérée : Du mythe à la réalité ?
Entreprise libérée : Du mythe à la réalité ?Entreprise libérée : Du mythe à la réalité ?
Entreprise libérée : Du mythe à la réalité ?
 
NightClazz Docker Découverte
NightClazz Docker Découverte NightClazz Docker Découverte
NightClazz Docker Découverte
 
Matinale DevOps / Docker
Matinale DevOps / DockerMatinale DevOps / Docker
Matinale DevOps / Docker
 
NightClazz Build Tools & Continuous Delivery
NightClazz Build Tools & Continuous DeliveryNightClazz Build Tools & Continuous Delivery
NightClazz Build Tools & Continuous Delivery
 
Deadlock Victim
Deadlock VictimDeadlock Victim
Deadlock Victim
 
Seren
SerenSeren
Seren
 
What’s Next Replay! Lyon 2011 - G. Darmont
What’s Next Replay! Lyon 2011 - G. DarmontWhat’s Next Replay! Lyon 2011 - G. Darmont
What’s Next Replay! Lyon 2011 - G. Darmont
 

WTF - What's The Fold - Bordeaux JUG 2013

  • 1. WTF ? (What's the Fold) principes de programmation fonctionnelle, expliqués simplement Olivier Croisier
  • 3. FOLD ? Programmation fonctionnelle Haskell, Scala... ? Difficile ? Vocabulaire Functor, Applicative, Monoid, Monad, Arrow... map(), filter()... fold()
  • 4. FOLD ? Définition en Haskell foldl :: (a → b → a) → a → [b] → a … Pas de panique !
  • 5. FOLD ? Exercice 1 Soit une liste d'entiers → Les additionner List<Integer> nums = Arrays.asList(1,2,3,4,5);
  • 6. FOLD ? Exercice 1 Soit une liste d'entiers → Les additionner List<Integer> nums = Arrays.asList(1,2,3,4,5); public Integer sum(List<Integer> nums) { Integer sum = 0; for (Integer num : nums) { sum = sum + num; } return sum; }
  • 7. FOLD ? Exercice 2 Soit une liste d'entiers → Les multiplier List<Integer> nums = Arrays.asList(1,2,3,4,5);
  • 8. FOLD ? Exercice 2 Soit une liste d'entiers → Les multiplier List<Integer> nums = Arrays.asList(1,2,3,4,5); public Integer product(List<Integer> nums) { Integer product = 1; for (Integer num : nums) { product = product * num; } return product; }
  • 9. FOLD ? Pattern commun Accumulateur ← valeur initiale Boucle sur la liste Opération (accumulateur, élément) public Integer foo(List<Integer> nums) { Integer accu = <init>; for (Integer num : nums) { accu = accu <op> num; } return accu; }
  • 10. FOLD ? Type de l'accumulateur Type des éléments de la liste public <A, E> A fold (BiFunction<A, E, A> op, A init, List<E> list) { A accu = init; for (E num : list) { accu = op.apply(accu, num); } return accu; }
  • 11. FOLD ? BiFunction<Integer,Integer,Integer> plus = new BiFunction<>() { public Integer apply(Integer accu, Integer elem) { return accu + elem; } }; BiFunction<Integer,Integer,Integer> mult = new BiFunction<>() { public Integer apply(Integer accu, Integer elem) { return accu * elem; } }; Integer sum = fold (plus, 0, nums); Integer product = fold (mult, 1, nums);
  • 12. FOLD ? Java 8 : Expressions Lambda (args) -> expression BiFunction<Int,Int,Int> BiFunction<Int,Int,Int> plus mult = = (a,e) (a,e) Integer Integer sum product = = fold fold (plus, (mult, 0, 1, Integer Integer sum product = = fold fold ((a,e)->a+e, ((a,e)->a*e, -> -> a+e; a*e; nums); nums); 0, 1, nums); nums);
  • 13. FOLD ? Java 8 : Références de méthodes Class::staticFunction Integer sum = fold (Integer::plus, 0, nums); public class MathUtil { public static Integer mult(Integer x,Integer y) { return x * y; } } Integer prod = fold (MathUtil::mult, 1, nums);
  • 14. FOLD ? Définition en Haskell foldl :: (a → b → a) → a → [b] → a fonction (a,b) → a accumulateur de type a résultat liste<b>
  • 15. PRINCIPES Définition “ En programmation fonctionnelle, l'opération fold (ou reduce) est une famille de fonctions d'ordre supérieur qui traitent une structure de données dans un certain ordre pour produire un résultat. – http://www.haskell.org/haskellwiki/Fold
  • 16. PRINCIPES Avantages Mécanisme très générique Fonction d'ordre supérieur Encapsulation de l'itération Expressivité ("quoi" vs "comment") Optimisation des opérations associatives Famille de fonctions foldl, foldr, foldl1, foldr1 scanl, scanr, scanl1, scanr1
  • 17. PRINCIPES Fold left - foldl accumulateur 0 + 1 [1,2,3,4,5] 1 + 2 [1,2,3,4,5] 3 + 3 [1,2,3,4,5] 6 + 4 10 + 5 15 [1,2,3,4,5] [1,2,3,4,5]
  • 18. PRINCIPES Fold right - foldr itération inversée ! accumulateur [1,2,3,4,5] 5 + 0 [1,2,3,4,5] 4 + 5 [1,2,3,4,5] [1,2,3,4,5] [1,2,3,4,5] 3 + 9 2 + 12 1 + 14 15
  • 19. PRINCIPES Fold left vs Fold right Opérations non commutatives (soustraction, division...) foldl foldr (-) (-) 0 0 [1..5] [1..5] quiz ! Performances Plus efficace d'ajouter en tête des listes → foldr : élément à gauche, liste à droite
  • 20. PRINCIPES Autres folds foldl1, foldr1 Même principe que foldl et foldr Accumulateur ← 1° élément de la liste foldl (+) 0 [1..5] foldl1 (+) X [1..5] valeur initiale implicite
  • 21. PRINCIPES Autres folds scanl, scanr scanl1, scanr1 Même principe Renvoient toutes les valeurs intermédiaires scanl (+) 0 [1..5] [0,1,3,6,10,15] scanr (+) 0 [1..5] [15,14,12,9,5,0]
  • 22. USAGES Folds complexes Fold sert de base à beaucoup d'algorithmes impliquant le parcours d'une liste Le résultat peut être une valeur unique ("reduce") ou une autre liste ! Dépend de l'accumulateur et de l'opération On peut effectuer une opération complexe par composition de fonctions simples f(g(x)) ↔ (f ⋅ g)(x)
  • 23. USAGES Fonction map Applique une fonction f à chaque élément [1,2,3,4,5] → [f(1),f(2),f(3),f(4),f(5)] Implémentation avec foldr Accumulateur ← liste cible vide Pour chaque élément e : - Calculer f(e) - Ajouter f(e) à la liste cible fonction composée
  • 24. USAGES Fonction map "cons" fonction f result = foldr ((:).(*2)) [] [1..5] composition de fonctions - application de f - puis ajout à la liste
  • 25. USAGES Fonction map List<Integer> accu = new ArrayList<>(); BiFunction<List<Integer>,Integer,List<Integer>> op = (l,e) -> { l.add(0, e * 2); return l; }; List<Int> result = foldr(op, accu, nums);
  • 26. USAGES Fonction filter Sélectionne uniquement les éléments qui répondent à un prédicat p [1,2,3,4,5] –-(garder si >3)--> [4,5] Implémentation avec foldr Accumulateur ← liste cible vide Pour chaque élément e : - Vérifier p(e) - Si p(e), ajouter e à la liste cible fonction composée
  • 27. USAGES Fonction filter ajout de l'élément à l'accumulateur let op e list = if e then else > 3 (e:list) list result = foldr op [] [1..5]
  • 28. USAGES Fonction filter List<Integer> accu = new LinkedList<>(); BiFunction<List<Integer>,Integer,List<Integer>> op = (l, e) -> { if (e > 3) l.add(0,e); return l; }; List<Int> result = foldr(op, accu, nums);
  • 29. USAGES Fonction count Compte le nombre d'éléments dans la liste [1,2,3,4,5] → 5 Implémentation avec foldl Accumulateur ← 0 Pour chaque élément e : - Incrémenter l'accumulateur
  • 30. USAGES Fonction count count = foldl (a e → a+1) 0 [1..5] Integer result = foldl((a,e)->a+1, 0, nums)
  • 31. USAGES Fonction max Renvoie le plus grand élément de la liste [1,2,3,4,5] → 5 Implémentation avec foldl Accumulateur ← 0 Pour chaque élément e : - Si e > accumulateur, alors accumulateur = e
  • 32. USAGES Fonction max let op e m = if e then else > m e m result = foldl op 0 [1..5] Integer max = foldl((e,m)-> e>m?e:m, 0, nums);
  • 33. IMPLEMENTATIONS Java 8 Notion de Stream (java.util.stream.Stream) Pipeline de transformation Spécialisé par type (IntStream…) Implémente reduce (foldl restreint à 1 type) T reduce( T identity, BinaryOperator<T> reducer ); List<Integer> nums = Arrays.asList(1,2,3,4,5); int sum = nums.stream() .reduce(0, Integer::sum);
  • 34. IMPLEMENTATIONS Javascript Sur les tableaux reduce (foldl) et reduceRight (foldr) array.reduce (func, array.reduceRight(func, initval) initval) var nums = new Array(1,2,3,4,5); var sum = nums.reduce( function(a,e) {return a+e;}, 0);
  • 35. IMPLEMENTATIONS Scala Sur les listes et tableaux foldLeft (/:) et foldRight (:) List.foldLeft (initval)(func) List.foldRight(initval)(func) val nums = Array(1, 2, 3, 4, 5) val sum = nums.foldLeft(0)(_+_) val sum = (0 /: list)(_+_)
  • 36. IMPLEMENTATIONS Groovy Sur les listes list.inject (foldl) nums = [1,2,3,4]; sum = nums.inject(0) { a,e -> a+e }
  • 37. CONCLUSION Alors, What's The Fold ? Un principe simple, puissant et générique Socle pour d'autre opérations map, filter, count... Déjà présent dans vos langages reduce, inject, foldLeft... Apprenez à le reconnaître !