what kind of problem is this fat arrow feature trying to solve ?

# Andrea Giammarchi (12 years ago)

Apologies for the off topic, I swear I thought I opened a new thread for that so here again my post. Thanks


I need to read everything Brendan suggested but if anyone would be so kind to refresh my memories on this arrow function I'd appreciate that. I don't need much more than yes/no as answer, thanks.

  1. var o = {method: () => this}; will o.method() return o ? (I guess

nope)

Considering the following code:

var Proto = (function(){
  this.method = () => this;
  return this.constructor;
}.bind(function Proto() {}.prototype));
  1. will it work as expected per each new Proto object ? (I guess nope, everything referred to Proto.prototype)

Considering the following code:

var o = {i: 0};

(function(O){

  O.fatMethod = (i) => i + this.i;
  O.justMethod = function (i) {
    return i + O.i;
  };

}.bind(o,O));
  1. will the fatMethod be ideally/theoretically/technically faster to execute once made hot through JIT capable engines (or made preventively hot since immutable in such form) ?

My bonus, humble, honest, and final question would be:

  1. what kind of problem is this fat arrow feature trying to solve exactly, if it cannot be used for classes, direct methods assignment, but only for some runtime event assignment instead of using bind and still being unable to remove that listener later on ?

Thanks a lot in advance for any refreshing and/or enlightening answer, it's actually a while I am wondering this stuff.

Best

# Tab Atkins Jr. (12 years ago)

On Tue, Oct 1, 2013 at 3:43 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

  1. what kind of problem is this fat arrow feature trying to solve exactly, if it cannot be used for classes, direct methods assignment, but only for some runtime event assignment instead of using bind and still being unable to remove that listener later on ?

I'm not sure what sort of JS you write, but anonymous functions that don't need standard 'this' binding are used in lots of places, far beyond just "runtime event assignment". Have you never used setTimeout, forEach, map/reduce/etc, and all the callback/Promise-based features of DOM/etc?

# Andrea Giammarchi (12 years ago)

setTimeout accept extra arguments ... I write JavaScript that uses this feature.

setTimeout(callback, delay, arg1, arg2, argN, evenAnObject);

so fat arrow does not solve much here, I can use self as first argument and I am good.

forEach and all other arrays accept a second argument

array.forEach(doStuff, boundContextObject);

so fat arrow does not solve a thing in mostly all Array extras.

for DOM I use handlers as specified by W3C so that {handleEvent: function () {this}} works better than any mess I could create with callbacks that I won't be unable to remove later on (as I've said) ... so I can use removeEventListener(this) in every method handled by that object.

So I actually wonder what kind of JavaScript you write because this was a honest question but probably ... people not familiar with JS are the answer: since developers ignore part of JS specs available since every then we need a fat arrow to break old syntax to make the creation of self bound function easier.

This would be already an answer so thanks for participating.

br

# Andrea Giammarchi (12 years ago)

Since every => Since ever

Sent from my Windows Phone

From: Andrea Giammarchi <andrea.giammarchi at gmail.com>

Sent: 10/1/2013 7:35 PM To: Tab Atkins Jr. <jackalmage at gmail.com>

Cc: es-discuss at mozilla.org Subject: Re: what kind of problem is this fat arrow feature trying to solve ?

setTimeout accept extra arguments ... I write JavaScript that uses this feature.

setTimeout(callback, delay, arg1, arg2, argN, evenAnObject);

so fat arrow does not solve much here, I can use self as first argument and I am good.

forEach and all other arrays accept a second argument

array.forEach(doStuff, boundContextObject);

so fat arrow does not solve a thing in mostly all Array extras.

for DOM I use handlers as specified by W3C so that {handleEvent: function () {this}} works better than any mess I could create with callbacks that I won't be unable to remove later on (as I've said) ... so I can use removeEventListener(this) in every method handled by that object.

So I actually wonder what kind of JavaScript you write because this was a honest question but probably ... people not familiar with JS are the answer: since developers ignore part of JS specs available since every then we need a fat arrow to break old syntax to make the creation of self bound function easier.

This would be already an answer so thanks for participating.

br

# David Bruant (12 years ago)

Le 02/10/2013 04:35, Andrea Giammarchi a écrit :

setTimeout accept extra arguments ... I write JavaScript that uses this feature.

setTimeout(callback, delay, arg1, arg2, argN, evenAnObject);

What is "evenAnObject"? It doesn't look like a standard thing: www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#windowtimers

