Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is a => f(a) not equivalent to f?

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.

like image 238
bbarrington Avatar asked May 05 '19 22:05

bbarrington


People also ask

How do you know if something is logically equivalent?

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.

Are P → Q and P ∨ Q 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.

Why is contrapositive logically equivalent?

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.


1 Answers

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.

like image 68
Aadit M Shah Avatar answered Sep 30 '22 12:09

Aadit M Shah