La programmation fonctionnelle en javascript / PF

26
La Programmation fonctionnelle en JavaScript AMINE EL HARRAK

Transcript of La programmation fonctionnelle en javascript / PF

La Programmation fonctionnelle en JavaScript

AMINE EL HARRAK

Sommaire

• Rappel sur les paradigmes de programmation

• Concept, avantage PF

• Quelques méthodes et exemples

• Bibliothèque à utiliser / Comment apprendre ?

• Conclusion

La Programmation fonctionnelle en JavaScript

Rappel sur les paradigmes de programmation

• la programmation impérative : Tout tourne autours du temps. On commence par créer une variable, on assigne une valeur à cette variable, on utilise des boucles for et while pour réaliser des actions on fait des test avec if then. Ces variables sont muables (mutable en anglais), c’est à dire qu’on peut leur donner de nouvelles valeurs dans le temps.

• la programmation logique : associe des règles de logique. Elle est particulièrement adaptée au monde de l’intelligence artificielle.

• la programmation fonctionnelle : utilise comme objet principal des fonctions. Les fonctions peuvent retourner des fonctions, prendre d’autres fonctions en paramètre. Les variables sont immuables (Les langages fonctionnels existent depuis toujours ! ~1950 )

La Programmation fonctionnelle en JavaScript

Pourquoi ce paradigme n'a pas été plus utilisé plus tôt ?

Obstacles techniques• Puissance des machines

• Utilisation mémoire• Processeur mono-cœur

Scientifique et académique• Application dans la recherche• Utilisé pour dans l'enseignement

Application industrielle spécifique• Programmation concurrente et

distribuée• Fault-tolerant systems

Renaissance

Contraintes de scalabilité de plus en plus forte (Google, Twitter ..)

Multi-coeurs, parallèlisme

Introduction des concepts dans les langages impératifs les plus utilisés

Montée en puissance de langages fonctionnels (Scala, Erlang, Clojure ...)

Pourquoi en avons nous besoin ?

• Aujourd’hui, de plus en plus de machines sont dotées de plusieurs microprocesseurs. De plus avec l’émergence du cloud computing, il est très aisé d’avoir plusieurs machines à sa disposition.

• D’autre part, de nombreuses applications ont besoin d’une grande capacité de calcul.

• Twitter par exemple doit gérer plusieurs centaines de milliers de tweets par seconde.

• C’est là que la programmation parallèle et la programmation concurrente entrent en jeu. Or il est compliqué dans un langage impératif de gérer plusieurs threads. Il faut notamment faire attention aux fameux points de blocages (deadlocks).De plus, en programmation parallèle avec des types muables , des phénomènes non-déterministes apparaissent…

• C’est ici que la force de la programmation fonctionnelle et ses types immuables entre en jeu.

• La programmation fonctionnelle est déjà utilisée par les plus grandes startups webs, comme Twitter et Linkedin justement pour gérer les problématiques de croissance (scalability en anglais).

La Programmation fonctionnelle en JavaScript

Concepts et avantages

• Immutabilité

• Fonctions d’ordre supérieur

• Lambda

• Récursivité

La Programmation fonctionnelle en JavaScript

Immutabilité

Ce concept permet de s'assurer de la valeur des variables du début à la fin de nos actions.

• code plus robuste

• code plus stable

• moins de bugs

• moins de maintenances

Une fonction ne doit pas modifier les variables qui lui sont passées en paramètre.

La Programmation fonctionnelle en JavaScript

Fonctions d'ordre supérieur

• Fonction qui prend au moins une autre fonction en paramètre pour fournir un résultat

• Réduit la quantité de code

• Compositions

• Développement plus haut niveau

La Programmation fonctionnelle en JavaScript

Fonctions d'ordre supérieur

// fonctions d'ordre supérieur

function add(a){

return function(b){

return a+b

}

};

add(3)(4) 7

var bump=add(1);

bump(3) 4

La Programmation fonctionnelle en JavaScript

Les lambdas

Les lambdas, aussi appelées fonctions anonymes, sont des fonctions utilisées de manière ponctuelle et n'effectuant généralement qu'une opération.

La Programmation fonctionnelle en JavaScript

Reprenons l'exemple de isEven().// utilisation d'une lambda en JavaScript

var evens = array. functionX(function(v) {

return v % 2 == 0;

});

// utilisation d'une lambda en CoffeeScript

var evens = array.functionX((v) -> v % 2 == 0);

La Programmation fonctionnelle en JavaScript

Récursivité

Il est possible d'utiliser la programmation fonctionnelle de manière récursive.

• Pas de "variables" donc boucle itérative impossible.

Cela va permettre d'avoir un code plus lisible et plus court.

De plus, le code s'auto documenter de lui-même.

La Programmation fonctionnelle en JavaScript

function factorial(num){

// If the number is less than 0, reject it.

if (num < 0) {

return -1;

}

// If the number is 0, its factorial is 1.

else if (num == 0) {

return 1;

}

var tmp = num;

while (num-- > 2) {

tmp *= num;

}

return tmp;

}

var result = factorial(8);

factorial Récursivité

function factorial(num) {

// If the number is less than 0, reject it.

if (num < 0) {

return -1;

}

// If the number is 0, its factorial is 1.

else if (num == 0) {

return 1;

}

// Otherwise, call this recursive procedure again.

else {

return (num * factorial(num - 1));

}

}

