New to lodash and playing around with it to gain more understanding. I don't understand the behavior of the following code.
After learning about the arity argument to _.curry
, I have a code snippet that produces results that seems strange to me.
const words = ['jim', 'john'];
const pad10 = words =>
_.map(words, word => _.pad(word, 10));
console.log(pad10(words)); // [ ' jim ', ' john ' ]
const flipMap = _.flip(_.map);
const flipPad = _.flip(_.pad);
const curriedFlipMap = _.curry(flipMap, 2);
const pad10v2 = curriedFlipMap(word => flipPad(' ', 10, word));
console.log(pad10v2(words)); // [ ' jim ', ' john ' ]
const curriedFlipPad = _.curry(flipPad, 3);
const padWord10 = curriedFlipPad(' ', 10);
const pad10v3 = curriedFlipMap(word => padWord10(word));
console.log(pad10v3(words)); // [ ' jim ', ' john ' ]
const pad10v4 = curriedFlipMap(padWord10);
console.log(pad10v4(words)); // [ 'jim,john', 'jim,john' ]
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
I don't understand the output of the last console.log. Looks to me like I'm just replacing a => f(a) with f when a one arg function is expected.
Two statement forms are logically equivalent if, and only if, their resulting truth tables are identical for each variation of statement variables. p q and q p have the same truth values, so they are logically equivalent.
P→Q is logically equivalent to ⌝P∨Q. So. ⌝(P→Q) is logically equivalent to ⌝(⌝P∨Q). Hence, by one of De Morgan's Laws (Theorem 2.5), ⌝(P→Q) is logically equivalent to ⌝(⌝P)∧⌝Q.
More specifically, the contrapositive of the statement "if A, then B" is "if not B, then not A." A statement and its contrapositive are logically equivalent, in the sense that if the statement is true, then its contrapositive is true and vice versa.
Yes, there is a difference between f
and a => f(a)
in JavaScript. Consider the following example:
const array = (...args) => args;
const arrayEta = a => array(a);
console.log(array(1, 2, 3)); // [1, 2, 3]
console.log(arrayEta(1, 2, 3)); // [1]
Do you see the problem? When I call arrayEta(1, 2, 3)
it expands to (a => array(a))(1, 2, 3)
which beta reduces to array(1)
because the 2
and 3
are never used. However, the non-eta expanded version is array(1, 2, 3)
. This is the problem with your code:
const words = ["jim", "john"];
const flipMap = _.flip(_.map);
const flipPad = _.flip(_.pad);
const curriedFlipMap = _.curry(flipMap, 2);
const curriedFlipPad = _.curry(flipPad, 3);
const padWord10 = curriedFlipPad(" ", 10);
const pad10v4 = curriedFlipMap((...args) => {
console.log(args); // args is an array of 3 arguments
return padWord10(...args);
});
console.log(pad10v4(words)); // ["jim,john", "jim,john"]
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Notice that args is an array of three arguments, word, index, and array. Hence, curriedFlipMap(padWord10)
is actually eta equivalent to curriedFlipMap((word, index, array) => padWord10(word, index, array))
. It is not eta equivalent to curriedFlipMap(word => padWord10(word))
.
Hence, your function call is reduced as follows:
padWord10("jim", 0, ["jim", "john"])
= curriedFlipPad(" ", 10)("jim", 0, ["jim", "john"])
= _curry(flipPad, 3)(" ", 10)("jim", 0, ["jim", "john"])
= _.pad(["jim", "john"], 0, "jim", 10, " ")
= _.pad(["jim", "john"], 0, "jim")
As you can see, you're providing the function _.pad
5 arguments out of which it ignores the last 2. Hence, it converts ["jim", "john"]
to a string and then adds padding to it.
Anyway, the solution is to not do eta-conversion in this case. By the way, if you want to use Lodash for functional programming then use lodash/fp
instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With