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 hate
callback 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