var result = factorial(8);

La Programmation fonctionnelle en JavaScript

Closures

• L'exécution d'une closure "ressemble" à l'instance d'un objet

• Scope de la fonction parente conservée après exécution

• Une closure ressemble à une fonction, mais est bien plus puissante. Elle peut être assignée à une variable, passée comme argument ou encore retournée par une autre fonction. On parle alors de high-order function.

La Programmation fonctionnelle en JavaScript

On va voir quelques concepts de FP qui peuvent s'appliquer à JavaScript, et comment ça améliore le code !

La Programmation fonctionnelle en JavaScript

Disponibilité

Certains concepts ne sont utilisables (correctement) que dans des langages fonctionnels

D'autres sont parfaitement utilisables dans un langage (moderne) impératif

• Natif avec ECMAScript 5

• Partout avec underscore.js

La Programmation fonctionnelle en JavaScript

var array = [1,2,3,4,5,6];

for (var i=0; i < array.length; i++) { array[i] = array[i] +1;}

// retourne [2,3,4,5,6,7];

map()

Natifvar array = [1,2,3,4,5,6];array.map(function(a) {return a + 1} );

underscorejsvar array = [1,2,3,4,5,6];_.map(array , function(a){ return a+1; });

La Programmation fonctionnelle en JavaScript

var str = '12345';[].map.call(str, function(x) {

return x;}).reverse()

.join('');

// Output: '54321‘// Bonus: use '===' to test if original string was a palindrome

La méthode call() réalise un appel à une fonction avec une valeur this et les arguments fournis individuellement.

La Programmation fonctionnelle en JavaScript

var array = [1,2,3,4,5,6];

// retourne true si la variable est pair, false sinon.

var isEven = function(v) {return v % 2 == 0;

};

var evens = [];

for (var i=0; i < array.length; i++) {if (isEven(array[i])) {

evens.push(array[i]);}

}

// retourne [2, 4, 6]

Natif var array = [1,2,3,4,5,6];var evens = array.filter(isEven);

filter()

Underscorejsvar array = [1,2,3,4,5,6];var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });

La Programmation fonctionnelle en JavaScript

Grep()Natif var allStarCast = [

{ firstName: "Zack", lastName: "Morris" },{ firstName: "Kelly", lastName: "Kapowski" },{ firstName: "Lisa", lastName: "Turtle" },{ firstName: "Screech", lastName: "Powers" },

{ firstName: "Jessie", lastName: "Spano" },{ firstName: "Richard", lastName: "Belding" }

]var worldsCutestCouple = $.grep(allStarCast, function(actor) {

return (actor.firstName === "Zack" || actor.firstName === "Kelly");});

console.log(worldsCutestCouple); [Object { firstName="Zack", lastName="Morris"}, Object { firstName="Kelly", lastName="Kapowski"}]

La Programmation fonctionnelle en JavaScript

var array = [1,2,3,4,5,6];

var sum = 0;

for (var i=0; i < array.length; i++) {Sum = sum +array[i];

}

// output : 21

Natif var array = [1,2,3,4,5,6];var sum = array .reduce(function(memo, a) {

return memo + a} );

reduce() / reduceRight()

Underscorejsvar array = [1,2,3,4,5,6];var sum = _.reduce(array , function(memo, num){ return memo + num; }, 0);

La Programmation fonctionnelle en JavaScript

(Récapitulatif)

Si vous avez un tableau et que vous voulez :

• Appliquer une transformation sur chacune de ses cases (en conservant leur ordre/nombre) :

• Supprimer certaines cases (en conservant l’ordre et le contenu des autres) :

• Parcourir pour construire une nouvelle structure de données :

map

filter

reduce

La Programmation fonctionnelle en JavaScript

Conclusion

• Écrire du code qui fonctionne ne suffit pas• Utiliser des mécanismes qui facilitent le raisonnement :

• transparence référentielle• fonctions d’ordre supérieur• évaluation paresseuse• immuabilité• systèmes de types avancés• ...

• La programmation fonctionnelle offre de belles manières d'écrire des programmes fiables et maintenables.

La Programmation fonctionnelle en JavaScript

COMMENT APPRENDRE ?

Casser ses habitudes

• Le plus simple pour y parvenir est de s'imerger

• Apprendre avec un langage à tendance fonctionnelle très importante le(s)quel(s) ? Scala

Penser différemment

Construire son programme avec un maximum de fonctions pures

La logique métier est fiable, sans surprise et aisément testable.

Isoler les fonctions qui ont des effets de bord

On sait quelles fonctions ont des effets de bord, ce qui permet d’être prudent lorsqu’on les manipule.

La Programmation fonctionnelle en JavaScript

Ressources

• Learn You A Haskell For Great Good : LE livre pour débuter Haskell ; il est très accessible (traduction FR non officielle)

• JavaScript Alongé : un livre avancé sur JavaScript ; il explique et met en place certains concepts que nous avons survolés ici

• Lo-Dash : une bibliothèque JavaScript qui propose notamment des fonctions d'ordre supérieur très intéressantes pour manipuler les collections

• Bacon.js : une bibliothèque JavaScript qui permet de faire de la programmation fonctionnelle réactive

• Underscore.js

• Is your programming language unreasonable? or, why predictability is important

QUESTION ?