Skip to content

Commit a3c1dad

Browse files
authored
Merge pull request #178 from Aakodal/patch-2
Currying
2 parents 02143e0 + 118daf8 commit a3c1dad

File tree

1 file changed

+57
-57
lines changed

1 file changed

+57
-57
lines changed

1-js/99-js-misc/03-currying-partials/article.md

Lines changed: 57 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@ libs:
33

44
---
55

6-
# Currying
6+
# Curryfication
77

8-
[Currying](https://en.wikipedia.org/wiki/Currying) is an advanced technique of working with functions. It's used not only in JavaScript, but in other languages as well.
8+
La [curryfication](https://fr.wikipedia.org/wiki/Curryfication) est une technique avancée de travail avec les fonctions. Ce n'est pas seulement utilisé avec JavaScript, mais dans d'autres langages également.
99

10-
Currying is a transformation of functions that translates a function from callable as `f(a, b, c)` into callable as `f(a)(b)(c)`.
10+
La curryfication est la transformation de fonctions qui traduit une fonction de la forme `f(a, b, c)` en une fonction de la forme `f(a)(b)(c)`.
1111

12-
Currying doesn't call a function. It just transforms it.
12+
La curryfication n'est pas une fonction. Elle la transforme simplement.
1313

14-
Let's see an example first, to better understand what we're talking about, and then practical applications.
14+
Voyons d'abord un exemple, pour mieux comprendre de quoi nous parlons, et ensuite mettons en pratique.
1515

16-
We'll create a helper function `curry(f)` that performs currying for a two-argument `f`. In other words, `curry(f)` for two-argument `f(a, b)` translates it into a function that runs as `f(a)(b)`:
16+
Nous allons créer une fonction d'aide `curry(f)` qui curryfie une fonction `f` à deux arguments. En d'autres mots, `curry(f)` sur une fonction `f(a, b)` la traduit en une fonction qui s'appelle par `f(a)(b)` :
1717

1818
```js run
1919
*!*
20-
function curry(f) { // curry(f) does the currying transform
20+
function curry(f) { // curry(f) fait la curryfication
2121
return function(a) {
2222
return function(b) {
2323
return f(a, b);
@@ -36,84 +36,84 @@ let curriedSum = curry(sum);
3636
alert( curriedSum(1)(2) ); // 3
3737
```
3838

39-
As you can see, the implementation is straightforward: it's just two wrappers.
39+
Comme vous pouvez le voir, l'implémentation est simple : il ne s'agit que de deux enveloppes.
4040

41-
- The result of `curry(func)` is a wrapper `function(a)`.
42-
- When it is called like `sum(1)`, the argument is saved in the Lexical Environment, and a new wrapper is returned `function(b)`.
43-
- Then this wrapper is called with `2` as an argument, and it passes the call to the original `sum`.
41+
- Le résultat de `curry(func)` est une enveloppe `function(a)`.
42+
- Lorsqu'il est appelé comme `curriedSum(1)`, l'argument est sauvegardé dans l'environnement lexical, et une nouvelle enveloppe `function(b)` est retournée.
43+
- Ensuite cette enveloppe est appelée avec `2` comme argument, et passe l'appel à la fonction originelle `sum`.
4444

45-
More advanced implementations of currying, such as [_.curry](https://lodash.com/docs#curry) from lodash library, return a wrapper that allows a function to be called both normally and partially:
45+
Des implémentations plus avancées de la curryfication, comme [_.curry](https://lodash.com/docs#curry) de la bibliothèque lodash, retournent une enveloppe qui permet à une fonction d'être à la fois appelée normalement et partiellement :
4646

4747
```js run
4848
function sum(a, b) {
4949
return a + b;
5050
}
5151

52-
let curriedSum = _.curry(sum); // using _.curry from lodash library
52+
let curriedSum = _.curry(sum); // usage de _.curry de la bibliothèque lodash
5353

54-
alert( curriedSum(1, 2) ); // 3, still callable normally
55-
alert( curriedSum(1)(2) ); // 3, called partially
54+
alert( curriedSum(1, 2) ); // 3, toujours appelable normalement
55+
alert( curriedSum(1)(2) ); // 3, appelée partiellement
5656
```
5757

58-
## Currying? What for?
58+
## La curryfication ? Pour quoi faire ?
5959

60-
To understand the benefits we need a worthy real-life example.
60+
Pour comprendre les bénéfices, nous avons besoin d'un exemple réel.
6161

62-
For instance, we have the logging function `log(date, importance, message)` that formats and outputs the information. In real projects such functions have many useful features like sending logs over the network, here we'll just use `alert`:
62+
Par exemple, nous avons la fonction de journalisation `log(date, importance, message)` qui formate et écrit l'information. Dans de réels projets de telles fonctions ont beaucoup de fonctionnalités utiles comme envoyer les journaux sur un réseau, ici nous allons juste utiliser `alert` :
6363

6464
```js
6565
function log(date, importance, message) {
6666
alert(`[${date.getHours()}:${date.getMinutes()}] [${importance}] ${message}`);
6767
}
6868
```
6969

70-
Let's curry it!
70+
Curryfions-la !
7171

7272
```js
7373
log = _.curry(log);
7474
```
7575

76-
After that `log` works normally:
76+
Après ça `log` fonctionne normalement:
7777

7878
```js
7979
log(new Date(), "DEBUG", "some debug"); // log(a, b, c)
8080
```
8181

82-
...But also works in the curried form:
82+
...Mais aussi dans la forme curryfiée :
8383

8484
```js
8585
log(new Date())("DEBUG")("some debug"); // log(a)(b)(c)
8686
```
8787

88-
Now we can easily make a convenience function for current logs:
88+
Nous pouvons maintenant faire une fonction pratique pour la journalisation actuelle :
8989

9090
```js
91-
// logNow will be the partial of log with fixed first argument
91+
// logNow sera la partie partielle de log avec un premier argument fixe
9292
let logNow = log(new Date());
9393

94-
// use it
94+
// utilisons-la
9595
logNow("INFO", "message"); // [HH:mm] INFO message
9696
```
9797

98-
Now `logNow` is `log` with fixed first argument, in other words "partially applied function" or "partial" for short.
98+
Maintenant `logNow` est `log` avec un premier argument fixe, en d'autres termes "fonction partiellement appliquée" ou "partielle" pour faire court.
9999

100-
We can go further and make a convenience function for current debug logs:
100+
Nous pouvons aller plus loin et faire une fonction pratique pour le débogage actuel :
101101

102102
```js
103103
let debugNow = logNow("DEBUG");
104104

105105
debugNow("message"); // [HH:mm] DEBUG message
106106
```
107107

108-
So:
109-
1. We didn't lose anything after currying: `log` is still callable normally.
110-
2. We can easily generate partial functions such as for today's logs.
108+
Donc :
109+
1. Nous n'avons rien perdu après avoir curryfié : `log` est toujours appelable normalement.
110+
2. Nous pouvons aisément créer des fonctions partielles comme pour la journalisation d'aujourd'hui.
111111

112-
## Advanced curry implementation
112+
## Implémentation avancée de la curryfication
113113

114-
In case you'd like to get in to the details, here's the "advanced" curry implementation for multi-argument functions that we could use above.
114+
Au vas où vous souhaitiez entrer dans les détails, voici l'implémentation "avancée" de la curryfication pour les fonctions à plusieurs arguments que nous avons pu utiliser plus haut.
115115

116-
It's pretty short:
116+
C'est plutôt court :
117117

118118
```js
119119
function curry(func) {
@@ -131,7 +131,7 @@ function curry(func) {
131131
}
132132
```
133133

134-
Usage examples:
134+
Exemples d'usage :
135135

136136
```js
137137
function sum(a, b, c) {
@@ -140,17 +140,17 @@ function sum(a, b, c) {
140140

141141
let curriedSum = curry(sum);
142142

143-
alert( curriedSum(1, 2, 3) ); // 6, still callable normally
144-
alert( curriedSum(1)(2,3) ); // 6, currying of 1st arg
145-
alert( curriedSum(1)(2)(3) ); // 6, full currying
143+
alert( curriedSum(1, 2, 3) ); // 6, toujours appelable normalement
144+
alert( curriedSum(1)(2,3) ); // 6, curryfiée au premier argument
145+
alert( curriedSum(1)(2)(3) ); // 6, curryfiée totalement
146146
```
147147

148-
The new `curry` may look complicated, but it's actually easy to understand.
148+
La nouvelle `curry` semble être compliquée, mais est assez simple à comprendre.
149149

150-
The result of `curry(func)` call is the wrapper `curried` that looks like this:
150+
Le résultat de `curry(func)` est l'enveloppe `curried` qui ressemble à ça :
151151

152152
```js
153-
// func is the function to transform
153+
// func est la fonction à transformer
154154
function curried(...args) {
155155
if (args.length >= func.length) { // (1)
156156
return func.apply(this, args);
@@ -162,35 +162,35 @@ function curried(...args) {
162162
};
163163
```
164164

165-
When we run it, there are two `if` execution branches:
165+
Quand on la lance, il y a deux branches `if` :
166166

167-
1. Call now: if passed `args` count is the same as the original function has in its definition (`func.length`) or longer, then just pass the call to it.
168-
2. Get a partial: otherwise, `func` is not called yet. Instead, another wrapper `pass` is returned, that will re-apply `curried` providing previous arguments together with the new ones. Then on a new call, again, we'll get either a new partial (if not enough arguments) or, finally, the result.
167+
1. Appeler maintenant : si la longueur du `args` donné est supérieure ou égale à la fonction originelle a dans sa déclaration (`func.length`), alors simplement appeler la fonction avec.
168+
2. Obtenir une partielle : sinon, `func` n'est pas encore appelée. À la place, une autre enveloppe `pass` est retournée, qui réappliquera `curried` sur les anciens arguments avec les nouveaux. Enfin sur un nouvel appel, encore, nous obtiendrons une nouvelle partielle (s'il n'y a pas assez d'arguments) ou, enfin, le résultat.
169169

170-
For instance, let's see what happens in the case of `sum(a, b, c)`. Three arguments, so `sum.length = 3`.
170+
Par exemple, voyons ce qu'il se passe dans le cas de `sum(a, b, c)`. Trois arguments, donc `sum.length = 3`.
171171

172-
For the call `curried(1)(2)(3)`:
172+
Pour l'appel `curried(1)(2)(3)` :
173173

174-
1. The first call `curried(1)` remembers `1` in its Lexical Environment, and returns a wrapper `pass`.
175-
2. The wrapper `pass` is called with `(2)`: it takes previous args (`1`), concatenates them with what it got `(2)` and calls `curried(1, 2)` with them together. As the argument count is still less than 3, `curry` returns `pass`.
176-
3. The wrapper `pass` is called again with `(3)`, for the next call `pass(3)` takes previous args (`1`, `2`) and adds `3` to them, making the call `curried(1, 2, 3)` -- there are `3` arguments at last, they are given to the original function.
174+
1. Le premier appel `curried(1)` retient `1` dans son environnement lexical, et retourne une enveloppe `pass`.
175+
2. L'enveloppe `pass` est appelée avec `(2)` : elle prend les arguments précédents (`1`), les concatène avec ce qu'elle a (`2`) et appelle `curried(1, 2)` avec lesdits arguments. Comme le nombre d'arguments est toujours inférieur à 3, `curry` retourne `pass`.
176+
3. L'enveloppe `pass` est de nouveau appelée avec `(3)`, cet appel `pass(3)` prend les anciens arguments (`1`, `2`) et y ajoute `3`, créant l'appel `curried(1, 2, 3)` -- il y a au moins `3` arguments, ils sont donnés à la fonction originelle.
177177

178-
If that's still not obvious, just trace the calls sequence in your mind or on paper.
178+
Si ce n'est toujours pas évident, tracez les appels dans votre esprit ou sur un papier.
179179

180-
```smart header="Fixed-length functions only"
181-
The currying requires the function to have a fixed number of arguments.
180+
```smart header="Fonctions à nombre d'arguments fixe seulement"
181+
La curryfaction requiert que la fonction ait un nombre d'arguments fixe.
182182
183-
A function that uses rest parameters, such as `f(...args)`, can't be curried this way.
183+
Une fonction qui utilise un paramètre de reste, comme `f(...args)`, ne peut pas être curryfiée de cette façon.
184184
```
185185

186-
```smart header="A little more than currying"
187-
By definition, currying should convert `sum(a, b, c)` into `sum(a)(b)(c)`.
186+
```smart header="Un peu plus que la curryfication"
187+
Par définition, la curryfication devrait convertir `sum(a, b, c)` en `sum(a)(b)(c)`.
188188
189-
But most implementations of currying in JavaScript are advanced, as described: they also keep the function callable in the multi-argument variant.
189+
Mais la plupart des implémentations en JavaScript sont avancées, comme décrites : elles laissent la possibilité d'appeler la fonction via plusieurs arguments.
190190
```
191191

192-
## Summary
192+
## Résumé
193193

194-
*Currying* is a transform that makes `f(a,b,c)` callable as `f(a)(b)(c)`. JavaScript implementations usually both keep the function callable normally and return the partial if the arguments count is not enough.
194+
La *curryfication* est une transformation qui rend `f(a,b,c)` appelable comme `f(a)(b)(c)`. Les implémentations en JavaScript laissent généralement la possibilité d'appeler les fonctions normalement et de retourner une partielle si le nombre d'arguments n'est pas suffisant.
195195

196-
Currying allows us to easily get partials. As we've seen in the logging example, after currying the three argument universal function `log(date, importance, message)` gives us partials when called with one argument (like `log(date)`) or two arguments (like `log(date, importance)`).
196+
La curryfication nous permet d'avoir aisément des partielles. Comme nous avons pu le voir dans l'exemple de journalisation, après avoir curryfié la fonction à trois arguments, `log(date, importance, message)` nous donne une partielle quand appelée avec un argument (comme `log(date)`) ou deux arguments (comme `log(date, importance)`).

0 commit comments

Comments
 (0)