so fat arrow does not solve much here, I can use self as first argument and I am good.

forEach and all other arrays accept a second argument

array.forEach(doStuff, boundContextObject);

so fat arrow does not solve a thing in mostly all Array extras.

Both examples are most certainly design mistakes. It feels absurd that every function accepting a function as argument must also have a second argument for the |this| value (or even variable number of arguments to be passed around). Especially in the ES5 era with Function.prototype.bind. The design mistake is emphasized by the inconsistency in the order of arguments in the 2 examples you provide. I'm glad Node.js didn't make all async functions accept another argument for |this|.

for DOM I use handlers as specified by W3C

Since when the DOM is specified by W3C? Must be about 10 years it isn't the case anymore</troll> ;-)

Passing a function directly is standard too.

so that {handleEvent: function () {this}} works better than any mess I could create with callbacks that I won't be unable to remove later on (as I've said) ... so I can use removeEventListener(this) in every method handled by that object.

Interesting trick. But "won't be able to remove later on" is false:

 document.addEventListener('DOMContentLoaded', function dcl(){
     // whatev's
     document.removeEventListener('DOMContentLoaded', dcl);
 });

So I actually wonder what kind of JavaScript you write because this was a honest question but probably ... people not familiar with JS are the answer: since developers ignore part of JS specs available since every then we need a fat arrow to break old syntax to make the creation of self bound function easier.

One of the reason of arrow functions to exist is to get rid of the need for "var self = this" or equivalent ('that', '_this', etc.). Example on MDN: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/arrow_functions#Lexical_this

I understand that in some cases, specs allow to pass |this| or additional arguments, but it doesn't make it a good idea. I see the fact that Node.js didn't take that road as a very strong signal.

# Claude Pache (12 years ago)

Le 2 oct. 2013 à 09:34, David Bruant <bruant.d at gmail.com> a écrit :

So I actually wonder what kind of JavaScript you write because this was a honest question but probably ... people not familiar with JS are the answer: since developers ignore part of JS specs available since every then we need a fat arrow to break old syntax to make the creation of self bound function easier. One of the reason of arrow functions to exist is to get rid of the need for "var self = this" or equivalent ('that', '_this', etc.). Example on MDN: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/arrow_functions#Lexical_this

+1. The big win of arrow-functions, is that it prevents from using various ad-hoc kludges (var that = this, [].some(..., this), etc), whose sole goal is to defeat some unwanted feature (proper this binding in callbacks). Not a killing-feature, but a nice addition that will help to reduce noise in code.

# Benjamin (Inglor) Gruenbaum (12 years ago)

There are two things here:

  • In JS I (as well as most code in libraries I read) tend to use function expressions a lot. The arrow notation is easier to read in my opinion. It's shorter and more concise. That's a weak argument for it, but I think just making the language more concise is an argument on its own.

  • While we're making function expressions shorter, let's fix this function expresisons. Pretty much every host environment be it node, the web browser or embedding uses deferred execution and event loop driven concurrency at some level.

While there is nothing in JavaScript itself that dictates this sort of concurrency in practice events are used extensively when coding JavaScript. Using an object and adding handlers that need a reference to that object is very common in the browser and in node.

It's very common in practice and having lexical this in arrow functions seems very useful. An indicator might be that in languages that support it like CoffeeScript you see it used all the time, and the fact you see people using the this=that/self/_this ""pattern"" all the time. That pattern introduces its own set of problems - for example it creates a closure scope where one might not be needed and it's boilerplate.

Having fat arrow lets us solve that.

Benjamin Gruenbaum

---------- Forwarded message ---------- From: Andrea Giammarchi <andrea.giammarchi at gmail.com>

To: "Tab Atkins Jr." <jackalmage at gmail.com>

Cc: "es-discuss at mozilla.org" <es-discuss at mozilla.org>

Date: Tue, 1 Oct 2013 19:35:28 -0700 Subject: Re: what kind of problem is this fat arrow feature trying to solve ? setTimeout accept extra arguments ... I write JavaScript that uses this feature.

setTimeout(callback, delay, arg1, arg2, argN, evenAnObject);

so fat arrow does not solve much here, I can use self as first argument and I am good.

forEach and all other arrays accept a second argument

array.forEach(doStuff, boundContextObject);

so fat arrow does not solve a thing in mostly all Array extras.

for DOM I use handlers as specified by W3C so that {handleEvent: function () {this}} works better than any mess I could create with callbacks that I won't be unable to remove later on (as I've said) ... so I can use removeEventListener(this) in every method handled by that object.

