Despite making repeated arguments for "soft binding", I'm pretty sure I haven't 
outlined here what it actually would *be*. Now that we're looking to add 
syntactic forms that create bound function objects (arrows and class methods), 
perhaps it's time to get consensus for or against. Soft binding has 2 
properties that make it desirable:

  * The global contract that methods can have their "this" re-set with .call() 
and .apply() is maintained
  * Common-case usage avoids the hazards of unbound and mis-appropriated "this" 
contexts. Most commonly, passing a method to a function which takes a callback:

     node.addEventListener("click", foo.bar);

The language today has 2 types of functions:

   * unbound: methods for which "this" is not fixed
   * hard-bound: methods bound by Function.prototype.bind()

Crucially, we have no syntax which creates hard-bound methods which means that 
they're not common (yet). To the extent that they are used, it is explicitly 
through forms like:

     node.addEventListener("click", foo.bar.bind(foo));

Or through libraries:

     dojo.connect(node, "onclick", foo, "bar");

This means that most users of most functions can still use .call() and .apply() 
without apprehension. Functions are still "just functions".

The new forms we're adding (methods and arrows) have the potential to change 
this radically, causing a large percentage of functions encountered by 
programmers to have binding. If that binding is hard-binding, .call() and 
.apply() break in the minds of users. Perhaps that's fine by you, but in 
addition to being a contractual failure, it removes a form of genericness which 
is unique in the language.

What to do?

One option is to barrel onward with either unbound functions, hard bound 
functions, or some mix thereof. These are all painful in ways I don't need to 
spend time here explaining. I propose a third alternative: soft binding (aka 
"preferred binding"). It enables the following:

     node.addEventListener("click", foo.bar.prefer(foo));

While still allowing the following:

     foo.bar.call(otherThis, …args);

Functions with preferred bindings can still be re-bound either with new 
preferred binding or with new hard binding (both forms vend new functions 
objects and they do today).

Here's a JSFiddle with an a quick ES5 desugaring + example:

      http://jsfiddle.net/slightlyoff/739CS/20/

Note that we need to re-define .call() and .apply() to be savvy to preferences, 
but this doesn't seem particularly painful. I've bluntly worked around it in 
this example to avoid __proto__ re-wiring.

Thoughts?

--
Alex Russell
slightly...@google.com
slightly...@chromium.org
a...@dojotoolkit.org BE03 E88D EABB 2116 CC49 8259 CF78 E242 59C3 9723

_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to