SlideShare une entreprise Scribd logo
1  sur  49
Télécharger pour lire hors ligne
SCALA
PROGRAMMATION FONCTIONNELLE
CONCEPTS ET MISE EN ŒUVRE
Dr Mustapha Michrafy
M. MICHRAFY
Contact de l’auteur :
datascience.km@gmail.com
datascience.km@gmail.com1
Contexte
Cette étude a été présentée dans le cadre
du séminaire « Data Science principes, outils
et applications » au laboratoire Cermsem.
datascience.km@gmail.comM. MICHRAFY 2
Plan
• Objectif
• Prérequis
• Tout est fonction
• Fonction pure
• Fonction anonyme
• Fonction d’ordre supérieur
• Clôture
• Fonction partielle
• Récursivité
• Curryfication
datascience.km@gmail.comM. MICHRAFY 3
Objectif
Cette étude vise à présenter la
programmation fonctionnelle sous Scala.
datascience.km@gmail.comM. MICHRAFY 4
Prérequis
• Connaissance du langage Scala
• Notion de récursivité
datascience.km@gmail.comM. MICHRAFY 5
Tout est fonction
• Dans le paradigme fonctionnel, tout est fonction.
• Un traitement complexe est composé de plusieurs
fonctions
datascience.km@gmail.comM. MICHRAFY 6
Fonction en scala
• En scala, une fonction est un objet qui peut être affecté à
une variable.
• La définition d’une fonction peut être effectuée n’importe
où dans un fichier source.
• La définition d’une fonction en scala nécessite l’utilisation
du mot clé def suivi du nom de la fonction, de zéro,
d’un ou de plusieurs arguments d’entrée, le type de
retour et le corps de la fonction
def add(x:Int, y:Int) : Int = {return x+y;}
Nom de la fonction
Arguments d’entrée
Valeur de retour
Corps de la fonction
datascience.km@gmail.comM. MICHRAFY 7
Appel à une fonction en scala
• L’appel d’une fonction se fait via son nom, suivi par les
arguments d’entrée entre parenthèses et séparés par un virgule.
• Si la fonction ne demande pas d’argument d’entrée, l’appel se
fait seulement avec son nom, et optionnellement suivi par une
paire de parenthèses vides ().
def add(x:Int, y:Int) : Int = {return x+y;}
Add(8,17) Appel de la fonction add
Définition de la fonction add
def hello() =
hello()
hello
Définition de la fonction hello
Appel de la fonction hello avec ()
Appel de la fonction hello sans ()
datascience.km@gmail.comM. MICHRAFY 8
Fonction pure
• Une fonction pure est une fonction qui respecte les 2
critères suivants :
1. La fonction est déterministe, c-à-d renvoie toujours la même
valeur pour les mêmes arguments
2. La fonction ne retourne que la valeur résultat, sans effet de bord.
• Les fonctions arithmétiques sont des fonctions pures
• Les fonctions mathématiques sont des fonctions pures
• Toute fonction à effet de bord n’est pas une fonction
pure
datascience.km@gmail.comM. MICHRAFY 9
Fonctions mathématiques
Fonction Sin def sin(x:Double) : Double = Math.sin(x)
Fonction
identité
def identite(x:Double) : Double = x
Fonction
constante
def constante(x:Double) : Double = 7
Fonction
affine
def affine(x:Double) : Double = 3*x+5
Formulation syntaxique en scala
Nom de la fonction
Argument d’entré et son type
Expression de retour
Type de retour
datascience.km@gmail.comM. MICHRAFY 10
Fonctions mathématiques
scalascalascalascala> defdefdefdef sin(x : Double) : Doublesin(x : Double) : Doublesin(x : Double) : Doublesin(x : Double) : Double ==== Math.sinMath.sinMath.sinMath.sin(x)(x)(x)(x)
sin: (x: Double)Double
scalascalascalascala> sin(80)
res0: Double = -0.9938886539233752
scalascalascalascala> def identite(x : Double) : Double = {return x;}
identite: (x: Double)Double
scalascalascalascala> identite(80)
res1: Double = 80.0
scalascalascalascala> def constante(x : Double) : Double = 13
constante: (x: Double)Double
scalascalascalascala> constante(80)
res2: Double = 13.0
scalascalascalascala> def affine(x : Double) : Double = 3*x + 5
affine: (x : Double)Double
scalascalascalascala> affine(80)
res3: Double = 245.0
datascience.km@gmail.comM. MICHRAFY 11
Signature de la fonction
Fonction anonyme : principe
• Une fonction anonyme en scala permet de définir une
fonction sans déclarer le nom de la fonction
• Une fonction anonyme est similaire à une lambda
expression et permet de créer des fonctions à la volée
• Une fonction anonyme peut être utilisée :
• pour initialiser une variable
• comme argument d’une fonction
• comme valeur de retour d’une fonction
datascience.km@gmail.comM. MICHRAFY 12
Fonction anonyme : syntaxe
• La syntaxe d’une fonction anonyme commence par une
liste d’arguments séparés par des virgules et entourés par
des parenthèses. Observons l’exemple suivant :
scala> val add = (x:Int, y:Int) => x+y
La fonction anonymeAdd est initialisé par la fonction anonyme
datascience.km@gmail.comM. MICHRAFY 13
Fonction anonyme : invocation
scala> val add = (x:Int, y:Int) => x+y
add: (Int, Int) => Int = <function2>
scala> add(7,8)
res4: Int = 15
Invocation de la fonction
anonyme
Définition de la fonction
anonyme
Comment les fonctions anonymes sont-elles créées ?
Pourquoi <fonction2>?
datascience.km@gmail.comM. MICHRAFY 14
Fonction anonyme : construction
scala> val add1:(Int, Int) => Int = (x:Int, y:Int) => x+y
add1: (Int, Int) => Int = <function2>= <function2>= <function2>= <function2>
scala> add1(1,10)
res0: Int = 11
scala> val add2: Function2[Function2[Function2[Function2[Int,Int,IntInt,Int,IntInt,Int,IntInt,Int,Int]]]] = ((((x:Intx:Intx:Intx:Int, y:Int) =>, y:Int) =>, y:Int) =>, y:Int) => x+yx+yx+yx+y
add2: (Int, Int) => Int = <function2><function2><function2><function2>
scala> add2.applyapplyapplyapply(1,10)
res1: Int = 11
• Une fonction anonyme est instanciée par un objet de type « fonction »
• L’objet étend le type FonctionNFonctionNFonctionNFonctionN, N désignant l’arité de la fonction anonymes
• L ’objet FonctionN dispose d’une méthode « apply »
datascience.km@gmail.comM. MICHRAFY 15
Fonction comme variable
• En scala et dans le paradigme fonctionnel en général,
nous pouvons utiliser une fonction comme variable.
scala> val valImpair = (n:Int) => 2*n + 1
valImpair: Int => Int = <function1>
scala> valImpair(10)
res3: Int = 21
La variable valImpair a pour valeur la fonction <function1>
datascience.km@gmail.comM. MICHRAFY 16
Fonction comme argument : déclaration
• Il est aussi possible de définir une fonction qui prend en
entrée une fonction
• Ce principe est similaire au pointeur de fonction en
C/C++ ou aux interfaces fonctionnelles en Java
• Il suffit de déclarer la signature de la fonction
defdefdefdef nomFonctionnomFonctionnomFonctionnomFonction(fctfctfctfct:([:([:([:([paramsparamsparamsparams]) =>]) =>]) =>]) => typeRetourtypeRetourtypeRetourtypeRetour, arg:type, ...) : typeRetourtypeRetourtypeRetourtypeRetour = {....}
Fonction comme argument d’une autre fonction
datascience.km@gmail.comM. MICHRAFY 17
Fonction comme argument : exemple
scala>scala>scala>scala> def operationoperationoperationoperation(op:(op:(op:(op:(Int,IntInt,IntInt,IntInt,Int)=>Int)=>Int)=>Int)=>Int, x:Int,y:Int) : Int = op(x,y)
operation: (op: (Int, Int) => Int, x: Int, y: Int)Int
scala>scala>scala>scala> def addaddaddadd(x:Int,y:Int):Int = x+y
add: (x: Int, y: Int)Int
scala>scala>scala>scala> def produitproduitproduitproduit(x:Int, y:Int):Int = x*y
produit: (x: Int, y: Int)Int
scala>scala>scala>scala> operationoperationoperationoperation(addaddaddadd,7,8)
res4: Int = 15
scala>scala>scala>scala> operationoperationoperationoperation(produit,produit,produit,produit,7,8)
res5: Int = 56
operation a la fonction op
comme argument
Les fonctions add et produit
ont la même signature que op
Appel de la fonction operation avec add
comme paramètre
Appel à la fonction operation avec produit
comme paramètre
datascience.km@gmail.comM. MICHRAFY 18
Fonction comme valeur de retour
• Il est aussi possible d’avoir une fonction comme valeur de
retour d’une fonction
• Dans ce cas, la fonction doit avoir une valeur de retour
de type fonction ou une fonction anonyme
• Il préférable d’utiliser les accolades pour la lisibilité.
datascience.km@gmail.comM. MICHRAFY 19
Fonction comme valeur de retour
scala>scala>scala>scala> def fabriqueFctAffinefabriqueFctAffinefabriqueFctAffinefabriqueFctAffine(a:Int ,b:Int) : (Int)=>Int
| = {(x:Int)=> a*x+b}
fabriqueFctAffine: (a: Int, b: Int)Int => Int
scalascalascalascala> def diag = fabriqueFctAffinefabriqueFctAffinefabriqueFctAffinefabriqueFctAffine(2,3)
diag: Int => Int
scalascalascalascala> diag(1)
res0: Int = 5
datascience.km@gmail.comM. MICHRAFY 20
La fonction fabriqueFctAffine renvoie une fonction affine ayant
pour coefficients les arguments a et b fournis en entrée
diag est la fonction définit par : → 		 → 2 3
Signature de la fonction
fabriqueFctAffine
Signature de la fonction diag
La fonction composée
• La fonction composée (notée o en mathématique) est la
fonction qui prend en entrée deux fonctions et retourne la
fonction composée des deux
• Soient deux fonctions F et G, pour définir FoG, il est
nécessaire que l’ensemble {G(x), x dans Domaine(G)}
inclut dans Domaine(F) :
∶ 1 → 2, ∶ 2 → 2
∶ 1 	∁		 2
datascience.km@gmail.comM. MICHRAFY 21
La fonction composée
datascience.km@gmail.comM. MICHRAFY 22
F(x) = x*x
G(x) = x+1
FoG(x) = F(G(x))
= F(x + 1) = x*x+1
Formulation mathématique
Opérateur o
scala>scala>scala>scala> def FFFF(x : Int) : Int = x*x
F: (x: Int)Int
scala>scala>scala>scala> def GGGG(x : Int) : Int = x + 1
G: (x: Int)Int
scala>scala>scala>scala> defdefdefdef compose(Fcompose(Fcompose(Fcompose(F:(Int)=>(Int), G:(Int)=>(Int)) : (Int)=>(Int) = (Int)=>F(G(Int))
compose: (F: Int => Int, G: Int => Int)Int => Intcompose: (F: Int => Int, G: Int => Int)Int => Intcompose: (F: Int => Int, G: Int => Int)Int => Intcompose: (F: Int => Int, G: Int => Int)Int => Int
Compose(F,G) = FoG
Clôture : principe
• Une clôture ou fermeture est une fonction dont la valeur
de retour dépend de la valeur d'une ou plusieurs variables
déclarées à l'extérieur de cette fonction
• Les clôtures permettent d’encapsuler une partie du
contexte d’exécution dans une fonction
datascience.km@gmail.comM. MICHRAFY 23
Clôture : exemple
scala> val a = 2
a: Int = 2
scala> val b = 3
b: Int = 3
scala> def affine(x:Int,y:Int):Int = aaaa*x + bbbb
affine: (x: Int, y: Int)Int
scala> affine(1,1)
res7: Int = 5
a, b sont déclarées en dehors de la portée
de la fonction affine
datascience.km@gmail.comM. MICHRAFY 24
Fonction partielle
• En figeant les valeurs d’un sous-ensemble des
paramètres d’une fonction connue, on obtient une
fonction partielle (projection, spécialisation)
scala>scala>scala>scala> def produit(x:Int, y:Int):Int = x*y
produit: (x: Int, y: Int)Int
scala>scala>scala>scala> val partialyProduit = produit(2,_:Int)produit(2,_:Int)produit(2,_:Int)produit(2,_:Int)
partialyProduit: Int => Int = <function1<function1<function1<function1>>>>
scala>scala>scala>scala> partialyProduit(7)
res10: Int = 14
datascience.km@gmail.comM. MICHRAFY 25
Fonction récursive
• Une fonction récursive est une fonction qui peut s’appeler
elle-même.
• La récursivité reproduit le formalisme de la relation de
récurrence en mathématique
• La récursivité doit satisfaire deux conditions :
• Un ou plusieurs cas d’arrêts qui ne font pas appel à la fonction
• Définir le cas général en fonction des états antérieurs
• La récursivité est un principe fondamental en
programmation fonctionnelle, permettant de remplacer les
boucles.
datascience.km@gmail.comM. MICHRAFY 26
Fonction récursive : intérêt
• Pour des structures de données récursives, il est bien
plus facile d'écrire des algorithmes récursifs qu'itératifs
• Certains algorithmes sont extrêmement difficiles à écrire
dans un style itératif
• Dans certains cas, les fonctions récursives permettent
d’écrire des programmes très lisibles, et aussi de
concevoir des algorithmes dont l'analyse ou la preuve
sera facilitée.
datascience.km@gmail.comM. MICHRAFY 27
Fonction récursive : Calcul PGCD
datascience.km@gmail.comM. MICHRAFY 28
a = kb + r et 0 ≤ r < b
a si b=0
PGCD(b,r)
PGDC(a,b)=
Algorithme d’Euclide
appel à PGCD(42,24)
. Appel a PGCD(24,18)
.. Appel à PGCD(18,6)
…Appel à PGCD(6,0)
….retour 6
scalascalascalascala>>>> defdefdefdef pgcdpgcdpgcdpgcd((((a:Int,b:Inta:Int,b:Inta:Int,b:Inta:Int,b:Int) :) :) :) : IntIntIntInt ={={={={
|||| if(bif(bif(bif(b==0) a==0) a==0) a==0) a
|||| elseelseelseelse pgcdpgcdpgcdpgcd((((b,b%ab,b%ab,b%ab,b%a))))
| }| }| }| }
pgcd: (a: Int, b: Int)Int
scalascalascalascala> pgcd(42,24)
res0: Int = 6
Fonction récursive : pile d’exécution
• Chaque appel d’une fonction récursive est associé à un
contexte d’exécution propre
• Ce contexte d’exécution est composé de :
• l'adresse mémoire de l'instruction qui a appelé la fonction
• les valeurs des paramètres et des variables définies par la fonction
• La récursivité implique une allocation dynamique de la
mémoire.
• La pile d’exécution fonctionne selon le principe LIFO
• La pile ayant une taille fixe, une mauvaise utilisation de la
récursivité peut entraîner son débordement.
datascience.km@gmail.comM. MICHRAFY 29
Fonction récursive : pile d’exécution
appel à fact(4)
. 4*fact(3) = ?
. appel à fact(3)
. . 3*fact(2) = ?
. . appel à fact(2)
. . . 2*fact(1) = ?
. . . appel à fact(1)
. . . . 1*fact(0) = ?
. . . . appel à fact(0)
. . . . retour de la valeur 1
. . . . 1*1
. . . retour de la valeur 1
. . . 2*1
. . retour de la valeur 2
. . 3*2
. retour de la valeur 6
. 4*6
retour de la valeur 24
scalascalascalascala>>>> def fact(n : Int) : Int
| = if(n==0) 1 else n*fact(n-1)
fact: (n: Int)Int
scalascalascalascala>>>> fact(4)
res2: Int = 24
1 si n=0
n*fact(n-1)fact(n)=
datascience.km@gmail.comM. MICHRAFY 30
La récursivité : terminale ou non ?
Deux types
Terminale Non Terminale
datascience.km@gmail.comM. MICHRAFY 31
• Une fonction f est récursive terminale, si tous les appels récursifs invoquent f au
plus une fois et sont de la forme return f(…)
• Une fonction récursive terminale a un coût en mémoire constant (pas
d’empilement des appels récursifs).
• Il est toujours possible de transformer une fonction récursive non terminale en une
fonction terminale en introduisant des accumulateurs comme arguments
d’entrée
Récursivité : Transformation
def factNonTerminalfactNonTerminalfactNonTerminalfactNonTerminal(n:Int):Int ={
if(n==0) 1
else n+factNonTerminalfactNonTerminalfactNonTerminalfactNonTerminal(n-1)
}
datascience.km@gmail.comM. MICHRAFY 32
def factTerminalfactTerminalfactTerminalfactTerminal(n:Int, m:Int) : Int ={
if(n==0) m
else factTerminalfactTerminalfactTerminalfactTerminal(n-1,m*n)
}
Transformation Terminale
Fonction récursive
non terminale
Fonction récursive
terminale
accumulateur
Récursivité : fonctions enveloppe et
auxiliaire
• Une fonction enveloppe est une fonction qui encapsule
une fonction ou plusieurs (nommée fonction enveloppée ou
auxiliaire).
• Les fonctions enveloppes peuvent être utilisées pour
initialiser les arguments d’une fonction récursive terminale
• La réécriture d’une fonction en récursivité terminale
nécessite l’introduction d’un argument ou plusieurs et dont
l’initialisation dépend de l’implémentation. La solution
consiste à implémenter une fonction récursive terminale
comme une fonction auxiliaire d’une fonction principale
datascience.km@gmail.comM. MICHRAFY 33
Récursivité : réécriture d’une fonction
def factNonTerminalfactNonTerminalfactNonTerminalfactNonTerminal(n:Int):Int ={
if(n==0) 1
else n+factNonTerminalfactNonTerminalfactNonTerminalfactNonTerminal(n-1)
}
datascience.km@gmail.comM. MICHRAFY 34
def factTerminalfactTerminalfactTerminalfactTerminal(n:Int, m:Int) : Int ={
if(n==0) m
else factTerminalfactTerminalfactTerminalfactTerminal(n-1,m*n)
}
Transformation Terminale
def factfactfactfact(n : Int) : Int = {
def factTerminalfactTerminalfactTerminalfactTerminal(n:Int, m:Int) : Int ={
if(n==0) m
else factTerminalfactTerminalfactTerminalfactTerminal(n-1,m*n)
}
factTerminalfactTerminalfactTerminalfactTerminal(n,1(n,1(n,1(n,1))))
}
Réécriture de la fonction
Définition de la fonction auxiliaire
1
2
Appel à la fonction auxiliaire avec deux
arguments dont un est initialisé à 1
Récursivité : Primalité d’un nombre
• Un nombre p est premier s’il admet que deux diviseurs 1
et n
• Tout nombre pair est non premier à l’exception de 2
• Pour améliorer les performance, il suffit de tester
seulement les nombre entre 2 et √ .
• Comme un nombre premier est toujours impair – à
l’exception de 2- il suffit de tester les nombre impairs
entre 3 et √ .Mais ceci est utile pour un algorithme itératif
datascience.km@gmail.comM. MICHRAFY 35
Récursivité : Primalité d’un nombre
def isPrimAuxisPrimAuxisPrimAuxisPrimAux((((p:Intp:Intp:Intp:Int, d:Int), d:Int), d:Int), d:Int) : Boolean={
if(d*d <= p){
if(p%d==0) false
else isPrimAux(p,d+1);
}
else true
}
def isPrimisPrimisPrimisPrim((((p:Intp:Intp:Intp:Int)))) : Boolean ={
def isPrimAux(p:Int, d:Int):Boolean ={
if(d*d <= p){
if(p%d==0) false
else isPrimAux(p,d+1);
}
else true
}
isPrimAux(p,2)
}
d=2
isPrim(p) =
si d*d <= p
si d/p alors faux
sinon estPrim(p,d+1)
sinon vrai
Algorithme pour tester la primalité
1
2
datascience.km@gmail.comM. MICHRAFY 36
Récursivité: fonction d’ordre sup.
• n et m deux entiers, n < m
• Calculer A et B :
- ∑ - ∑
datascience.km@gmail.comM. MICHRAFY 37
Similarité : la somme
!: 	 → 		
! 	
#: 	 → 		
#
	 $ !% & , $ #
Réécriture de A et B
Ecrire une fonction sum qui prend en
entrée une fonction f
Idée
'() !, , )
0																																							' 	 + )
! '() !, 1, ) 	'
Relation de
récurrence.
Récursivité: fonction d’ordre sup.
• n et m deux entiers, n < m
• Calculer A et B :
- ∑ - ∑
datascience.km@gmail.comM. MICHRAFY 38
!: 	 → 		
! 	
#: 	 → 		
#
	 $ !% & , $ #
'() !, , )
0																																							' 	 + )
! '() !, 1, ) 	'
def sumsumsumsum(ffff: Int => Int, a: Int, b: Int): Int ={
if (a > b) 0 else f(a) + sum(f, a + 1, b)
}
val A = sum(x=>x)
val B = sum(x=>x*x)
def sumCompactesumCompactesumCompactesumCompacte(f: Int => Int): (Int, Int) => Int = {
def sum(a: Int, b: Int): Int =if (a > b) 0 else f(a) + sum (a + 1, b)
sum
}
Calcul de A et B
Récursivité : stratégie d’implémentation
• Un algorithme récursif peut donner lieu à plusieurs
implémentations.
• Ce cas se présente lorsque le problème est composé de
plusieurs sous-problèmes de même nature. Ceci est similaire
au principe de diviser pour régner ou aux algorithmes relevant
de la programmation dynamique.
• L’implémentation dépend à la fois de la :
• La Stratégie du parcours ou de construction
• L’initialisation des paramètres
• Une mauvaise implémentation peut pénaliser le temps de
calcul.
Analysons la suite de Fibonacci
datascience.km@gmail.comM. MICHRAFY 39
Récursivité : Fibonacci, version naïve
Fibonacci(n)=
0 si n = 0
1 si n =1
Fibonacci(n-1) + Fibonacci(n-2)
Suite de fibonacci
def fibonaccifibonaccifibonaccifibonacci(n:Int) : Int = {
if(n < 2) n
else fibonaccifibonaccifibonaccifibonacci(n-1) + fibonaccifibonaccifibonaccifibonacci(n-2)
}
datascience.km@gmail.comM. MICHRAFY 40
Récursivité : analyse de l’algorithme
Fibonacci 7
6 5
4 35 4
4 3 3 2 3 2 2 1
1 03 2 2 1 2 1 2 1 1 0
1 01 01 01 02 1
1 0
1 0
• Chaque nœud désigne un terme de la suite de fibonacci
• Les nœuds -portant les valeurs 2 à 7- sont des appels récursifs
• Les nœuds verts désignent les termes 0 et 1 de la suite fibonacci
• On constate le calcul redondant généré par l’algorithme « naïf »de fibonacci.
Arborescence de
Fibonacci(7)
7
0
datascience.km@gmail.comM. MICHRAFY 41
Récursivité : algorithme constructif de
fibonacci
• Le problème consiste à ne pas recalculer le même terme
de fibonnaci plusieurs fois.
• Remarquons que le terme n de Fibonacci nécessite le
calcul des termes de n-1 à 0.
• Par conséquent, pour éviter le calcul redondant, nous
pouvons calculer le terme n en commençant par calculer
le terme 0,1, 2 …. via la relation de récurrence.
• Pour calculer le terme n sans redondance, il faut
mémoriser les termes n-1 et n-2.
• Nous avons besoin aussi d’un test d’arrêt, ce qui est le
terme n.
datascience.km@gmail.comM. MICHRAFY 42
Récursivité : Fibonacci, algorithme constructif
p, a1,a0 trois entiers
Fibonacci(n,p,a1,a0) =
n si n<2
Fibonacci(n,p+1,a1+a0,a1) si p<n
a1+ a0 sinon
a0 = 0, a1=1 ( a0 et a1 2 termes consécutifs de fibonacci)
p=2, ( p varie de 2 à n)
Relation de
récursivité
Etape
d’initialisation
• C’est un algorithme constructif.
• A chaque étape, l’algorithme conserve les deux états m-1, m-2
• Les deux états consécutifs sont stockés dans a0 et a1
• Les termes 0 et 1 sont utilisés dans la phase d’initialisation
• Le terme n de Fibonacci est la somme de a0 et a1
datascience.km@gmail.comM. MICHRAFY 43
Récursivité : Fibonacci, algorithme constructif
p, a1,a0 trois entiers
Fibonacci(n,p,a1,a0) =
n si n<2
Fibonacci(n,p+1,a1+a0,a1) si p<n
a1+ a0 sinon
2
10
3
1
4
2
5
3
4
65
7
n=7, p=2, a0=0, a1=1
def fibonaccifibonaccifibonaccifibonacci(n:Int):Int={
def fibfibfibfib(n:Int, p:Int, a0:Int, a1:Int) : Int ={
if(n<2) n
else{
if(p<n) fibfibfibfib(n, p+1, a1+a0,a1)
else a1+a0
}
}
fib(n,2,1,0)
}
Plus de calcul
redondant
0
7
Chaque ligne
désigne les termes
consécutifs
datascience.km@gmail.comM. MICHRAFY 44
Curryfication : principe
• La curryfication désigne l'opération transforme une
fonction à plusieurs arguments à une fonction à un
argument qui retourne une fonction prenant le reste des
arguments. Elle permet de convertir une fonction avec
plusieurs paramètres en créant une chaîne de fonction,
chacun attendant un seul argument.
• En mathématique, on peut définir une fonction à plusieurs
variables alors que le Lambda-calcul se limite à des
fonctions avec une seule variable. Une correspondance
« curryfication » bijective a été définie entre les fonctions
Lambda-calcul et les fonctions multivariées
datascience.km@gmail.comM. MICHRAFY 45
Curryfication : Transformation
• A chaque fonction multivariées, on associe une fonction avec
une seule variable. La curryfication s’appuie sur les définition
des fonctions partielles
,		 →
, - → -
!. ∶ → →
→ !. - -
Curryfication
! ∶ → 		
, -, / → - /
!.: 	 0 → →
-, / → - /	
!.,1 ∶ 	 → % → &	
/ → - /
→ !.
- → !.,1
Fonctions de
curryfication
→ !.
2
1
datascience.km@gmail.comM. MICHRAFY 46
Curryfication : méthode add
scala> def add1add1add1add1(x:Double, y:Double):Double = x + y
add1add1add1add1: (x: Double, y: Double)Double
scala> def add1Curry = (x : Double) => (y : Double) => x + y
add1Curry: Double => (Double => Double)
scala> def add2add2add2add2(x:Int,y:Int,z:Int) : Int = x+y+z
add2: (x: Int, y: Int, z: Int)Int
scala> def add2Curryadd2Curryadd2Curryadd2Curry(x:Int) : Int => (Int => Int) = y => (z => x + y + z)
add2Curryadd2Curryadd2Curryadd2Curry: (x: Int)Int => (Int => Int)
Curryfication
Curryfication
datascience.km@gmail.comM. MICHRAFY 47
Références bibliographiques
• Beginning Scala, par David Pollak, 2015
• Programming in Scala, par Martin Odersky and al., 2011
• Programming Scala, par Dean Wampler, Alex Payne, 2014
• Functional Thinking par Neal Ford, 2014
• Functional Programming in Scala, par Paul Chiusano,
Rúnar Bjarnason, 2014
datascience.km@gmail.comM. MICHRAFY
Dr Mustapha Michrafy
DataScientist, ATOS
Contact : datascience.km@gmail.com
datascience.km@gmail.comM. MICHRAFY 49

Contenu connexe

Tendances

le NLP à l'ére de l'IA
le NLP à l'ére de l'IAle NLP à l'ére de l'IA
le NLP à l'ére de l'IAhabib200
 
BigData_Chp1: Introduction à la Big Data
BigData_Chp1: Introduction à la Big DataBigData_Chp1: Introduction à la Big Data
BigData_Chp1: Introduction à la Big DataLilia Sfaxi
 
TP1 Big Data - MapReduce
TP1 Big Data - MapReduceTP1 Big Data - MapReduce
TP1 Big Data - MapReduceAmal Abid
 
Introduction-A-La-Logique.pdf
Introduction-A-La-Logique.pdfIntroduction-A-La-Logique.pdf
Introduction-A-La-Logique.pdfdenischef1
 
BigData_Chp2: Hadoop & Map-Reduce
BigData_Chp2: Hadoop & Map-ReduceBigData_Chp2: Hadoop & Map-Reduce
BigData_Chp2: Hadoop & Map-ReduceLilia Sfaxi
 
TP2 Big Data HBase
TP2 Big Data HBaseTP2 Big Data HBase
TP2 Big Data HBaseAmal Abid
 
BigData_TP3 : Spark
BigData_TP3 : SparkBigData_TP3 : Spark
BigData_TP3 : SparkLilia Sfaxi
 
Apache Kafka, Un système distribué de messagerie hautement performant
Apache Kafka, Un système distribué de messagerie hautement performantApache Kafka, Un système distribué de messagerie hautement performant
Apache Kafka, Un système distribué de messagerie hautement performantALTIC Altic
 
Ontology concept et applications
Ontology concept et applicationsOntology concept et applications
Ontology concept et applicationsbenouini rachid
 
Chap 6 : classes et interfaces
Chap 6 : classes et interfacesChap 6 : classes et interfaces
Chap 6 : classes et interfacesAziz Darouichi
 
Parquet and AVRO
Parquet and AVROParquet and AVRO
Parquet and AVROairisData
 
BigData_TP2: Design Patterns dans Hadoop
BigData_TP2: Design Patterns dans HadoopBigData_TP2: Design Patterns dans Hadoop
BigData_TP2: Design Patterns dans HadoopLilia Sfaxi
 
Chp2 - Les Entrepôts de Données
Chp2 - Les Entrepôts de DonnéesChp2 - Les Entrepôts de Données
Chp2 - Les Entrepôts de DonnéesLilia Sfaxi
 
Chp3 - Modélisation Multidimensionnelle
Chp3 - Modélisation MultidimensionnelleChp3 - Modélisation Multidimensionnelle
Chp3 - Modélisation MultidimensionnelleLilia Sfaxi
 
Big Data : SQL, NoSQL ? Pourquoi faire un choix ?
Big Data : SQL, NoSQL ? Pourquoi faire un choix ?Big Data : SQL, NoSQL ? Pourquoi faire un choix ?
Big Data : SQL, NoSQL ? Pourquoi faire un choix ?Microsoft Décideurs IT
 
Appalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSPAppalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSPYouness Boukouchi
 
Installation hadoopv2.7.4-amal abid
Installation hadoopv2.7.4-amal abidInstallation hadoopv2.7.4-amal abid
Installation hadoopv2.7.4-amal abidAmal Abid
 
Interface fonctionnelle, Lambda expression, méthode par défaut, référence de...
Interface fonctionnelle, Lambda expression, méthode par défaut,  référence de...Interface fonctionnelle, Lambda expression, méthode par défaut,  référence de...
Interface fonctionnelle, Lambda expression, méthode par défaut, référence de...MICHRAFY MUSTAFA
 

Tendances (20)

le NLP à l'ére de l'IA
le NLP à l'ére de l'IAle NLP à l'ére de l'IA
le NLP à l'ére de l'IA
 
BigData_Chp1: Introduction à la Big Data
BigData_Chp1: Introduction à la Big DataBigData_Chp1: Introduction à la Big Data
BigData_Chp1: Introduction à la Big Data
 
TP1 Big Data - MapReduce
TP1 Big Data - MapReduceTP1 Big Data - MapReduce
TP1 Big Data - MapReduce
 
Introduction-A-La-Logique.pdf
Introduction-A-La-Logique.pdfIntroduction-A-La-Logique.pdf
Introduction-A-La-Logique.pdf
 
BigData_Chp2: Hadoop & Map-Reduce
BigData_Chp2: Hadoop & Map-ReduceBigData_Chp2: Hadoop & Map-Reduce
BigData_Chp2: Hadoop & Map-Reduce
 
TP2 Big Data HBase
TP2 Big Data HBaseTP2 Big Data HBase
TP2 Big Data HBase
 
BigData_TP3 : Spark
BigData_TP3 : SparkBigData_TP3 : Spark
BigData_TP3 : Spark
 
Apache Kafka, Un système distribué de messagerie hautement performant
Apache Kafka, Un système distribué de messagerie hautement performantApache Kafka, Un système distribué de messagerie hautement performant
Apache Kafka, Un système distribué de messagerie hautement performant
 
Ontology concept et applications
Ontology concept et applicationsOntology concept et applications
Ontology concept et applications
 
Chap 6 : classes et interfaces
Chap 6 : classes et interfacesChap 6 : classes et interfaces
Chap 6 : classes et interfaces
 
Parquet and AVRO
Parquet and AVROParquet and AVRO
Parquet and AVRO
 
BigData_TP2: Design Patterns dans Hadoop
BigData_TP2: Design Patterns dans HadoopBigData_TP2: Design Patterns dans Hadoop
BigData_TP2: Design Patterns dans Hadoop
 
Chp2 - Les Entrepôts de Données
Chp2 - Les Entrepôts de DonnéesChp2 - Les Entrepôts de Données
Chp2 - Les Entrepôts de Données
 
Chp3 - Modélisation Multidimensionnelle
Chp3 - Modélisation MultidimensionnelleChp3 - Modélisation Multidimensionnelle
Chp3 - Modélisation Multidimensionnelle
 
Programmation Fonctionnelle
Programmation FonctionnelleProgrammation Fonctionnelle
Programmation Fonctionnelle
 
Big Data : SQL, NoSQL ? Pourquoi faire un choix ?
Big Data : SQL, NoSQL ? Pourquoi faire un choix ?Big Data : SQL, NoSQL ? Pourquoi faire un choix ?
Big Data : SQL, NoSQL ? Pourquoi faire un choix ?
 
Appalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSPAppalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSP
 
Spark graphx
Spark graphxSpark graphx
Spark graphx
 
Installation hadoopv2.7.4-amal abid
Installation hadoopv2.7.4-amal abidInstallation hadoopv2.7.4-amal abid
Installation hadoopv2.7.4-amal abid
 
Interface fonctionnelle, Lambda expression, méthode par défaut, référence de...
Interface fonctionnelle, Lambda expression, méthode par défaut,  référence de...Interface fonctionnelle, Lambda expression, méthode par défaut,  référence de...
Interface fonctionnelle, Lambda expression, méthode par défaut, référence de...
 

En vedette

Spark SQL principes et fonctions
Spark SQL principes et fonctionsSpark SQL principes et fonctions
Spark SQL principes et fonctionsMICHRAFY MUSTAFA
 
Scala: Pattern matching, Concepts and Implementations
Scala: Pattern matching, Concepts and ImplementationsScala: Pattern matching, Concepts and Implementations
Scala: Pattern matching, Concepts and ImplementationsMICHRAFY MUSTAFA
 
Apache SPARK ML : principes, concepts et mise en œuvre
Apache SPARK  ML : principes, concepts et  mise en œuvre Apache SPARK  ML : principes, concepts et  mise en œuvre
Apache SPARK ML : principes, concepts et mise en œuvre MICHRAFY MUSTAFA
 
Spark RDD : Transformations & Actions
Spark RDD : Transformations & ActionsSpark RDD : Transformations & Actions
Spark RDD : Transformations & ActionsMICHRAFY MUSTAFA
 
Base de données graphe, Noe4j concepts et mise en oeuvre
Base de données graphe, Noe4j concepts et mise en oeuvreBase de données graphe, Noe4j concepts et mise en oeuvre
Base de données graphe, Noe4j concepts et mise en oeuvreMICHRAFY MUSTAFA
 
Programmation fonctionnelle
Programmation fonctionnelleProgrammation fonctionnelle
Programmation fonctionnelleJean Detoeuf
 
Big Data: Concepts, techniques et démonstration de Apache Hadoop
Big Data: Concepts, techniques et démonstration de Apache HadoopBig Data: Concepts, techniques et démonstration de Apache Hadoop
Big Data: Concepts, techniques et démonstration de Apache Hadoophajlaoui jaleleddine
 
Tour d’horizon de scala
Tour d’horizon de scalaTour d’horizon de scala
Tour d’horizon de scalaBenoit Wilcox
 
Scala - La transformation numérique (Français)
Scala - La transformation numérique (Français)Scala - La transformation numérique (Français)
Scala - La transformation numérique (Français)SCALA
 
Formuler son objectif, l'évaluer et tracer le plan d'action optimal: Un trava...
Formuler son objectif, l'évaluer et tracer le plan d'action optimal: Un trava...Formuler son objectif, l'évaluer et tracer le plan d'action optimal: Un trava...
Formuler son objectif, l'évaluer et tracer le plan d'action optimal: Un trava...Fabrice Bronsart
 
Big Data - Open Coffee Brest - 20121121
Big Data - Open Coffee Brest - 20121121Big Data - Open Coffee Brest - 20121121
Big Data - Open Coffee Brest - 20121121Mathias Herberts
 
No more (unsecure) secrets, Marty
No more (unsecure) secrets, MartyNo more (unsecure) secrets, Marty
No more (unsecure) secrets, MartyMathias Herberts
 
This is not your father's monitoring.
This is not your father's monitoring.This is not your father's monitoring.
This is not your father's monitoring.Mathias Herberts
 
Artimon - Apache Flume (incubating) NYC Meetup 20111108
Artimon - Apache Flume (incubating) NYC Meetup 20111108Artimon - Apache Flume (incubating) NYC Meetup 20111108
Artimon - Apache Flume (incubating) NYC Meetup 20111108Mathias Herberts
 
Insulinotherapie en 2013
Insulinotherapie en 2013Insulinotherapie en 2013
Insulinotherapie en 2013djamel bouema
 

En vedette (20)

Spark SQL principes et fonctions
Spark SQL principes et fonctionsSpark SQL principes et fonctions
Spark SQL principes et fonctions
 
Scala: Pattern matching, Concepts and Implementations
Scala: Pattern matching, Concepts and ImplementationsScala: Pattern matching, Concepts and Implementations
Scala: Pattern matching, Concepts and Implementations
 
Apache SPARK ML : principes, concepts et mise en œuvre
Apache SPARK  ML : principes, concepts et  mise en œuvre Apache SPARK  ML : principes, concepts et  mise en œuvre
Apache SPARK ML : principes, concepts et mise en œuvre
 
Spark RDD : Transformations & Actions
Spark RDD : Transformations & ActionsSpark RDD : Transformations & Actions
Spark RDD : Transformations & Actions
 
Base de données graphe, Noe4j concepts et mise en oeuvre
Base de données graphe, Noe4j concepts et mise en oeuvreBase de données graphe, Noe4j concepts et mise en oeuvre
Base de données graphe, Noe4j concepts et mise en oeuvre
 
Programmation fonctionnelle
Programmation fonctionnelleProgrammation fonctionnelle
Programmation fonctionnelle
 
Big Data: Concepts, techniques et démonstration de Apache Hadoop
Big Data: Concepts, techniques et démonstration de Apache HadoopBig Data: Concepts, techniques et démonstration de Apache Hadoop
Big Data: Concepts, techniques et démonstration de Apache Hadoop
 
spark_intro_1208
spark_intro_1208spark_intro_1208
spark_intro_1208
 
Tour d’horizon de scala
Tour d’horizon de scalaTour d’horizon de scala
Tour d’horizon de scala
 
Scala - La transformation numérique (Français)
Scala - La transformation numérique (Français)Scala - La transformation numérique (Français)
Scala - La transformation numérique (Français)
 
Paralell collections in Scala
Paralell collections in ScalaParalell collections in Scala
Paralell collections in Scala
 
Formuler les objectifs
Formuler les objectifsFormuler les objectifs
Formuler les objectifs
 
Formuler son objectif, l'évaluer et tracer le plan d'action optimal: Un trava...
Formuler son objectif, l'évaluer et tracer le plan d'action optimal: Un trava...Formuler son objectif, l'évaluer et tracer le plan d'action optimal: Un trava...
Formuler son objectif, l'évaluer et tracer le plan d'action optimal: Un trava...
 
Big Data - Open Coffee Brest - 20121121
Big Data - Open Coffee Brest - 20121121Big Data - Open Coffee Brest - 20121121
Big Data - Open Coffee Brest - 20121121
 
No more (unsecure) secrets, Marty
No more (unsecure) secrets, MartyNo more (unsecure) secrets, Marty
No more (unsecure) secrets, Marty
 
This is not your father's monitoring.
This is not your father's monitoring.This is not your father's monitoring.
This is not your father's monitoring.
 
Artimon - Apache Flume (incubating) NYC Meetup 20111108
Artimon - Apache Flume (incubating) NYC Meetup 20111108Artimon - Apache Flume (incubating) NYC Meetup 20111108
Artimon - Apache Flume (incubating) NYC Meetup 20111108
 
0712_Seigneurin
0712_Seigneurin0712_Seigneurin
0712_Seigneurin
 
The Hadoop Ecosystem
The Hadoop EcosystemThe Hadoop Ecosystem
The Hadoop Ecosystem
 
Insulinotherapie en 2013
Insulinotherapie en 2013Insulinotherapie en 2013
Insulinotherapie en 2013
 

Similaire à Scala : programmation fonctionnelle

Développement informatique : Programmation fonctionnelle, décorateur et génér...
Développement informatique : Programmation fonctionnelle, décorateur et génér...Développement informatique : Programmation fonctionnelle, décorateur et génér...
Développement informatique : Programmation fonctionnelle, décorateur et génér...ECAM Brussels Engineering School
 
Visual Studio 2008 Overview
Visual Studio 2008 OverviewVisual Studio 2008 Overview
Visual Studio 2008 OverviewGregory Renard
 
03_Prog_C_Fonctions.pdf
03_Prog_C_Fonctions.pdf03_Prog_C_Fonctions.pdf
03_Prog_C_Fonctions.pdfAhmed12314
 
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
 
Cours de C++, en français, 2002 - Cours 2.1
Cours de C++, en français, 2002 - Cours 2.1Cours de C++, en français, 2002 - Cours 2.1
Cours de C++, en français, 2002 - Cours 2.1Laurent BUNIET
 
Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logiciellecyrilgandon
 
02 Spécificité du C++ COURS SYS SYSSSSSS
02 Spécificité du C++  COURS SYS SYSSSSSS02 Spécificité du C++  COURS SYS SYSSSSSS
02 Spécificité du C++ COURS SYS SYSSSSSSAyoubElmrabet6
 
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 OCamlStéphane Legrand
 
C2 - Langage C - ISIMA 1 - Deuxieme partie
C2 - Langage C - ISIMA 1 - Deuxieme partieC2 - Langage C - ISIMA 1 - Deuxieme partie
C2 - Langage C - ISIMA 1 - Deuxieme partieLoic Yon
 
Les nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ ModerneLes nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ ModerneMicrosoft
 
Introduction à scala
Introduction à scalaIntroduction à scala
Introduction à scalaSOAT
 
Découvrez C# 4.0 et les améliorations apportées à la BCL
Découvrez C# 4.0 et les améliorations apportées à la BCLDécouvrez C# 4.0 et les améliorations apportées à la BCL
Découvrez C# 4.0 et les améliorations apportées à la BCLDotNetHub
 

Similaire à Scala : programmation fonctionnelle (20)

Développement informatique : Programmation fonctionnelle, décorateur et génér...
Développement informatique : Programmation fonctionnelle, décorateur et génér...Développement informatique : Programmation fonctionnelle, décorateur et génér...
Développement informatique : Programmation fonctionnelle, décorateur et génér...
 
Visual Studio 2008 Overview
Visual Studio 2008 OverviewVisual Studio 2008 Overview
Visual Studio 2008 Overview
 
Chapitre 04 : les fonctions
Chapitre 04 : les fonctionsChapitre 04 : les fonctions
Chapitre 04 : les fonctions
 
03_Prog_C_Fonctions.pdf
03_Prog_C_Fonctions.pdf03_Prog_C_Fonctions.pdf
03_Prog_C_Fonctions.pdf
 
Seance 3- Programmation en langage C
Seance 3- Programmation en langage C Seance 3- Programmation en langage C
Seance 3- Programmation en langage C
 
Theme 7
Theme 7Theme 7
Theme 7
 
Cours de C++, en français, 2002 - Cours 2.1
Cours de C++, en français, 2002 - Cours 2.1Cours de C++, en français, 2002 - Cours 2.1
Cours de C++, en français, 2002 - Cours 2.1
 
Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logicielle
 
Chapitre 1 rappel
Chapitre 1 rappelChapitre 1 rappel
Chapitre 1 rappel
 
Chapitre 1 rappel
Chapitre 1 rappelChapitre 1 rappel
Chapitre 1 rappel
 
C# 7 - Nouveautés
C# 7 - NouveautésC# 7 - Nouveautés
C# 7 - Nouveautés
 
COURS_PYTHON_22.ppt
COURS_PYTHON_22.pptCOURS_PYTHON_22.ppt
COURS_PYTHON_22.ppt
 
POO en C++: Les fonctions
POO en C++: Les fonctionsPOO en C++: Les fonctions
POO en C++: Les fonctions
 
02 Spécificité du C++ COURS SYS SYSSSSSS
02 Spécificité du C++  COURS SYS SYSSSSSS02 Spécificité du C++  COURS SYS SYSSSSSS
02 Spécificité du C++ COURS SYS SYSSSSSS
 
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
 
C2 - Langage C - ISIMA 1 - Deuxieme partie
C2 - Langage C - ISIMA 1 - Deuxieme partieC2 - Langage C - ISIMA 1 - Deuxieme partie
C2 - Langage C - ISIMA 1 - Deuxieme partie
 
Les nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ ModerneLes nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ Moderne
 
Introduction à scala
Introduction à scalaIntroduction à scala
Introduction à scala
 
Découvrez C# 4.0 et les améliorations apportées à la BCL
Découvrez C# 4.0 et les améliorations apportées à la BCLDécouvrez C# 4.0 et les améliorations apportées à la BCL
Découvrez C# 4.0 et les améliorations apportées à la BCL
 
Pensez objets avec java
Pensez objets avec javaPensez objets avec java
Pensez objets avec java
 

Scala : programmation fonctionnelle

  • 1. SCALA PROGRAMMATION FONCTIONNELLE CONCEPTS ET MISE EN ŒUVRE Dr Mustapha Michrafy M. MICHRAFY Contact de l’auteur : datascience.km@gmail.com datascience.km@gmail.com1
  • 2. Contexte Cette étude a été présentée dans le cadre du séminaire « Data Science principes, outils et applications » au laboratoire Cermsem. datascience.km@gmail.comM. MICHRAFY 2
  • 3. Plan • Objectif • Prérequis • Tout est fonction • Fonction pure • Fonction anonyme • Fonction d’ordre supérieur • Clôture • Fonction partielle • Récursivité • Curryfication datascience.km@gmail.comM. MICHRAFY 3
  • 4. Objectif Cette étude vise à présenter la programmation fonctionnelle sous Scala. datascience.km@gmail.comM. MICHRAFY 4
  • 5. Prérequis • Connaissance du langage Scala • Notion de récursivité datascience.km@gmail.comM. MICHRAFY 5
  • 6. Tout est fonction • Dans le paradigme fonctionnel, tout est fonction. • Un traitement complexe est composé de plusieurs fonctions datascience.km@gmail.comM. MICHRAFY 6
  • 7. Fonction en scala • En scala, une fonction est un objet qui peut être affecté à une variable. • La définition d’une fonction peut être effectuée n’importe où dans un fichier source. • La définition d’une fonction en scala nécessite l’utilisation du mot clé def suivi du nom de la fonction, de zéro, d’un ou de plusieurs arguments d’entrée, le type de retour et le corps de la fonction def add(x:Int, y:Int) : Int = {return x+y;} Nom de la fonction Arguments d’entrée Valeur de retour Corps de la fonction datascience.km@gmail.comM. MICHRAFY 7
  • 8. Appel à une fonction en scala • L’appel d’une fonction se fait via son nom, suivi par les arguments d’entrée entre parenthèses et séparés par un virgule. • Si la fonction ne demande pas d’argument d’entrée, l’appel se fait seulement avec son nom, et optionnellement suivi par une paire de parenthèses vides (). def add(x:Int, y:Int) : Int = {return x+y;} Add(8,17) Appel de la fonction add Définition de la fonction add def hello() = hello() hello Définition de la fonction hello Appel de la fonction hello avec () Appel de la fonction hello sans () datascience.km@gmail.comM. MICHRAFY 8
  • 9. Fonction pure • Une fonction pure est une fonction qui respecte les 2 critères suivants : 1. La fonction est déterministe, c-à-d renvoie toujours la même valeur pour les mêmes arguments 2. La fonction ne retourne que la valeur résultat, sans effet de bord. • Les fonctions arithmétiques sont des fonctions pures • Les fonctions mathématiques sont des fonctions pures • Toute fonction à effet de bord n’est pas une fonction pure datascience.km@gmail.comM. MICHRAFY 9
  • 10. Fonctions mathématiques Fonction Sin def sin(x:Double) : Double = Math.sin(x) Fonction identité def identite(x:Double) : Double = x Fonction constante def constante(x:Double) : Double = 7 Fonction affine def affine(x:Double) : Double = 3*x+5 Formulation syntaxique en scala Nom de la fonction Argument d’entré et son type Expression de retour Type de retour datascience.km@gmail.comM. MICHRAFY 10
  • 11. Fonctions mathématiques scalascalascalascala> defdefdefdef sin(x : Double) : Doublesin(x : Double) : Doublesin(x : Double) : Doublesin(x : Double) : Double ==== Math.sinMath.sinMath.sinMath.sin(x)(x)(x)(x) sin: (x: Double)Double scalascalascalascala> sin(80) res0: Double = -0.9938886539233752 scalascalascalascala> def identite(x : Double) : Double = {return x;} identite: (x: Double)Double scalascalascalascala> identite(80) res1: Double = 80.0 scalascalascalascala> def constante(x : Double) : Double = 13 constante: (x: Double)Double scalascalascalascala> constante(80) res2: Double = 13.0 scalascalascalascala> def affine(x : Double) : Double = 3*x + 5 affine: (x : Double)Double scalascalascalascala> affine(80) res3: Double = 245.0 datascience.km@gmail.comM. MICHRAFY 11 Signature de la fonction
  • 12. Fonction anonyme : principe • Une fonction anonyme en scala permet de définir une fonction sans déclarer le nom de la fonction • Une fonction anonyme est similaire à une lambda expression et permet de créer des fonctions à la volée • Une fonction anonyme peut être utilisée : • pour initialiser une variable • comme argument d’une fonction • comme valeur de retour d’une fonction datascience.km@gmail.comM. MICHRAFY 12
  • 13. Fonction anonyme : syntaxe • La syntaxe d’une fonction anonyme commence par une liste d’arguments séparés par des virgules et entourés par des parenthèses. Observons l’exemple suivant : scala> val add = (x:Int, y:Int) => x+y La fonction anonymeAdd est initialisé par la fonction anonyme datascience.km@gmail.comM. MICHRAFY 13
  • 14. Fonction anonyme : invocation scala> val add = (x:Int, y:Int) => x+y add: (Int, Int) => Int = <function2> scala> add(7,8) res4: Int = 15 Invocation de la fonction anonyme Définition de la fonction anonyme Comment les fonctions anonymes sont-elles créées ? Pourquoi <fonction2>? datascience.km@gmail.comM. MICHRAFY 14
  • 15. Fonction anonyme : construction scala> val add1:(Int, Int) => Int = (x:Int, y:Int) => x+y add1: (Int, Int) => Int = <function2>= <function2>= <function2>= <function2> scala> add1(1,10) res0: Int = 11 scala> val add2: Function2[Function2[Function2[Function2[Int,Int,IntInt,Int,IntInt,Int,IntInt,Int,Int]]]] = ((((x:Intx:Intx:Intx:Int, y:Int) =>, y:Int) =>, y:Int) =>, y:Int) => x+yx+yx+yx+y add2: (Int, Int) => Int = <function2><function2><function2><function2> scala> add2.applyapplyapplyapply(1,10) res1: Int = 11 • Une fonction anonyme est instanciée par un objet de type « fonction » • L’objet étend le type FonctionNFonctionNFonctionNFonctionN, N désignant l’arité de la fonction anonymes • L ’objet FonctionN dispose d’une méthode « apply » datascience.km@gmail.comM. MICHRAFY 15
  • 16. Fonction comme variable • En scala et dans le paradigme fonctionnel en général, nous pouvons utiliser une fonction comme variable. scala> val valImpair = (n:Int) => 2*n + 1 valImpair: Int => Int = <function1> scala> valImpair(10) res3: Int = 21 La variable valImpair a pour valeur la fonction <function1> datascience.km@gmail.comM. MICHRAFY 16
  • 17. Fonction comme argument : déclaration • Il est aussi possible de définir une fonction qui prend en entrée une fonction • Ce principe est similaire au pointeur de fonction en C/C++ ou aux interfaces fonctionnelles en Java • Il suffit de déclarer la signature de la fonction defdefdefdef nomFonctionnomFonctionnomFonctionnomFonction(fctfctfctfct:([:([:([:([paramsparamsparamsparams]) =>]) =>]) =>]) => typeRetourtypeRetourtypeRetourtypeRetour, arg:type, ...) : typeRetourtypeRetourtypeRetourtypeRetour = {....} Fonction comme argument d’une autre fonction datascience.km@gmail.comM. MICHRAFY 17
  • 18. Fonction comme argument : exemple scala>scala>scala>scala> def operationoperationoperationoperation(op:(op:(op:(op:(Int,IntInt,IntInt,IntInt,Int)=>Int)=>Int)=>Int)=>Int, x:Int,y:Int) : Int = op(x,y) operation: (op: (Int, Int) => Int, x: Int, y: Int)Int scala>scala>scala>scala> def addaddaddadd(x:Int,y:Int):Int = x+y add: (x: Int, y: Int)Int scala>scala>scala>scala> def produitproduitproduitproduit(x:Int, y:Int):Int = x*y produit: (x: Int, y: Int)Int scala>scala>scala>scala> operationoperationoperationoperation(addaddaddadd,7,8) res4: Int = 15 scala>scala>scala>scala> operationoperationoperationoperation(produit,produit,produit,produit,7,8) res5: Int = 56 operation a la fonction op comme argument Les fonctions add et produit ont la même signature que op Appel de la fonction operation avec add comme paramètre Appel à la fonction operation avec produit comme paramètre datascience.km@gmail.comM. MICHRAFY 18
  • 19. Fonction comme valeur de retour • Il est aussi possible d’avoir une fonction comme valeur de retour d’une fonction • Dans ce cas, la fonction doit avoir une valeur de retour de type fonction ou une fonction anonyme • Il préférable d’utiliser les accolades pour la lisibilité. datascience.km@gmail.comM. MICHRAFY 19
  • 20. Fonction comme valeur de retour scala>scala>scala>scala> def fabriqueFctAffinefabriqueFctAffinefabriqueFctAffinefabriqueFctAffine(a:Int ,b:Int) : (Int)=>Int | = {(x:Int)=> a*x+b} fabriqueFctAffine: (a: Int, b: Int)Int => Int scalascalascalascala> def diag = fabriqueFctAffinefabriqueFctAffinefabriqueFctAffinefabriqueFctAffine(2,3) diag: Int => Int scalascalascalascala> diag(1) res0: Int = 5 datascience.km@gmail.comM. MICHRAFY 20 La fonction fabriqueFctAffine renvoie une fonction affine ayant pour coefficients les arguments a et b fournis en entrée diag est la fonction définit par : → → 2 3 Signature de la fonction fabriqueFctAffine Signature de la fonction diag
  • 21. La fonction composée • La fonction composée (notée o en mathématique) est la fonction qui prend en entrée deux fonctions et retourne la fonction composée des deux • Soient deux fonctions F et G, pour définir FoG, il est nécessaire que l’ensemble {G(x), x dans Domaine(G)} inclut dans Domaine(F) : ∶ 1 → 2, ∶ 2 → 2 ∶ 1 ∁ 2 datascience.km@gmail.comM. MICHRAFY 21
  • 22. La fonction composée datascience.km@gmail.comM. MICHRAFY 22 F(x) = x*x G(x) = x+1 FoG(x) = F(G(x)) = F(x + 1) = x*x+1 Formulation mathématique Opérateur o scala>scala>scala>scala> def FFFF(x : Int) : Int = x*x F: (x: Int)Int scala>scala>scala>scala> def GGGG(x : Int) : Int = x + 1 G: (x: Int)Int scala>scala>scala>scala> defdefdefdef compose(Fcompose(Fcompose(Fcompose(F:(Int)=>(Int), G:(Int)=>(Int)) : (Int)=>(Int) = (Int)=>F(G(Int)) compose: (F: Int => Int, G: Int => Int)Int => Intcompose: (F: Int => Int, G: Int => Int)Int => Intcompose: (F: Int => Int, G: Int => Int)Int => Intcompose: (F: Int => Int, G: Int => Int)Int => Int Compose(F,G) = FoG
  • 23. Clôture : principe • Une clôture ou fermeture est une fonction dont la valeur de retour dépend de la valeur d'une ou plusieurs variables déclarées à l'extérieur de cette fonction • Les clôtures permettent d’encapsuler une partie du contexte d’exécution dans une fonction datascience.km@gmail.comM. MICHRAFY 23
  • 24. Clôture : exemple scala> val a = 2 a: Int = 2 scala> val b = 3 b: Int = 3 scala> def affine(x:Int,y:Int):Int = aaaa*x + bbbb affine: (x: Int, y: Int)Int scala> affine(1,1) res7: Int = 5 a, b sont déclarées en dehors de la portée de la fonction affine datascience.km@gmail.comM. MICHRAFY 24
  • 25. Fonction partielle • En figeant les valeurs d’un sous-ensemble des paramètres d’une fonction connue, on obtient une fonction partielle (projection, spécialisation) scala>scala>scala>scala> def produit(x:Int, y:Int):Int = x*y produit: (x: Int, y: Int)Int scala>scala>scala>scala> val partialyProduit = produit(2,_:Int)produit(2,_:Int)produit(2,_:Int)produit(2,_:Int) partialyProduit: Int => Int = <function1<function1<function1<function1>>>> scala>scala>scala>scala> partialyProduit(7) res10: Int = 14 datascience.km@gmail.comM. MICHRAFY 25
  • 26. Fonction récursive • Une fonction récursive est une fonction qui peut s’appeler elle-même. • La récursivité reproduit le formalisme de la relation de récurrence en mathématique • La récursivité doit satisfaire deux conditions : • Un ou plusieurs cas d’arrêts qui ne font pas appel à la fonction • Définir le cas général en fonction des états antérieurs • La récursivité est un principe fondamental en programmation fonctionnelle, permettant de remplacer les boucles. datascience.km@gmail.comM. MICHRAFY 26
  • 27. Fonction récursive : intérêt • Pour des structures de données récursives, il est bien plus facile d'écrire des algorithmes récursifs qu'itératifs • Certains algorithmes sont extrêmement difficiles à écrire dans un style itératif • Dans certains cas, les fonctions récursives permettent d’écrire des programmes très lisibles, et aussi de concevoir des algorithmes dont l'analyse ou la preuve sera facilitée. datascience.km@gmail.comM. MICHRAFY 27
  • 28. Fonction récursive : Calcul PGCD datascience.km@gmail.comM. MICHRAFY 28 a = kb + r et 0 ≤ r < b a si b=0 PGCD(b,r) PGDC(a,b)= Algorithme d’Euclide appel à PGCD(42,24) . Appel a PGCD(24,18) .. Appel à PGCD(18,6) …Appel à PGCD(6,0) ….retour 6 scalascalascalascala>>>> defdefdefdef pgcdpgcdpgcdpgcd((((a:Int,b:Inta:Int,b:Inta:Int,b:Inta:Int,b:Int) :) :) :) : IntIntIntInt ={={={={ |||| if(bif(bif(bif(b==0) a==0) a==0) a==0) a |||| elseelseelseelse pgcdpgcdpgcdpgcd((((b,b%ab,b%ab,b%ab,b%a)))) | }| }| }| } pgcd: (a: Int, b: Int)Int scalascalascalascala> pgcd(42,24) res0: Int = 6
  • 29. Fonction récursive : pile d’exécution • Chaque appel d’une fonction récursive est associé à un contexte d’exécution propre • Ce contexte d’exécution est composé de : • l'adresse mémoire de l'instruction qui a appelé la fonction • les valeurs des paramètres et des variables définies par la fonction • La récursivité implique une allocation dynamique de la mémoire. • La pile d’exécution fonctionne selon le principe LIFO • La pile ayant une taille fixe, une mauvaise utilisation de la récursivité peut entraîner son débordement. datascience.km@gmail.comM. MICHRAFY 29
  • 30. Fonction récursive : pile d’exécution appel à fact(4) . 4*fact(3) = ? . appel à fact(3) . . 3*fact(2) = ? . . appel à fact(2) . . . 2*fact(1) = ? . . . appel à fact(1) . . . . 1*fact(0) = ? . . . . appel à fact(0) . . . . retour de la valeur 1 . . . . 1*1 . . . retour de la valeur 1 . . . 2*1 . . retour de la valeur 2 . . 3*2 . retour de la valeur 6 . 4*6 retour de la valeur 24 scalascalascalascala>>>> def fact(n : Int) : Int | = if(n==0) 1 else n*fact(n-1) fact: (n: Int)Int scalascalascalascala>>>> fact(4) res2: Int = 24 1 si n=0 n*fact(n-1)fact(n)= datascience.km@gmail.comM. MICHRAFY 30
  • 31. La récursivité : terminale ou non ? Deux types Terminale Non Terminale datascience.km@gmail.comM. MICHRAFY 31 • Une fonction f est récursive terminale, si tous les appels récursifs invoquent f au plus une fois et sont de la forme return f(…) • Une fonction récursive terminale a un coût en mémoire constant (pas d’empilement des appels récursifs). • Il est toujours possible de transformer une fonction récursive non terminale en une fonction terminale en introduisant des accumulateurs comme arguments d’entrée
  • 32. Récursivité : Transformation def factNonTerminalfactNonTerminalfactNonTerminalfactNonTerminal(n:Int):Int ={ if(n==0) 1 else n+factNonTerminalfactNonTerminalfactNonTerminalfactNonTerminal(n-1) } datascience.km@gmail.comM. MICHRAFY 32 def factTerminalfactTerminalfactTerminalfactTerminal(n:Int, m:Int) : Int ={ if(n==0) m else factTerminalfactTerminalfactTerminalfactTerminal(n-1,m*n) } Transformation Terminale Fonction récursive non terminale Fonction récursive terminale accumulateur
  • 33. Récursivité : fonctions enveloppe et auxiliaire • Une fonction enveloppe est une fonction qui encapsule une fonction ou plusieurs (nommée fonction enveloppée ou auxiliaire). • Les fonctions enveloppes peuvent être utilisées pour initialiser les arguments d’une fonction récursive terminale • La réécriture d’une fonction en récursivité terminale nécessite l’introduction d’un argument ou plusieurs et dont l’initialisation dépend de l’implémentation. La solution consiste à implémenter une fonction récursive terminale comme une fonction auxiliaire d’une fonction principale datascience.km@gmail.comM. MICHRAFY 33
  • 34. Récursivité : réécriture d’une fonction def factNonTerminalfactNonTerminalfactNonTerminalfactNonTerminal(n:Int):Int ={ if(n==0) 1 else n+factNonTerminalfactNonTerminalfactNonTerminalfactNonTerminal(n-1) } datascience.km@gmail.comM. MICHRAFY 34 def factTerminalfactTerminalfactTerminalfactTerminal(n:Int, m:Int) : Int ={ if(n==0) m else factTerminalfactTerminalfactTerminalfactTerminal(n-1,m*n) } Transformation Terminale def factfactfactfact(n : Int) : Int = { def factTerminalfactTerminalfactTerminalfactTerminal(n:Int, m:Int) : Int ={ if(n==0) m else factTerminalfactTerminalfactTerminalfactTerminal(n-1,m*n) } factTerminalfactTerminalfactTerminalfactTerminal(n,1(n,1(n,1(n,1)))) } Réécriture de la fonction Définition de la fonction auxiliaire 1 2 Appel à la fonction auxiliaire avec deux arguments dont un est initialisé à 1
  • 35. Récursivité : Primalité d’un nombre • Un nombre p est premier s’il admet que deux diviseurs 1 et n • Tout nombre pair est non premier à l’exception de 2 • Pour améliorer les performance, il suffit de tester seulement les nombre entre 2 et √ . • Comme un nombre premier est toujours impair – à l’exception de 2- il suffit de tester les nombre impairs entre 3 et √ .Mais ceci est utile pour un algorithme itératif datascience.km@gmail.comM. MICHRAFY 35
  • 36. Récursivité : Primalité d’un nombre def isPrimAuxisPrimAuxisPrimAuxisPrimAux((((p:Intp:Intp:Intp:Int, d:Int), d:Int), d:Int), d:Int) : Boolean={ if(d*d <= p){ if(p%d==0) false else isPrimAux(p,d+1); } else true } def isPrimisPrimisPrimisPrim((((p:Intp:Intp:Intp:Int)))) : Boolean ={ def isPrimAux(p:Int, d:Int):Boolean ={ if(d*d <= p){ if(p%d==0) false else isPrimAux(p,d+1); } else true } isPrimAux(p,2) } d=2 isPrim(p) = si d*d <= p si d/p alors faux sinon estPrim(p,d+1) sinon vrai Algorithme pour tester la primalité 1 2 datascience.km@gmail.comM. MICHRAFY 36
  • 37. Récursivité: fonction d’ordre sup. • n et m deux entiers, n < m • Calculer A et B : - ∑ - ∑ datascience.km@gmail.comM. MICHRAFY 37 Similarité : la somme !: → ! #: → # $ !% & , $ # Réécriture de A et B Ecrire une fonction sum qui prend en entrée une fonction f Idée '() !, , ) 0 ' + ) ! '() !, 1, ) ' Relation de récurrence.
  • 38. Récursivité: fonction d’ordre sup. • n et m deux entiers, n < m • Calculer A et B : - ∑ - ∑ datascience.km@gmail.comM. MICHRAFY 38 !: → ! #: → # $ !% & , $ # '() !, , ) 0 ' + ) ! '() !, 1, ) ' def sumsumsumsum(ffff: Int => Int, a: Int, b: Int): Int ={ if (a > b) 0 else f(a) + sum(f, a + 1, b) } val A = sum(x=>x) val B = sum(x=>x*x) def sumCompactesumCompactesumCompactesumCompacte(f: Int => Int): (Int, Int) => Int = { def sum(a: Int, b: Int): Int =if (a > b) 0 else f(a) + sum (a + 1, b) sum } Calcul de A et B
  • 39. Récursivité : stratégie d’implémentation • Un algorithme récursif peut donner lieu à plusieurs implémentations. • Ce cas se présente lorsque le problème est composé de plusieurs sous-problèmes de même nature. Ceci est similaire au principe de diviser pour régner ou aux algorithmes relevant de la programmation dynamique. • L’implémentation dépend à la fois de la : • La Stratégie du parcours ou de construction • L’initialisation des paramètres • Une mauvaise implémentation peut pénaliser le temps de calcul. Analysons la suite de Fibonacci datascience.km@gmail.comM. MICHRAFY 39
  • 40. Récursivité : Fibonacci, version naïve Fibonacci(n)= 0 si n = 0 1 si n =1 Fibonacci(n-1) + Fibonacci(n-2) Suite de fibonacci def fibonaccifibonaccifibonaccifibonacci(n:Int) : Int = { if(n < 2) n else fibonaccifibonaccifibonaccifibonacci(n-1) + fibonaccifibonaccifibonaccifibonacci(n-2) } datascience.km@gmail.comM. MICHRAFY 40
  • 41. Récursivité : analyse de l’algorithme Fibonacci 7 6 5 4 35 4 4 3 3 2 3 2 2 1 1 03 2 2 1 2 1 2 1 1 0 1 01 01 01 02 1 1 0 1 0 • Chaque nœud désigne un terme de la suite de fibonacci • Les nœuds -portant les valeurs 2 à 7- sont des appels récursifs • Les nœuds verts désignent les termes 0 et 1 de la suite fibonacci • On constate le calcul redondant généré par l’algorithme « naïf »de fibonacci. Arborescence de Fibonacci(7) 7 0 datascience.km@gmail.comM. MICHRAFY 41
  • 42. Récursivité : algorithme constructif de fibonacci • Le problème consiste à ne pas recalculer le même terme de fibonnaci plusieurs fois. • Remarquons que le terme n de Fibonacci nécessite le calcul des termes de n-1 à 0. • Par conséquent, pour éviter le calcul redondant, nous pouvons calculer le terme n en commençant par calculer le terme 0,1, 2 …. via la relation de récurrence. • Pour calculer le terme n sans redondance, il faut mémoriser les termes n-1 et n-2. • Nous avons besoin aussi d’un test d’arrêt, ce qui est le terme n. datascience.km@gmail.comM. MICHRAFY 42
  • 43. Récursivité : Fibonacci, algorithme constructif p, a1,a0 trois entiers Fibonacci(n,p,a1,a0) = n si n<2 Fibonacci(n,p+1,a1+a0,a1) si p<n a1+ a0 sinon a0 = 0, a1=1 ( a0 et a1 2 termes consécutifs de fibonacci) p=2, ( p varie de 2 à n) Relation de récursivité Etape d’initialisation • C’est un algorithme constructif. • A chaque étape, l’algorithme conserve les deux états m-1, m-2 • Les deux états consécutifs sont stockés dans a0 et a1 • Les termes 0 et 1 sont utilisés dans la phase d’initialisation • Le terme n de Fibonacci est la somme de a0 et a1 datascience.km@gmail.comM. MICHRAFY 43
  • 44. Récursivité : Fibonacci, algorithme constructif p, a1,a0 trois entiers Fibonacci(n,p,a1,a0) = n si n<2 Fibonacci(n,p+1,a1+a0,a1) si p<n a1+ a0 sinon 2 10 3 1 4 2 5 3 4 65 7 n=7, p=2, a0=0, a1=1 def fibonaccifibonaccifibonaccifibonacci(n:Int):Int={ def fibfibfibfib(n:Int, p:Int, a0:Int, a1:Int) : Int ={ if(n<2) n else{ if(p<n) fibfibfibfib(n, p+1, a1+a0,a1) else a1+a0 } } fib(n,2,1,0) } Plus de calcul redondant 0 7 Chaque ligne désigne les termes consécutifs datascience.km@gmail.comM. MICHRAFY 44
  • 45. Curryfication : principe • La curryfication désigne l'opération transforme une fonction à plusieurs arguments à une fonction à un argument qui retourne une fonction prenant le reste des arguments. Elle permet de convertir une fonction avec plusieurs paramètres en créant une chaîne de fonction, chacun attendant un seul argument. • En mathématique, on peut définir une fonction à plusieurs variables alors que le Lambda-calcul se limite à des fonctions avec une seule variable. Une correspondance « curryfication » bijective a été définie entre les fonctions Lambda-calcul et les fonctions multivariées datascience.km@gmail.comM. MICHRAFY 45
  • 46. Curryfication : Transformation • A chaque fonction multivariées, on associe une fonction avec une seule variable. La curryfication s’appuie sur les définition des fonctions partielles , → , - → - !. ∶ → → → !. - - Curryfication ! ∶ → , -, / → - / !.: 0 → → -, / → - / !.,1 ∶ → % → & / → - / → !. - → !.,1 Fonctions de curryfication → !. 2 1 datascience.km@gmail.comM. MICHRAFY 46
  • 47. Curryfication : méthode add scala> def add1add1add1add1(x:Double, y:Double):Double = x + y add1add1add1add1: (x: Double, y: Double)Double scala> def add1Curry = (x : Double) => (y : Double) => x + y add1Curry: Double => (Double => Double) scala> def add2add2add2add2(x:Int,y:Int,z:Int) : Int = x+y+z add2: (x: Int, y: Int, z: Int)Int scala> def add2Curryadd2Curryadd2Curryadd2Curry(x:Int) : Int => (Int => Int) = y => (z => x + y + z) add2Curryadd2Curryadd2Curryadd2Curry: (x: Int)Int => (Int => Int) Curryfication Curryfication datascience.km@gmail.comM. MICHRAFY 47
  • 48. Références bibliographiques • Beginning Scala, par David Pollak, 2015 • Programming in Scala, par Martin Odersky and al., 2011 • Programming Scala, par Dean Wampler, Alex Payne, 2014 • Functional Thinking par Neal Ford, 2014 • Functional Programming in Scala, par Paul Chiusano, Rúnar Bjarnason, 2014 datascience.km@gmail.comM. MICHRAFY
  • 49. Dr Mustapha Michrafy DataScientist, ATOS Contact : datascience.km@gmail.com datascience.km@gmail.comM. MICHRAFY 49