So I actually wonder what kind of JavaScript you write because this was a honest question but probably ... people not familiar with JS are the answer: since developers ignore part of JS specs available since every then we need a fat arrow to break old syntax to make the creation of self bound function easier.

This would be already an answer so thanks for participating.

br

# Peter van der Zee (12 years ago)

(In all fairness, Andrea was merely, and quite explicitly so, asking for the rationale behind the fat arrow, not a scrutiny of his examples. Tab's sarcastic response was unnecessary on a whole different level, too.)

# Aymeric Vitte (12 years ago)

Le 02/10/2013 10:37, Claude Pache a écrit :

+1. The big win of arrow-functions, is that it prevents from using various ad-hoc kludges (var that = this, [].some(..., this), etc), whose sole goal is to defeat some unwanted feature (proper this binding in callbacks). Not a killing-feature, but a nice addition that will help to reduce noise in code.

And for those that do not use any longer var that=this but .bind(this) the transition is easy: just remove .bind(this) and replace function by fat arrow, one of the most wanted feature for me.

# Andrea Giammarchi (12 years ago)

first of all thank you all for your answers. In my experience I tend to not write var self = this; or var that = this; since the introduction of bind. Last Aymeric example is indeed part of what I was asking ... developers like it because they don't have to write .bind(context) at the end neither function at the beginning plus the closure or scope might not be necessary. This is why I've asked if point 3 would be eventually faster ... but again there are few misunderstanding, specially from David. I'll try to reply inline.

On Wed, Oct 2, 2013 at 12:34 AM, David Bruant <bruant.d at gmail.com> wrote:

Le 02/10/2013 04:35, Andrea Giammarchi a écrit :

setTimeout accept extra arguments ... I write JavaScript that uses this

feature.

setTimeout(callback, delay, arg1, arg2, argN, evenAnObject);

What is "evenAnObject"? It doesn't look like a standard thing: www.whatwg.org/specsweb-apps/current-work/ multipage/timers.html#**windowtimerswww.whatwg.org/specs/web-apps/current-work/multipage/timers.html#windowtimers

evenAnObject is a way to solve the "frozen" state of passed arguments. For those non familiar, setTimeout and setInterval accepts extra arguments by W3C standard. www.w3.org/TR/2011/WD-html5-20110525/timers.html#timers

This is working in every single ES3 JS engine you can try (even very old one) with the nice exception of IE < 10. However, this code will address exclusively those IE < 10 browsers and fix the behavior in there too.


/*@cc_on
(function(f){
 window.setTimeout =f(window.setTimeout);
 window.setInterval =f(window.setInterval);
})(function(f){return function(c,t){var
a=[].slice.call(arguments,2);return
f(function(){c.apply(this,a)},t)}});
@*/

IE10 and 11 won't execute such comment so you are good with a universal way to pass arguments. Some example:

function alertSum(a, b) {
  alert(a + b);
}
setTimeout(alertSum, 1000, 1, 2);

Above code will show 3 after a second. The problem David comes with variables

function alertSum(a, b) {
  alert(a + b);
}
var a = 1, b = 2;
setTimeout(alertSum, 1000, a++, b++);

the result will be again 3 because arguments are "trapped by value" at setTimeout declaration.

Accordingly David, to solve this problem you might want to pass an object and address its properties.

function alertSum(o) {
  alert(o.a + o.b);
}
var o = {a: 1, b: 2};
setTimeout(alertSum, 1000, o);
o.a++;
o.b++;

The result will be 5 so evenAnObject meant you can pass any kind of value, including an object that could be your context in the function through bind setTimeout(fn.bind(ctx), 1000) or extra argument setTimeout(fn, 1000, ctx) without needing to create both a timed execution and a new bound object but of course, fn should accept a pythonish self argument.

I hope we are clear here ... the rest ...

so fat arrow does not solve much here, I can use self as first argument and I am good.

forEach and all other arrays accept a second argument

array.forEach(doStuff, boundContextObject);

so fat arrow does not solve a thing in mostly all Array extras.

Both examples are most certainly design mistakes. It feels absurd that every function accepting a function as argument must also have a second argument for the |this| value (or even variable number of arguments to be passed around). Especially in the ES5 era with Function.prototype.bind.

I wasn't talking about how great this approach is, I was rather saying that it is possible to send a context so design mistake or not, the fat arrow won't solve anything if not extra operations/oibjects to create promoting a "reuse nothing" pattern hopefully optimized better than current inline function, but something I've personally never advocated if operations are repeated. I create the forEach utility unscoped as much as possible and once per execution lifecycle, so that I can send the context through the second argument instead of create O(n) times the inline function or the fat arrow.

The design mistake is emphasized by the inconsistency in the order of arguments in the 2 examples you provide. I'm glad Node.js didn't make all async functions accept another argument for |this|.

for DOM I use handlers as specified by W3C

Since when the DOM is specified by W3C? Must be about 10 years it isn't the case anymore</troll> ;-) Passing a function directly is standard too.

Thanks for the enlightening troll, I was talking about a technique developers keep forgetting and ignoring, a technique described here which is not a trick just standard behavior www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener

AnyClass.prototype.handleEvent = function (e) {
  // will point to the element where
  // addEventListener was used
  e.currentTarget;

  // will be an instanceof AnyClass
  // the object passed as handler
  this[e.type](e);
};


var handler = new AnyClass;
handler.click = function (e) {
  this.clicked = true; // won't expando in the node
  alert([e.screenX, e.screenY]);
};

document.body.addEventListener('click', handler);

Handler could be used for any sort of custom or real event and won't require any WeakMap to be attached and related to any DOM node.

Once again, this is the best pattern for state-machine like DOM behavior and developers keep creating 234567890 bound functions instead forgetting that simply using a different approach they could both solve and speed up many things at once.

This behavior is perfectly normalized in IE8 too, the only browser that does not have addEventListener and friends, through this ie8 library: WebReflection/ie8

Today, you could start writing a simplified and better approach to DOM <=>

JS interactions.

But "won't be able to remove later on" is false:

document.addEventListener('**DOMContentLoaded', function dcl(){
    // whatev's
    document.removeEventListener('**DOMContentLoaded', dcl);
});

You didn't use a fat arrow because indeed you cannot use one unless named and its name is available so ... what is your point here?

The fat arrow will inevitably lead to patterns such:

document.addEventListener('eventName', (e) => e.stopPropagation());

where it's impossible to get rid of that later on if needed (remember the statemachine approach? I could redefine entire behaviors simply adding or removing a single object ... won't be possible with fat arrows all over)

