Fermer

octobre 29, 2019

Qu'est-ce que la programmation fonctionnelle? –


En tant que programmeur, vous souhaiterez probablement écrire un code élégant, maintenable, évolutif et prévisible. Les principes de la programmation fonctionnelle, ou PF, peuvent considérablement contribuer à ces objectifs.

La programmation fonctionnelle est un paradigme, ou style, qui valorise l'immuabilité, les fonctions de première classe, la transparence référentielle et les fonctions pures. Si aucun de ces mots n’a de sens, ne vous inquiétez pas! Nous allons décomposer toute cette terminologie dans cet article.

La programmation fonctionnelle a évolué à partir du lambda calcul, un système mathématique construit autour de l’abstraction et de la généralisation des fonctions. En conséquence, beaucoup de langages de programmation fonctionnels ont une apparence très mathématique. Bonne nouvelle cependant: vous n'avez pas besoin d'utiliser un langage de programmation fonctionnel pour intégrer les principes de programmation fonctionnelle à votre code. Dans cet article, nous utiliserons JavaScript, qui comporte de nombreuses fonctionnalités qui la rendent accessible à la programmation fonctionnelle sans être lié à ce paradigme.

Principes fondamentaux de la programmation fonctionnelle

Maintenant que nous avons discuté de ce la programmation fonctionnelle est, parlons des principes de base de FP.

Fonctions pures

J'aime considérer les fonctions comme des machines: elles prennent une entrée ou des arguments, puis fournissent quelque chose, la valeur de retour. Les fonctions pures n’ont pas d’effets secondaires ou d’actions qui ne sont pas liées au résultat de la fonction. Certains effets secondaires potentiels seraient d’imprimer une valeur ou de la déconnecter avec console.log ou de manipuler des variables en dehors de la fonction.

Voici un exemple de fonction impure:

 let number = 2;

fonction squareNumber () {
  nombre = nombre * nombre; // action impure: manipuler une variable hors fonction
  console.log (nombre); // action impure: valeurs de journalisation de la console
  numéro de retour;
}

nombre carré();

La fonction ci-dessous est pure. Il prend une entrée et produit une sortie.

 // fonction pure
function squareNumber (nombre) {
  numéro de retour * numéro;
}

squareNumber (2);

Les fonctions pures fonctionnent indépendamment de l’état en dehors de la fonction, elles ne doivent donc pas dépendre d’un état global ni de variables en dehors de celle-ci. Dans le premier exemple, nous utilisons la variable number créée en dehors de la fonction et la plaçons à l'intérieur. Cela viole le principe. Si vous comptez beaucoup sur la modification constante des variables globales, votre code sera imprévisible et difficile à retracer. Il sera plus difficile de savoir où se trouvent les bugs et pourquoi les valeurs changent. En utilisant uniquement les entrées, les sorties et les variables locales aux fonctions, cela facilite le débogage.

De plus, les fonctions doivent suivre la transparence référentielle ce qui signifie que si une entrée est sélectionnée, leur sortie sera toujours la même. Dans la fonction ci-dessus, si je passe 2 à la fonction, elle retournera toujours 4 . Il n'en va pas de même pour les appels d'API ou la génération de nombres aléatoires, comme deux exemples. Si la même entrée est utilisée, la sortie peut être renvoyée ou non.

 // Non référentiel transparent.
Math.random ();
// 0.1406399143589343
Math.random ();
// 0.26768924082159495ß

Immutabilité

La ​​programmation fonctionnelle donne également la priorité à l'immutabilité ou ne modifie pas directement les données. L’immuabilité conduit à la prévisibilité – vous connaissez les valeurs de vos données et elles ne changent pas. Cela rend le code simple, testable et capable de fonctionner sur des systèmes distribués et multi-threadés.

L'immuabilité entre souvent en jeu lorsque nous travaillons avec des structures de données. De nombreuses méthodes de tableau en JavaScript modifient directement le tableau. Par exemple, .pop () supprime directement un élément de la fin du tableau et .splice () vous permet de prendre une section d'un tableau. Au lieu de cela, dans le paradigme fonctionnel, nous copions le tableau et éliminons ainsi l'élément que nous cherchons à éliminer.

 // Nous mutons directement myArr.
const myArr = [1, 2, 3];
myArr.pop ();
// [1, 2]
 // Nous copions le tableau sans le dernier élément et le stockons dans une variable
laissez myArr = [1, 2, 3];
laissez myNewArr = myArr.slice (0, 2);
// [1, 2]
console.log (myArr);

Fonctions de première classe

