Binding arrow functions.

# Mark Everitt (11 years ago)

Today I encountered an inconsistency between SpiderMonkey and V8 (in Aurora 33.0a2 (2014-08-24) and Canary 39.0.2135.0 canary (64-bit)). In chrome, I can bind an arrow function, and in firefox I cannot (see this gist: gist.github.com/qubyte/43e0093274e793cc82ba)

I find reading the ES6 draft spec hard going, but from searching around I get the impression that it states that bind should not be successful on an arrow function. If this is the case, then it raises an issue. There seems to be no clean way to tell apart regular functions and arrow functions (the only way I can do this is by looking at the result of toString). That being the case, arrow functions mean that we can no longer trust call, apply and bind, since we cannot easily tell if the function we want to bind is an arrow function and will silently ignore us.

Having said all that, if I have the wrong end of the stick and this is a bug in SpiderMonkey, please let me know!

# Domenic Denicola (11 years ago)

From: es-discuss [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Mark Everitt

There seems to be no clean way to tell apart regular functions and arrow functions (the only way I can do this is by looking at the result of toString). That being the case, arrow functions mean that we can no longer trust call, apply and bind, since we cannot easily tell if the function we want to bind is an arrow function and will silently ignore us.

There have been multitudes of threads on this before, but the short recap is that arrow functions are functions, not methods. That is, they do not change their behavior depending on what thisArg they are called with. Other examples of non-method functions include:

function f(x) {
  return x * 2;
}

var g = (function () { return this.foo; }).bind({ foo: 5 });

function F(x) {
  var hidden = x * 2;
  this.f = function () {
    return hidden;
  };
}

var h = (new F(12)).f;
# Mark Everitt (11 years ago)

That seems a little unsatisfactory. I'm aware of the difference in terminology of course. The problem remains that arrow functions make bind etc. unpredictable. You're relying on the programmer to do the right thing and that's a bad idea IMO.

Can you point me to one of the threads you mention? A quick search turned up nothing on thus earlier, and I should read one of those to get up to speed.

# Boris Zbarsky (11 years ago)

On 8/24/14, 10:26 PM, Mark Everitt wrote:

The problem remains that arrow functions make bind etc. unpredictable.

I think part of Domenic's point is that return values of bind() also make bind (and call/apply for that matter) unpredictable.

# Mark Everitt (11 years ago)

Ah, yes I'm seeing the point now. My apologies. The difference between SpiderMonkey and V8 that precipitated this thread has me frustrated. Thanks both.

# Rick Waldron (11 years ago)

SpiderMonkey is correct. Arrow functions aren't meant to be a drop in replacement for all functions. I replied to that bug confirming that Canary is incorrect with relevant spec notes.

# Till Schneidereit (11 years ago)

On Mon, Aug 25, 2014 at 4:30 AM, Boris Zbarsky <bzbarsky at mit.edu> wrote:

On 8/24/14, 10:26 PM, Mark Everitt wrote:

The problem remains that arrow functions make bind etc. unpredictable.

I think part of Domenic's point is that return values of bind() also make bind (and call/apply for that matter) unpredictable.

More fundamentally, I guess you could say that every function that doesn't use this makes bind unpredictable. Domenic's second example shows a function like that.

I would argue that, if anything, arrow functions slightly improve predictability: before arrow functions, the only way to meaningfully "predict" the change in behavior that bind causes for a functions was by looking at its source code and by ensuring that the function hasn't been bound already. For arrow functions, you only need to inspect the source code. (Granted, this probably isn't that much of a real-world improvement.)

# Mark Everitt (11 years ago)

I got my lack-of-sleep addled head around this by realising that an arrow function performs like an immediately bound function expression:

var test = (function (){
    // Do stuff with this...
}).bind(this);

i.e. Domenic's second example function. Then it was obvious that arrow functions are not really throwing anything new into the mix with regard to bind, apply, and call.

# Erik Arvidsson (11 years ago)

V8 is implementing arrow functions at the moment so they are incomplete/incorrect. We have not enabled them yet and using the experimental flags will lead to incomplete and incorrect behavior.