Even worst, that pattern could lead to this obscenity:

let fn;
document.addEventListener('once', fn = (e) =>

e.currentTarget.removeEventListener(e.type, fn));

WAIT, WHAT? Actually, we have a problem with the DOM.

First of all the this will be the one at fat arrow function definition time, so that the node must be retrieved through e.currentTarget which means that every single framework that relies in this should be somehow updated if fat => arrow is desired.

So, one of the major benefits of addEventListener compared with attachEvent is gone, this in the wild, most likely always window or undefined under use strict directive.

So here my question: is fat arrow solving anything in this case? My answer is no.

I understand that in some cases, specs allow to pass |this| or additional arguments, but it doesn't make it a good idea. I see the fact that Node.js didn't take that road as a very strong signal.

David

node.js has been lucky enough to born in an era where Function.prototype.bind() was already there otherwise would have came up with a similar solution.

That said, node.js also broke completely interoperability with any DOM Event we know since 1999 thanks to the (in?)famouse double argument pattern with the nullish error as first argument.

Not everything chose there is good neither but I agree, it would have been ugly to put a final context argument to each class method.

Best

# Tab Atkins Jr. (12 years ago)

On Tue, Oct 1, 2013 at 7:35 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

setTimeout accept extra arguments ... I write JavaScript that uses this feature.

setTimeout(callback, delay, arg1, arg2, argN, evenAnObject);

so fat arrow does not solve much here, I can use self as first argument and I am good.

forEach and all other arrays accept a second argument

array.forEach(doStuff, boundContextObject);

so fat arrow does not solve a thing in mostly all Array extras.

Having the capability to set 'this' (or pass the current this as a plain argument) doesn't make it any more convenient. 'this' still isn't captured by the closure like every other variable is, which is confusing. As David said, being forced to pollute the signature of every standard callback-taking function with this argument is just silly. As Claude and others have said, the silly 'this'-rebinding kludges we have to adopt everywhere just to work around this feature of JS are ridiculous and fragile. Automatic 'this' binding is very convenient in some places. In others, it's very inconvenient. Arrow functions give us something better suited for those latter cases.

for DOM I use handlers as specified by W3C so that {handleEvent: function () {this}} works better than any mess I could create with callbacks that I won't be unable to remove later on (as I've said) ...

