Eta-conversion is considering the function (x) => f(x) to be the same as the function f. While refactoring code at work, I sought to simplify some higher order function call using this equivalence. However, things didn't quite work out, and I'm somewhat lost at what is actually happening, being quite new at Javascript. Here's a minimal example that I hope correctly exemplifies my question.
const station = {
take: (f) => f(5),
love: function(car) {
this.take((x) => car.addFuel(x));
},
hate: function(car) {
this.take(car.addFuel);
}
};
const mercedes = {
fuel: 0,
addFuel: function(amount) {
this.fuel += amount;
}
};
station.love(mercedes);
console.log(mercedes.fuel);
// output: 5
station.hate(mercedes);
console.log(mercedes.fuel);
// output: 5; expected output: 10
From eta equivalence, I expected love and hate functions from the station object to behave the same. However, it seems like the hate function actually does nothing. What is happening here?
There is a scoping issue of this. In your original code in the hatecallback this refers to the global window object. You need to use Function.prototype.bind() to bind the correct scope for this.
const station = {
take: (f) => f(5),
love: function(car) {
this.take((x) => car.addFuel(x));
},
hate: function(car) {
this.take(car.addFuel.bind(car));
}
};
const mercedes = {
fuel: 0,
addFuel: function(amount) {
this.fuel += amount;
}
};
station.love(mercedes);
console.log(mercedes.fuel);
station.hate(mercedes);
console.log(mercedes.fuel);
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