4 Oct 2016

Mettez du piquant dans vos JS

Aujourd’hui, nous allons aborder le currying !

C’est souvent pratique, et la dernière fois que je l’ai utilisé, j’ai pensé à vous ! D’où cet article…

Allez, voyons ensemble comment ça se passe ?

I. Qu’est-ce ?

Commençons par la théorie, et pour une fois, vous verrez c’est super simple. Le currying c’est simplement le concept qui décrit le passage d’une fonction à x paramètres à x fonctions à un paramètre. Mais cela peut-être aussi la transformation d’une fonction à plusieurs arguments en une fonction à un argument qui retourne une fonction sur le reste des arguments.

Avec un exemple, vous verrez que c’est simple comme “bonjour” 😉

f(a,b,c) { //body } qui s’appelle f(1,2,3) peut devenir :

  1. f(a) {       return function(b,c){   //body } }
    •  qui s’appelle f(1)(2,3)
  2. f(a,b) {   return function(c){       //body } }
    •  qui s’appelle f(1,2)(3)
  3. f(a) {       return function(b){      return function(c){ //body } } }
    •  qui s’appelle f(1)(2)(3)

Voilà, le currying c’est le fait de découper une méthode qui prend plusieurs arguments en une série de fonctions qui prennent le reste des arguments.

Dis autrement, on va réécrire une fonction afin qu’elle prenne une partie des arguments et cette dernière renverra une série de plusieurs autres fonctions qui prendront le reste des paramètres.

II. Un exemple ?

Un exemple très simple avec une fonction ayant deux paramètres qui sera transformée en deux fonctions ayant chacune un paramètre :

C’est parti, mettons des épices :

Nous voyons bien ici les deux “nouvelles” fonctions :

Et les invocations correspondantes :

Nous aurions pu écrire le code correspondant aux étapes 3 et 4 de manière plus détaillée :

III. A quoi et quand ça sert ?

Comme vous le devinez, le currying peut s’appliquer dès que :

  • l’invocation de notre méthode demande des arguments qui ne sont pas tous “prêts” au moment de l’appel,
  • le besoin de “stocker” / “capturer” une variable dans une méthode est nécessaire,
  • nous voulons rendre plus générique certaines méthodes. En effet, cela permet de Ré-utiliser encore plus nos fonctions.

Le currying peut aussi “pousser” ou “conduire naturellement” à écrire des fonctions pures.

IV. Faire du Currying facilement ?

Et bien oui, John David Dalton pense à nous dans lodash avec https://lodash.com/docs/4.16.1#curry :

Creates a function that accepts arguments of func and either invokes func returning its result, if at least arity number of arguments have been provided, or returns a function that accepts the remaining func arguments, and so on. The arity of func may be specified if func.length is not sufficient.

The _.curry.placeholder value, which defaults to _ in monolithic builds, may be used as a placeholder for provided arguments.

Concrètement :

Concrètement sur notre exemple, cela donne :

Easy one ! Merci lodash !

Attention, il n’y a pas que lodash qui permet de faire du curry facilement, il existe aussi : Rambda. Avec cette libraire ça donnerait plutôt :

IV. Un exemple plus épicé ?

Dans le cas suivant, nous souhaitons pouvoir retrouver les utilisateurs selon plusieurs critères :  prénom, id, âge. Bref, nous n’avons besoin que d’une unique fonction paramétrable qui fera la recherche. L’avantage de la currification ici est de pouvoir définir à l’avance les méthodes dans son code et de les utiliser à la volée. En pratique, cela donne :

Et voilà, maintenant, vous savez que les épices c’est bon pour vous ! Ah oui, attention, il existe l’opération inverse : la décurryfication

A bientôt !

Share