En programmation fonctionnelle, nos fonctions sont de première classe, ce qui signifie que nous pouvons les utiliser comme n'importe quelle autre valeur. Nous pouvons créer des tableaux de fonctions, les transmettre comme arguments à d'autres fonctions et les stocker dans des variables.

 let myFunctionArr = [() => 1 + 2, () => console.log("hi"), x => 3 * x];
myFunctionArr [2] (2); // 6

const myFunction = anotherFunction => anotherFunction (20);
const secondFunction = x => x * 10;
maFonction (secondeFonction); // 200

Fonctions d'ordre supérieur

Les fonctions d'ordre supérieur sont des fonctions qui remplissent l'une des deux fonctions suivantes: elles prennent une fonction sous la forme d'un ou de plusieurs paramètres ou renvoient une fonction. De nombreux types du premier type de fonctions d'ordre supérieur sont intégrés à JavaScript – tels que map réduire et filtre que nous pouvons utiliser pour interagir avec des tableaux.

Le filtre renvoie un nouveau tableau d'un ancien tableau contenant uniquement des valeurs correspondant à une condition, que nous fournissons.

 const myArr = [1, 2, 3, 4, 5];

const evens = myArr.filter (x => x% 2 === 0); // [2, 4]

La carte est utilisée pour parcourir les éléments d'un tableau, en modifiant chaque élément en fonction de la logique fournie. Dans l'exemple ci-dessous, nous doublons chaque élément d'un tableau en passant une fonction à la carte qui multiplie notre valeur par 2.

 const myArr = [1, 2, 3, 4, 5];

const doubled = myArr.map (i => i * 2); // [2, 4, 6, 8, 10]

réduire nous permet de générer une valeur unique basée sur un tableau saisi – elle est souvent utilisée pour additionner un tableau, des tableaux aplatis ou des valeurs de groupe.

 const myArr = [1, 2, 3, 4, 5];

const sum = myArr.reduce ((i, runningSum) => i + runningSum); // 15

Vous pouvez également implémenter ces solutions vous-même! Par exemple, vous pouvez créer une fonction de filtre comme celle-ci:

 const filter = (arr, condition) => {
  const filtréArr = [];

  pour (let i = 0; i <arr.length; i ++) {
    if (condition (arr [i])) {
      filtréArr.push (arr [i]);
    }
  }

  return filtréArr;
};

Le deuxième type de fonction d'ordre supérieur, les fonctions qui renvoient d'autres fonctions, est également un motif relativement fréquent. Par exemple:

 const createGreeting = greeting => person => `$ {greeting} $ {person}`

const sayHi = createGreeting ("Hi")
console.log (sayHi ("Ali")) // "Bonjour Ali"

const sayHello = createGreeting ("Bonjour")
console.log (sayHi ("Ali")) // "Bonjour Ali"

Le currying est une technique connexe sur laquelle vous pouvez également lire des informations!

Composition de fonction

La ​​composition de fonction consiste à combiner plusieurs fonctions simples afin de créer des fonctions plus complexes. . Ainsi, vous pourriez avoir une fonction averageArray qui combine une fonction moyenne avec une fonction sum qui récapitule les valeurs d’un tableau. Les fonctions individuelles sont petites et peuvent être réutilisées à d'autres fins et combinent une tâche plus complète.

 const sum = arr => arr.reduce ((i, runningSum) => i + runningSum);
const moyenne = (somme, compte) => somme / compte;
const moyenneArr = arr => moyenne (somme (arr), arr.longueur);

Avantages

La programmation fonctionnelle conduit au code modulaire. Vous avez de petites fonctions que vous pouvez réutiliser encore et encore. Connaître la fonctionnalité spécifique de chaque fonction signifie repérer les bogues et écrire les tests doit être simple, d'autant plus que les sorties de fonction doivent être prévisibles.

De plus, si vous essayez d'utiliser plusieurs cœurs, vous pouvez répartir les appels de fonction entre ces cœurs, cela permet donc de gagner en efficacité informatique.

Comment utiliser la programmation fonctionnelle?

Il n'est pas nécessaire de passer complètement à la programmation fonctionnelle pour intégrer toutes ces idées. Vous pouvez même utiliser bon nombre de ces idées en combinaison avec la programmation orientée objet, souvent considérée comme son adversaire.

React, par exemple, incorpore de nombreux principes fonctionnels comme l’état immuable, mais aussi utilisé la syntaxe de classe principalement pendant des années. Il peut également être implémenté dans presque tous les langages de programmation – vous n'avez pas besoin d'écrire Clojure ou Haskell, sauf si vous le souhaitez vraiment.

Les principes de programmation fonctionnelle peuvent conduire à des résultats positifs dans votre code, même si vous n'êtes pas un habitué puriste.




Source link