You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/99-js-misc/03-currying-partials/article.md
+6-14Lines changed: 6 additions & 14 deletions
Original file line number
Diff line number
Diff line change
@@ -121,11 +121,7 @@ function curry(func) {
121
121
returnfunctioncurried(...args) {
122
122
if (args.length>=func.length) {
123
123
returnfunc.apply(this, args);
124
-
} else {
125
-
returnfunction(...args2) {
126
-
returncurried.apply(this, args.concat(args2));
127
-
}
128
-
}
124
+
} elsereturncurried.bind(this, ...args);
129
125
};
130
126
131
127
}
@@ -154,26 +150,22 @@ The result of `curry(func)` call is the wrapper `curried` that looks like this:
154
150
functioncurried(...args) {
155
151
if (args.length>=func.length) { // (1)
156
152
returnfunc.apply(this, args);
157
-
} else {
158
-
returnfunctionpass(...args2) { // (2)
159
-
returncurried.apply(this, args.concat(args2));
160
-
}
161
-
}
153
+
} elsereturncurried.bind(this, ...args); // (2)
162
154
};
163
155
```
164
156
165
157
When we run it, there are two `if` execution branches:
166
158
167
159
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.
160
+
2. Get a partial: otherwise, `func` is not called yet. Instead, a new bounded function using curried is returned, that takes the `...args` i.e. the current arguments as pre-specified. Then on a new call, again, we'll get either a new partial (if not enough arguments) or, finally, the result.
169
161
170
162
For instance, let's see what happens in the case of `sum(a, b, c)`. Three arguments, so `sum.length = 3`.
171
163
172
164
For the call `curried(1)(2)(3)`:
173
165
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.
166
+
1. The first call `curried(1)`returns a new bounded `curried` with `1` as pre-specified argument.
167
+
2. The bounded `curried` is called with `(2)`: it takes previous args (`1`) due to bind, and new leading argument `(2)` and calls `curried(2)`. As the argument count is still less than 3, `curry` returns new bounded `curried` with (`1`, `2`) as pre-specified arguments.
168
+
3. The bounded `curried` is called again with `(3)`, for the next call `curried(3)` takes previous args (`1`, `2`) and new leading argument `3`, making the call `curried(3)` -- there are `3` arguments at last, they are given to the original function.
177
169
178
170
If that's still not obvious, just trace the calls sequence in your mind or on paper.
0 commit comments