Virtually nobody does this, and newer interfaces specified with the WebIDL 'callback' type don't accept it at all.

so I can use removeEventListener(this) in every method handled by that object.

I didn't mention event listeners, actually. There are lots of other things that take callbacks besides event listeners.

So I actually wonder what kind of JavaScript you write because this was a honest question but probably ... people not familiar with JS are the answer: since developers ignore part of JS specs available since every then we need a fat arrow to break old syntax to make the creation of self bound function easier.

This would be already an answer so thanks for participating.

Wow, that's pretty rude.

# Andrea Giammarchi (12 years ago)

fat arrow does not add any capabilities but create the need to be sure about the context.

In use strict fat arrow will bring a lovely undefined wich is undesired so nothing is solved in there. You need to be sure that the function/closure that is defining the fat arrow is doing it in a this context you expect and I wonder how many developers will fall into a this hell instead of "callback hell" forced to define fat arrows inside functions such:

(function(){

this.method = () => alert(123);

}).call(theDesiredContext);

The good part is that I've already written about so many pattern able to solve many common mistakes fat arrow will introduce so at least for me this will be a good reference to solve those mistakes/problems later on in the future.

Not much to add if not please read again your first answer to my question, something not just me found not just rude.

I've asked a question, a honest one, trying to understand. I wasn't trolling and I write real code so your "virtually nobody use that" approach is my daily basis code which is "virtually a better architecture for my needs" that I strongly hope W3C won't ever decide to get rid of because it avoids massive, expensive, pointless usage of extra objects, GC operations, and amount of RAM.

Google is usually very keen to these problems, handleEvent solve an infinity of them at once, developers should just learn how convenient this approach could be for mostly all their DOM based tasks and why not, even more.

Best

# Brendan Eich (12 years ago)

Andrea Giammarchi wrote:

fat arrow does not add any capabilities but create the need to be sure about the context.

This does not make sense. The problem of being unsure about "which this" already exists. Adding arrows does not make it worse. The new syntax makes it better, compared to 'var self = this;' or .bind(this) hacks that are more verbose and easy to forget -- that is, whose absence is easy to overlook.

In use strict fat arrow will bring a lovely undefined wich is undesired so nothing is solved in there.

Stop comparing apples to oranges. If we have today

"use strict"; function foo() { ... setCallback(function () { ... this ...}.bind(this)); }

Then you have no greater or lesser incidence of undefined-this bugs due to someone calling foo() instead of foo.call, foo.apply, or obj = {method:foo}, obj.method() by changing this code to use an arrow:

"use strict"; function foo() { ... setCallback(() => {... this ...}); }

If you don't like strict mode, keep that out of this thread. Incidence of undefined-this bugs due to it do not change with arrows.

# Benoit Marchant (12 years ago)

One could say that JavaScript is an object oriented language where functions are first class citizen. But JavaScript doesn't have methods, which in most oo languages have the feature of always running with this being the object the methods is executed on.

Was introducing a new type "method" considered? In JavaScript it would solve one class of problem we have with functions, which is the one I've been most impacted with as I generally use JS in an more oo way than functional way. And yes, I used more handleEvent for that reason.

Benoit

# Andrea Giammarchi (12 years ago)

You need to be sure about the this because today you can bind(anyObject || this) while with fat arrow you can only bind this so you need to be sure that the function context, the one everybody has always borrowed through call and apply, is the one you expect to be.

In a new direction where instanceof is being discouraged, the usage of this become critical.

As shortcut, fat arrow fails. var o = {method: () => whatver;};

As DOM listener it brings what handleEvent does since ever.

var o = {
  init: function () {
    document.addEventListener('click', this);
    // virtually the same of
    document.addEventListener('click', (e) => this.handleEvent(e));
  },
  handleEvent: function () {
    this === o;
  }
};

So I don't see many advantages on DOM world.

Once again, I am trying to understand where is the glory of this new feature.

I am not saying it should not be there, ES6 classes and generators already breaks the old syntax so it won't hurt a new utility as fat arrow is but where this will be exactly a better approach to the current situation ?

The only one that comes into my mind is the once event listener in node or eddy.js ... but once a part, and I admit in there it's handy, I cannot see many other real/concrete usages.

In CoffeeScript the fat arrow behaves differently having a dynamic this, am I correct? So whoever is comparing fat arrow with CoffeeScript should be aware these are completely different beasts and there was my question about what is solving for the real world.

No need to talk about use strict.

# Andrea Giammarchi (12 years ago)

