Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Eta-conversion in Javascript

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?

like image 731
Marc-André Brochu Avatar asked Sep 13 '25 10:09

Marc-André Brochu


1 Answers

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);
like image 178
Greedo Avatar answered Sep 16 '25 01:09

Greedo