Skip to content

Commit 24380cf

Browse files
lex111ca11ado
andauthored
Apply suggestions from code review
Co-Authored-By: ca11ado <projects.tlt@yandex.ru>
1 parent a276c15 commit 24380cf

3 files changed

Lines changed: 20 additions & 20 deletions

File tree

1-js/06-advanced-functions/11-currying-partials/1-ask-currying/solution.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
Теперь `user` берётся из внешних переменных, и всё выполняется правильно.
1010

11-
2. Либо сделайте из `user.login` функцию частичного применения, которая использует `user`, как контекст, и у которой установлен правильный первый аргумент:
11+
2. Либо сделайте из `user.login` функцию частичного применения, которая использует `user` как контекст, и которой передан корректный первый аргумент:
1212

1313

1414
```js

1-js/06-advanced-functions/11-currying-partials/1-ask-currying/task.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ importance: 5
88

99
Объект `user` был изменён. Теперь, вместо двух функций `loginOk/loginFail`, у него одна функция: `user.login(true/false)`.
1010

11-
Что нужно передать функции `askPassword` в коде ниже, чтобы она вызывала `user.login(true)`, как `ok`, и `user.login(false)`, как `fail`?
11+
Что нужно передать функции `askPassword` в коде ниже, чтобы она вызывала `user.login(true)` как `ok` и `user.login(false)` как `fail`?
1212

1313
```js
1414
function askPassword(ok, fail) {

1-js/06-advanced-functions/11-currying-partials/article.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
библиотеки:
1+
libs:
22
- lodash
33

44
---
55

66
# Каррирование (currying) и частичное применение (partial application)
77

8-
До сих пор мы говорили только о привязывании "this". Давайте шагнём дальше.
8+
До сих пор мы говорили только о привязывании `this`. Давайте шагнём дальше.
99

1010
Мы можем привязать не только `this`, но и аргументы. Это делается редко, но иногда может быть полезно.
1111

@@ -40,7 +40,7 @@ alert( double(4) ); // = mul(2, 4) = 8
4040
alert( double(5) ); // = mul(2, 5) = 10
4141
```
4242

43-
Вызов `mul.bind(null, 2)` создаёт новую функцию `double`, которая передаёт вызов `mul`, фиксируя `null`, как контекст и `2` -- как первый аргумент. Следующие аргументы передаются "как есть".
43+
Вызов `mul.bind(null, 2)` создаёт новую функцию `double`, которая передаёт вызов `mul`, фиксируя `null` как контекст и `2` -- как первый аргумент. Следующие аргументы передаются "как есть".
4444

4545
Это называется [частичное применение](https://ru.wikipedia.org/wiki/Частичное_применение) -- мы создаём новую функцию, фиксируя некоторые из существующих параметров.
4646

@@ -64,11 +64,11 @@ alert( triple(5) ); // = mul(3, 5) = 15
6464

6565
Для чего мы обычно создаём функцию с частичным применением?
6666

67-
Польза от этого в том, что мы можем создать независимую функцию с понятным названием (`double`, `triple`). Мы можем использовать её и не передавать каждый раз первый аргумент, т.к. он зафиксирован с помощью `bind`.
67+
Польза от этого в том, что возможно создать независимую функцию с понятным названием (`double`, `triple`). Мы можем использовать её и не передавать каждый раз первый аргумент, т.к. он зафиксирован с помощью `bind`.
6868

69-
В других случаях, частичное применение полезно, когда у нас есть очень общая функция и, для удобства, мы хотим создать её частный случай.
69+
В других случаях частичное применение полезно, когда у нас есть очень общая функция и для удобства мы хотим создать её частный случай.
7070

71-
Например, у нас есть функция `send(from, to, text)`. Потом, внутри объекта `user`, мы можем захотеть использовать её частный случай: `sendTo(to, text)`, который отправляет текст от имени текущего пользователя.
71+
Например, у нас есть функция `send(from, to, text)`. Потом внутри объекта `user` мы можем захотеть использовать её частный случай: `sendTo(to, text)`, который отправляет текст от имени текущего пользователя.
7272

7373
## Частичное применение без контекста
7474

@@ -110,7 +110,7 @@ user.sayNow("Hello");
110110
- Затем передаёт ей `...argsBound` -- аргументы из "частичного" вызова (`"10:00"`)
111111
- Затем передаёт ей `...args` -- аргументы полученные обёрткой (`"Hello"`)
112112

113-
Итак, это не сложно сделать с помощью оператора `spread`?
113+
Итак, это легко сделать с помощью оператора расширения?
114114

115115
Так же есть готовый вариант [_.partial](https://lodash.com/docs#partial) из библиотеки lodash.
116116

@@ -122,7 +122,7 @@ user.sayNow("Hello");
122122

123123
Каррирование не вызывает функцию. Оно просто трансформирует её.
124124

125-
Давайте создадим функцию-помощник `curry(f)`, которая выполняет каррирование функции `f` с двумя аргументами. Другими словами, `curry(f)` для функции с двумя аргументами `f(a, b)` трансформирует её в `f(a)(b)`.
125+
Давайте создадим вспомогательную функцию `curry(f)`, которая выполняет каррирование функции `f` с двумя аргументами. Другими словами, `curry(f)` для функции с двумя аргументами `f(a, b)` трансформирует её в `f(a)(b)`.
126126

127127
```js run
128128
*!*
@@ -145,21 +145,21 @@ let carriedSum = curry(sum);
145145
alert( carriedSum(1)(2) ); // 3
146146
```
147147

148-
Как вы видите, имплементация -- это серия обёрток.
148+
Как вы видите, реализация состоит из множества обёрток.
149149

150150
- Результат `curry(func)` -- обёртка `function(a)`.
151151
- Когда она вызывается как `sum(1)`, аргумент сохраняется в лексическом окружении и возвращается новая обёртка `function(b)`.
152152
- When it is called like `sum(1)`, the argument is saved in the Lexical Environment, and a new wrapper is returned `function(b)`.
153153
- После чего `sum(1)(2)`, наконец, вызывает `function(b)`, предоставляя `2` и передаёт вызов к оригинальной функции `sum`, принимающей несколько аргументов.
154154

155-
Более продвинутая имплементация каррирования, как [_.curry](https://lodash.com/docs#curry) из библиотеки lodash, делает нечто более сложное. Она возвращает обёртку, которая позволяет выполнить функцию, если переданы все аргументы, в противном же случае -- возвращает функцию частичного применения.
155+
Более продвинутая реализация каррирования, как [_.curry](https://lodash.com/docs#curry) из библиотеки lodash, делает нечто более сложное. Она возвращает обёртку, которая позволяет выполнить функцию, если переданы все аргументы, в противном же случае -- возвращает функцию частичного применения.
156156

157157
```js
158158
function curry(f) {
159159
return function(...args) {
160160
// if args.length == f.length (количество аргументов, принимаемое f).
161161
// тогда передаёт вызов f
162-
// в противном случае, возвращает функцию частичного применения, которая фиксирует первые аргументы
162+
// в противном случае возвращает функцию частичного применения, которая фиксирует первые аргументы
163163
};
164164
}
165165
```
@@ -168,7 +168,7 @@ function curry(f) {
168168

169169
Чтобы понять выгоду, нам определенно нужен пример из реальной жизни.
170170

171-
Продвинутое каррирование позволяет вызывать функцию, и нормально, и частично.
171+
Продвинутое каррирование позволяет вызывать функцию, как обычно, так и частично.
172172

173173
Например, у нас есть функция логирования `log(date, importance, message)`, которая подготавливает и выводит информацию. В реальных проектах у таких функций есть много других полезных возможностей, например, посылать логи по сети:
174174

@@ -216,11 +216,11 @@ todayDebug("message"); // [HH:mm] DEBUG message
216216

217217
Итак:
218218
1. Мы ничего не потеряли после каррирования: `log` всё так же можно вызывать нормально.
219-
2. Мы смоглиол создать функции с частичным применением, как сделали для логов с текущим временем.
219+
2. Мы смогли создать функции с частичным применением, как сделали для логов с текущим временем.
220220

221-
## Продвинутая имплементация каррирования
221+
## Продвинутая реализация каррирования
222222

223-
В случае, если вам интересны детали (не обязательно!), вот "продвинутая" имплементация каррирования, которую мы могли бы испольовать выше.
223+
В случае, если вам интересны детали (не обязательно!), вот "продвинутая" реализация каррирования, которую мы могли бы использовать выше.
224224

225225
Она очень короткая:
226226

@@ -274,7 +274,7 @@ function curried(...args) {
274274
Когда мы запускаем её, есть два пути:
275275

276276
1. Вызвать сейчас: если количество переданных аргументов `args` совпадает с количеством аргументов при объявлении функции (`func.length`) или больше, тогда вызов просто переходит к ней.
277-
2. Частичное применение: в противном случае, `func` не вызывается сразу. Вместо этого, возвращается другая обёртка `pass`, которая снова применит `curried`, передав предыдущие аргументы вместе с новыми. Затем, при новом вызове, мы опять получим, либо новое частичное применение (если аргументов не достаточно), либо, наконец, результат.
277+
2. Частичное применение: в противном случае `func` не вызывается сразу. Вместо этого, возвращается другая обёртка `pass`, которая снова применит `curried`, передав предыдущие аргументы вместе с новыми. Затем при новом вызове, мы опять получим, либо новое частичное применение (если аргументов не достаточно), либо, наконец, результат.
278278

279279
Например, давайте посмотрим, что произойдёт в случае `sum(a, b, c)`. У неё три аргумента, так что `sum.length = 3`.
280280

@@ -295,7 +295,7 @@ function curried(...args) {
295295
```smart header="Немного больше, чем каррирование"
296296
По определению, каррирование должно превращать `sum(a, b, c)` в `sum(a)(b)(c)`.
297297
298-
Но, как было описано, большинство имплементаций каррирования в JavaScript более продвинуты: они так же оставляют вариант вызова функции с несколькими аргументами.
298+
Но, как было описано, большинство реализаций каррирования в JavaScript более продвинуты: они также оставляют вариант вызова функции с несколькими аргументами.
299299
```
300300

301301
## Итого
@@ -304,7 +304,7 @@ function curried(...args) {
304304

305305
Частичное применение удобно, когда мы не хотим повторять один и тот же аргумент много раз. Например, когда у нас есть функция `send(from, to)`, и `from` всё время будет одинаков для нашей задачи, мы можем выполнить частичное применение и дальше работать с ним.
306306

307-
- *Каррирование* -- это трансформация, которая превращает вызов `f(a, b, c)` в `f(a)(b)(c)`. В JavaScript имплементации обычно позволяют вызывать функцию обоими вариантами: либо
307+
- *Каррирование* -- это трансформация, которая превращает вызов `f(a, b, c)` в `f(a)(b)(c)`. В JavaScript реализация обычно позволяют вызывать функцию обоими вариантами: либо
308308
нормально, либо возвращают частичное применение, если количество аргументов недостаточно.
309309

310310
Каррирование подходит тогда, когда мы хотим легко использовать частичное применение. Как мы видели в примерах с логами: универсальная функция `log(date, importance, message)` после каррирования возвращает нам частичное применение, когда вызывается с одним аргументом, как `log(date)` или двумя аргументами, как `log(date, importance)`.

0 commit comments

Comments
 (0)