If you cannot use fat arrow to define prototypes than you cannot recycle functions per each instance neither. IIRC you are behind a pretty damn good framework that works on DOM and indeed I was wondering if handleEvent would have been your choice there too.

Thanks for your thoughts.

# Brendan Eich (12 years ago)

Your reply incoherently flattens some of my words with leading '> '

citation prefixes. But I'll be brief here, no need to reply:

Andrea Giammarchi wrote:

In CoffeeScript the fat arrow behaves differently having a dynamic this, am I correct?

No, you are incorrect. CoffeeScript's => binds this, its -> leaves this

unbound.

# Marius Gundersen (12 years ago)

Every time someone wants to make a framework in JS they need to consider this. For example, a simple pubsu library could look like this:

publish("event", arg1, arg2) subscribe("event", function(arg1, arg2){ //do something, e.g. this.something = arg1+arg2 }, this);

But now the callback has the wrong this. One way around this is to force people to use bind(this), or you can force developers to always support a boundContext argument for every callback. For example, in promises:

doSomething().then(function(result){ this.result = result }, this);

Or with Knockout:

this.sum = ko.computed(function(){ return this.a() + this.b(); }, this);

Or with array functions:

this.array.filter(function(a){ return a>5; }).forEach(function(a){ this.sum += a; }, this);

These can all be simplified using the fat arrow:

subscribe((arg1, arg2) => this.something = arg1 + arg2);

doSomething().then((result) => this.result = result);

this.sum = ko.computed(() => this.a() + this.b());

this.array.filter((a) => a>5).forEach((a) => this.sum += a);

Not only does it reduce the amount of typing, which makes it easy to fit all these examples into a single line, it takes care of the this variable, which is used in a lot more places than DOM event handlers.

Marius Gundersen

# Andrea Giammarchi (12 years ago)

Thanks. And do "we" know which one is the most common case or any reason we won't have the same in ES6 ? I see both options as a win. Having only the => version looks like a huge limit in arrow potential.

# Andrea Giammarchi (12 years ago)

when do you need to address at runtime so many methods per instance/object ?

I've got the "solve inline" thing but I keep wondering when, where, and why, we need so many inline runtime bound method attachments.

Any real code example beside showing how shorter it is ?

Promises could simply implement handleEvent too though, it will make objects reusable per each promise lifecycle at any time and with hot-swap per each handleMethod possibility.

Very powerful, too bad developers behind didn't propose this approach too (yes, handleEvent can be swapped at runtime, that's how you could create a whole new world of possibilities through a single object and without even bother the DOM through add/remove listeners)

# David Bruant (12 years ago)

Le 02/10/2013 19:45, Andrea Giammarchi a écrit :

    so fat arrow does not solve much here, I can use self as first
    argument and I am good.

    `forEach` and all other arrays accept a second argument

    `array.forEach(doStuff, boundContextObject);`

    so fat arrow does not solve a thing in mostly all Array extras.

Both examples are most certainly design mistakes. It feels absurd
that every function accepting a function as argument must also
have a second argument for the |this| value (or even variable
number of arguments to be passed around). Especially in the ES5
era with Function.prototype.bind.

I wasn't talking about how great this approach is, I was rather saying that it is possible to send a context

Yes, only for these particular examples. But that's where it stops, arrow functions can be used as Node callbacks for instance. In promise's .then, you can pass a function or two, but not their |this|. Which |this| is used then? If you want the lexical |this|, arrow functions work.

so design mistake or not, the fat arrow won't solve anything if not extra operations/oibjects to create promoting a "reuse nothing" pattern hopefully optimized better than current inline function, but something I've personally never advocated if operations are repeated. I create the forEach utility unscoped as much as possible and once per execution lifecycle, so that I can send the context through the second argument instead of create O(n) times the inline function or the fat arrow.

Optimization is possible to avoid creating n function objects. Actually, I've discussed that with Jim Blandy (who works on SpiderMonkey) some time ago and he told me that if given some heuristics on function length and number of repetition, it's completely inlined and the function is only actually allocated in the slow path (so asymptotically never). It also works with nested .forEach!

The design mistake is emphasized by the inconsistency in the order
of arguments in the 2 examples you provide.
I'm glad Node.js didn't make all async functions accept another
argument for |this|.


    for **DOM** I use handlers as specified by **W3C**

Since when the DOM is specified by W3C? Must be about 10 years it
isn't the case anymore</troll> ;-)
Passing a function directly is standard too.

Thanks for the enlightening troll, I was talking about a technique developers keep forgetting and ignoring, a technique described here which is not a trick just standard behavior www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener

I know, I'm aware of it. I was just saying that passing just a function is standard too. Each approach has benefits and downsides. Arrow functions benefit one pattern. It doesn't mean unbalance the other pattern, you can still use it.

But "won't be able to remove later on" is false:

    document.addEventListener('DOMContentLoaded', function dcl(){
        // whatev's
        document.removeEventListener('DOMContentLoaded', dcl);
    });

You didn't use a fat arrow because indeed you cannot use one unless named and its name is available so ... what is your point here?

yeah, sorry about that, you're right. I actually hit that problem in a TypeScript project. In a few instances, I needed to remove a listener and inline arrow functions don't work for that. The conclusion I made was that it was rare enough to remove a listener this way that I could just get back to an inline non-arrow named function. Since I use direct functions and not handler objects, I never use |this| anyway (which is the target or currentTarget, I never remember), so arrow functions are just a shorter convenience. But that's just my opinion.

I understand that in some cases, specs allow to pass |this| or
additional arguments, but it doesn't make it a good idea. I see
the fact that Node.js didn't take that road as a very strong signal.

David

node.js has been lucky enough to born in an era where Function.prototype.bind() was already there otherwise would have came up with a similar solution.

That said, node.js also broke completely interoperability with any DOM Event we know since 1999 thanks to the (in?)famouse double argument pattern with the nullish error as first argument.

Why would they have even tried interoperability with DOM events? On the server, you don't need DOM events, do you? DOM implementations, if they do implement events will be interoperable, but Node.js doesn't. More, Node.js has its own event system which doesn't have the 2 arguments convention.

All in all, I think that what you're trying to demonstrate is that there are coding styles in which arrow functions aren't necessary. I agree. Arrow functions are a convenience (No! Brendan! Put that hammer down!!), it's possible to live without them. But there are some coding styles that benefit from them. I've used them extensively in a project (with TypeScript). It took me some time to adjust, but overall, the code feels lighter and more readable to me (and no coworker I worked with complained, some started to like it better in some circumstances). They avoided the issue of forgetting "var self = this;" which people who aren't experts in the language easily forget and are annoying to track down because only noticeable at runtime. They were worth it in my experience.

Note that it's not because they're in the language that you have to use them. But someone else explained that better that I would: www.youtube.com/watch?v=N2u44-zZYdo&list=PL37ZVnwpeshF7AHpbZt33aW0brYJyNftx

# Marius Gundersen (12 years ago)

Look at knockout.js and the way computed properties work. You quickly end up with multiple bound functions on a single object, which are always anonymous. The projects I've worked on lately has a lot of var self = this to get things to work. Because we use knockout.js we don't have any native dom event handlers, so your trick with the eventHandler method won't work. And we use pubsub, which affect observables on the this object, and Ajax is handled through Promises, which also needs access to the this object.

Marius Gundersen

# Aymeric Vitte (12 years ago)

Andrea, it's difficult to understand why you think the fat arrow does not help or I misunderstood your point, if |this| is already bound to something, like for events, then you don't need it, if you want to bind to something else then you use bind, if you want to bind to the outer |this| then you use the fat arrow, that's extremely usefull, even in a DOM env, because for example while handling events you probably have the case of binding |this| again inside, but DOM is not only events, I am using a lot bind(this) in DOM, node, etc and will replace it as previously mentioned by the fat arrow when available.

,

Aymeric

Le 02/10/2013 20:11, Andrea Giammarchi a écrit :

# Brendan Eich (12 years ago)

Andrea Giammarchi <mailto:andrea.giammarchi at gmail.com> October 2, 2013 2:25 PM Thanks. And do "we" know which one is the most common case or any reason we won't have the same in ES6 ? I see both options as a win. Having only the => version looks like a huge limit in arrow potential.

We went through the case analysis here, perhaps you missed it?

esdiscuss/2012-March/021873

quoting:

"""

If the consensus is that two arrows are too confusing, and we must choose to prefer either object literal or blocks, then the code I sampled suggests that object literals as expression bodies are rather uncommon (only 16 out of 5705 BTF candidates, or 0.2%).

 // Not so bad...
 x =>  ({ a: 123 });

kevin

"""

This is based on Kevin Smith's quantitative study:

esdiscuss/2012-March/021126

Please study carefully!

As noted many times, going back to the March 2012 meeting, we also talked about -> but some on TC39 view it as "an arrow too far". See

esdiscuss/2012-March/021875

a followup from me to the notes:

esdiscuss/2012-March/021872

# Andrea Giammarchi (12 years ago)

in line

On Wed, Oct 2, 2013 at 2:54 PM, David Bruant <bruant.d at gmail.com> wrote:

Le 02/10/2013 19:45, Andrea Giammarchi a écrit :

Yes, only for these particular examples.

Tab mentioned Array extras, that's the reason I've put them in the plate.

Promises ... never used them so far. I'll try to see how convenient is =>

there the day I'll need/use them.

Optimization is possible to avoid creating n function objects. Actually, I've discussed that with Jim Blandy (who works on SpiderMonkey) some time ago and he told me that if given some heuristics on function length and number of repetition, it's completely inlined and the function is only actually allocated in the slow path (so asymptotically never). It also works with nested .forEach!

Still that does not promote reusable code but inline ad-hoc operation usually abused in for loops too as it is the classic $('CSS') anti pattern repeated all over in jQuery world. It took a while to tell developers that maybe they simply need to address that once per closure/logic ^_^

You know what I mean ... glad to know SpiderMonkey can optimize that. I hope V8, JSC, and Chakra can do the same as transparent win for laziest devs.

Why would they have even tried interoperability with DOM events?

you know the myth "write once, deploy everywhere" right ? They decided to avoid the single Event object as arguments with its types. There's no way in common Emitters to have an event object and an event type ... only a hopefully null error and some result after or forced different behavior through manual emit when you end up passing by default null as first emitted argument due common handler pattern.

Also node didn't know about handleEvent ... so yes, it would have been a better world if node.js chaps had a better look in what DOM Events were offering when they started the implementation, IMO

All in all, I think that what you're trying to demonstrate

I am not trying to demonstrate anything ... I am showing solution to common problems trying to understand where this => would be better than what we

have now.

I haven't said fat arrow is bad, I am trying to understand why is better ... I don't have to use it and I won't for a while since I am still a old-school hand written optimized JS donkey-idiotic developer but since it has been discussed and applauded for long time now I am curious why is that and discovered a lot in this thread.

# Andrea Giammarchi (12 years ago)

It's a knockout choice I would say, nothing to do with the fact you cannot have an handleEvent in there.

Look at eddy.js or put in in your project and you could handleEvent all the things, DOM and not ^_^

As easy as that, but you confirmed developers are not familiar at all with such pattern: this is bad, IMO, bad for them as massive limit over architectures aimed to deal with the DOM and/or even server side JS.

That being said, I understand your very specific knockout base, but that's a surrounding env problem that didn't give you an easy way to solve this if not through bind or self addressed variable :-(

Thanks for sharing though, libraries/frameworks are always a good example of "already got this problem in here".

br

# Andrea Giammarchi (12 years ago)

I honestly think that is a new model to explain out there, and for a language many misunderstood already because of the magic this behavior ... fat arrow introduces a whole new world of foot-guns and a third option over inheritance and/or mixins.

The fact you need a lot of bind in the DOM suggests me you were not familiar or did not consider the handleEvent approach that really simplifies that a lot. If this is not the case than yes, fat arrow is useful for you.

This just to say that I am not saying it won't help, I am trying to understand where it does.

# Andrea Giammarchi (12 years ago)

Yes, I've missed this and if Kevin already studied real world use cases and that's the result then it's OK.

What is misleading about this topic is that it looks like a shortcut for common functions but it is absolutely not like that and this should be emphasized quite a lot, IMO

We have function, function with a this in it, bind with this made immutable and arrow with this made immutable and not the whole closure in it ... this is a very specific and different thing I need to get familiar with.

I will, eventually.

# Benoit Marchant (12 years ago)

Just as a comparison point, in MontageJS we chose to implement the DOM Event Target and Event Listener interfaces on Montage JavaScript objects to avoid adding similar APIs under a different name.

Benoit

# Andrea Giammarchi (12 years ago)

just because you mentioned it, I've implemented a 1:1 EventTarget ES3 compatible interface a while ago and the code is using a "recycle 3 functions to rule them all"* approach based on a simple Python style without requiring bind, fat arrow, anything that fix the context in any given method.

WebReflection/event-target/blob/master/build/event-target.max.js

The RAM is linear, GC has almost nothing to do in there, the mixin is reusable everywhere either borrowed or inherited.

If you were lookign for some example where fat arrow won't be even an option, this is a great example I guess.

Best

  • all but frozen or not extensible objects