Le Curry en Javascript ES6

Je vous arrête de suite, les blagues sur le curry et l'implémentation curry, on me les a déjà faites en formation !

Peut être que vous en avez entendu parlé ou pas du tout pour les débutants. Peut-être que même ES6 est encore inconnu pour vous !

Vous n’avez peut-être pas le temps d’aller consulter les spécification ES6 alors on va résumer cette nouvelle fonctionnalité !

C’est quoi ce curry ?

Il s’agit d’un concept de la programmation fonctionnelle. Habituellement, on code en impératif.

Currying est un processus pour réduire les fonctions de plus d’un argument en fonctions d’un argument à l’aide du calcul lambda.

À l’ancienne, on ferait ça :

multiplier = (n, m) => (n * m)
multiplier(3, 4) === 12 // true

Maintenant avec curry :

curryMultiplication = (n) => ( (m) => multiplier(n, m) )
triple = curryMultiplication(3)
triple(4) === 12 // true

Comment ça fonctionne ?

L’implémentation de curry est définie par une suite d’opérations pour déterminer le résultat final, donc notre fonction va :

  • Accepte une fonction pour curry
  • Enregistre le nombre d’arguments que cette fonction devrait attendre
  • Renvoie une nouvelle “fonction curry”
  • Cette “fonction de curry” enregistre le nombre d’arguments qu’il reçoit
  • Si, ses arguments correspondent au nombre d’arguments que la fonction d’origine attend, nous appelons la fonction d’origine avec les arguments fournis
  • Sinon, nous renvoyons une nouvelle fonction qui attend le reste des arguments de la fonction d’origine
  • On combine les arguments et on appelle la fonction d’origine avec tous les args!

Est-ce qu’on peut inverser ?

Oui ! Tout à fait ! On peut faire l’inverse !

curryMultiplication = (n) => (m) => n * m
curryMultiplication(3)(4) === 12 // true
multiplier = (n, m) => curryMultiplication(n)(m)
multiplier(3, 4) === 12 // true

Notez que j’ai volontairement complexifié mon exemple, on aurait pu écrire aussi :

multiplier = (n, m) => n * m
multiplier(3, 4) === 12 // true
triple = (m) => multiplier(3, m)
triple(4) === 12 // true

Ce que voit c’est l’application partielle ce qui signifie que vous avez assigné une fonction en fonction de l’un de ses arguments.

Pratique lorsqu’on a un paramètre qui est constant !

Exemples de la vraie vie :

Binding

Le saviez-vous, la fonction “bind” en JavaScript utilise l’implémentation curry

function add (a, b) {
  return a+b;
}
increment = add.bind(undefined, 1)
increment(4) = 5;

Event

const handleEvent = (text) => (event) => {
  console.log(text, event.target.value)
}

<input type=”text” onChange={handleEvent(“hello”)} … />

Afficher de l’HTML

Une fonction peut être réutilisée pour afficher des tags

const renderHtmlTag = tagName => content => `<${tagName}>${content}</${tagName>`;

const renderOneDiv = renderHtmlTag(“div”);

const renderOneH1 = renderHtmlTag(“h1”);

console.log(
  renderOneDiv(“hello”),
  renderOneH1(“world”)
);

Conclusion

Curry existe depuis près de 40 ans et est une transformation essentielle dans le lambda-calculs.

JavaScript est utilisé plus comme un langage fonctionnel aujourd’hui, surtout avec les Promises natives et les fonctions de l’anonyme.

Pour maîtriser le langage, vous devriez avoir des connaissances dans le domaine du lambda-calculs et de la programmation fonctionnelle.

C’est un bon moyen de construire des logicielles de meilleure qualité !

function userInteraction(article) {

	const { user, david } = article.humans;

	if (user.likeArticle) {
		if (!user.isFanFacebookPage) {
			user.likeFacebookPage();
		}
		user.shareFacebook();
		user.shareTwitter();
		user.shareLinkedin();
		david.notifyThankYou();
	} else {
		david.noOffence();
		david.notifyStillLoveYou();
	}

}

userInteraction(this);
Partages ! 😉