# Concise Method Binding

26 messages
12
Open this post in threaded view
|

## Concise Method Binding

 Considering the proposals for both concise methods and the bind operator I think it would be a great addition to be able to use them together.I am already seeing a lot of this:```class Foo { bar = () => { // bound } buz() { // unbound } }```I think having the bind operator with a concise method makes things more uniform:```class Foo { ::bar() { // bound } buz() { // unbound } }```This would also allow for this to be using on object literals:```let foo = { ::bar() { // bound } buz() { // unbound } }```This would also make using recursion with concise functions feasible:```let fibonacci = { ::at(n) { if (n < 2) { return n; } return this.at(n-1) + this.at(n-2); } } fibonacci.at(7); // 13```I am looking for a champion for this feature. Anybody interested?Thanks,JD Isaacks _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Concise Method Binding

 In your first example, the arrow function's "this" would be the "this" of the context the "class" is defined in - it wouldn't be bound at all. Can you point me to an example of where that example "bar" is a function bound to the instance?On Mon, Nov 9, 2015 at 5:45 PM, JD Isaacks wrote:Considering the proposals for both concise methods and the bind operator I think it would be a great addition to be able to use them together.I am already seeing a lot of this:```class Foo { bar = () => { // bound } buz() { // unbound } }```I think having the bind operator with a concise method makes things more uniform:```class Foo { ::bar() { // bound } buz() { // unbound } }```This would also allow for this to be using on object literals:```let foo = { ::bar() { // bound } buz() { // unbound } }```This would also make using recursion with concise functions feasible:```let fibonacci = { ::at(n) { if (n < 2) { return n; } return this.at(n-1) + this.at(n-2); } } fibonacci.at(7); // 13```I am looking for a champion for this feature. Anybody interested?Thanks,JD Isaacks _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Concise Method Binding

 Jordan Harband schrieb:  > JD Isaacks <[hidden email]> wrote:  >  >> class Foo {  >>    bar = () => {  >>      // bound  >>    }  >>    buz() {  >>      // unbound  >>    }  >> } > In your first example, the arrow function's "this" would be the "this" of > the context the "class" is defined in - it wouldn't be bound at all. No, the methods defined with "=" are automatically moved into the constructor, so that they are created once for each new instance. `this` in the arrow function would in fact be bound to the instance. It's indeed super-confusing to "declare" such methods right inside the `class` though, that's why I'm really opposing that proposal (https://github.com/jeffmo/es-class-static-properties-and-fields). Greetings,   Bergi _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Re: Concise Method Binding

 In reply to this post by JD Isaacks Bergi, I agree and I think this proposal negates the need for assigning methods like that.On Mon, Nov 9, 2015 at 9:46 PM, John Isaacks wrote:Bergi, I agree and I think this proposal negates the need for assigning methods like that. _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Concise Method Binding

 In reply to this post by JD Isaacks On Mon, Nov 9, 2015 at 8:45 PM JD Isaacks <[hidden email]> wrote:Considering the proposals for both concise methods and the bind operator I think it would be a great addition to be able to use them together.I am already seeing a lot of this:```class Foo { bar = () => { // bound } buz() { // unbound } }```Can you clarify what this is, because it's not valid ES6 code. Also, "bound" and "unbound" in what sense? In `buz`, the `this` object will be the instance of Foo from which it's called. Rick _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Concise Method Binding

 It's using an ES7 proposal, and it's a method bound to the instance. On Tue, Nov 10, 2015, 18:58 Rick Waldron <[hidden email]> wrote:On Mon, Nov 9, 2015 at 8:45 PM JD Isaacks <[hidden email]> wrote:Considering the proposals for both concise methods and the bind operator I think it would be a great addition to be able to use them together.I am already seeing a lot of this:```class Foo { bar = () => { // bound } buz() { // unbound } }```Can you clarify what this is, because it's not valid ES6 code. Also, "bound" and "unbound" in what sense? In `buz`, the `this` object will be the instance of Foo from which it's called. Rick _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Concise Method Binding

 On Tue, Nov 10, 2015 at 6:59 PM Isiah Meadows <[hidden email]> wrote:It's using an ES7 proposal, and it's a method bound to the instance.Ah, right—that proposal does not have consensus:  https://github.com/rwaldron/tc39-notes/blob/master/es7/2015-09/sept-22.md#54-updates-on-class-properties-proposal. Rick _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Re: Concise Method Binding

 In reply to this post by JD Isaacks So far all the comments have been regarding my first example using ES7 class properties proposal. No one has actually even mentioned the the part I am proposing. Is my explanation just poor? _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Re: Concise Method Binding

 are you talking about this?On Wed, Nov 11, 2015 at 2:10 PM, JD Isaacks wrote:So far all the comments have been regarding my first example using ES7 class properties proposal. No one has actually even mentioned the the part I am proposing. Is my explanation just poor? _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Re: Concise Method Binding

 In reply to this post by JD Isaacks Andrea, Sort of. I am talking about adding an additional place where that operator `::` can be used -- with concise methods.Currently they cannot be used in the way I described above but I think there are several reasons why it makes sense. _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Re: Concise Method Binding

 Just my thoughts, I wouldn't put any self-bound thing in the class and rather improve that `::` proposal so that whenever you `obj::method` it creates a uniquely bound callback so that `obj::method === obj::method` and at that point whenever you need to export, pass, or use such method you just `obj::method` or `obj::method()` or `let method = obj::method` and bring the pattern whenever it's needed instead of being slightly different per each "place" (class rather than objects)That would make it lazy, usable for events (in order to be able to also remove them) and easily transpilable for smoother migration.Having `class A { ::method() {} }` feels like somebody is playing too much with the protoype or "accidentally" polluting the constructorRegardsOn Wed, Nov 11, 2015 at 2:50 PM, JD Isaacks wrote:Andrea, Sort of. I am talking about adding an additional place where that operator `::` can be used -- with concise methods.Currently they cannot be used in the way I described above but I think there are several reasons why it makes sense. _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Re: Concise Method Binding

 I think what you are suggesting already exists with `::obj.method` which evaluates to `obj.method.bind(obj)` However, this creates a new function each time so `::obj.method !== ::obj.method`, not sure how `::obj.method === ::obj.method` would work.I sort of agree with you that using it that way would be preferred. However if the community wants bound methods attached to objects, there is currently no way to do that with an object literal.You would have to do something like:```let obj = {};obj.method = function(){}.bind(obj);```With my proposal you can.```let obj = { ::method(){} };```On Wed, Nov 11, 2015 at 10:20 AM, Andrea Giammarchi wrote:Just my thoughts, I wouldn't put any self-bound thing in the class and rather improve that `::` proposal so that whenever you `obj::method` it creates a uniquely bound callback so that `obj::method === obj::method` and at that point whenever you need to export, pass, or use such method you just `obj::method` or `obj::method()` or `let method = obj::method` and bring the pattern whenever it's needed instead of being slightly different per each "place" (class rather than objects)That would make it lazy, usable for events (in order to be able to also remove them) and easily transpilable for smoother migration.Having `class A { ::method() {} }` feels like somebody is playing too much with the protoype or "accidentally" polluting the constructorRegardsOn Wed, Nov 11, 2015 at 2:50 PM, JD Isaacks wrote:Andrea, Sort of. I am talking about adding an additional place where that operator `::` can be used -- with concise methods.Currently they cannot be used in the way I described above but I think there are several reasons why it makes sense. _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Re: Concise Method Binding

 Yeah, I've got that, my point is that whenever you need it you just `obj::method`Your example indeed says that currently the proposal is that `obj::method` is similar to `obj.method.bind(obj)` which is indeed always different and indeed you want something that makes method always the same/unique bound one, which I believe is universally the preferred way.What are two different bound of the same method useful for? Pretty much nothing, IMHO, while having a shortcut to lazily obtain a single bound version of that method for that object can be useful in many ways, as example `obj.on('event', anotherObj::method)` where it's always possible at that point to `obj.removeListener('event', anotherObj::method)` in case its needed.Having a shortcut that all it does is replace something already short to write like a `.bind` feels to me like a missed opportunity.Moreover, with this improvement you won't need/care to have self-bound methods at all```jslet obj = { method(){} };// and whenever needed you useobj::method;```Hope my POV is more clear now.RegardsOn Wed, Nov 11, 2015 at 4:01 PM, JD Isaacks wrote:I think what you are suggesting already exists with `::obj.method` which evaluates to `obj.method.bind(obj)` However, this creates a new function each time so `::obj.method !== ::obj.method`, not sure how `::obj.method === ::obj.method` would work.I sort of agree with you that using it that way would be preferred. However if the community wants bound methods attached to objects, there is currently no way to do that with an object literal.You would have to do something like:```let obj = {};obj.method = function(){}.bind(obj);```With my proposal you can.```let obj = { ::method(){} };```On Wed, Nov 11, 2015 at 10:20 AM, Andrea Giammarchi wrote:Just my thoughts, I wouldn't put any self-bound thing in the class and rather improve that `::` proposal so that whenever you `obj::method` it creates a uniquely bound callback so that `obj::method === obj::method` and at that point whenever you need to export, pass, or use such method you just `obj::method` or `obj::method()` or `let method = obj::method` and bring the pattern whenever it's needed instead of being slightly different per each "place" (class rather than objects)That would make it lazy, usable for events (in order to be able to also remove them) and easily transpilable for smoother migration.Having `class A { ::method() {} }` feels like somebody is playing too much with the protoype or "accidentally" polluting the constructorRegardsOn Wed, Nov 11, 2015 at 2:50 PM, JD Isaacks wrote:Andrea, Sort of. I am talking about adding an additional place where that operator `::` can be used -- with concise methods.Currently they cannot be used in the way I described above but I think there are several reasons why it makes sense. _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Re: Concise Method Binding

 Yes your point of view is more clear now, I like this is a lot.But I do not know how that would be transpiled or what the desugared version would look like. However, that would be awesome as you described.A thing to note. You keep using `obj::method` which is different from `::object.method` the former is when method is not already attached to the object, the later is for then it is.An example:```let foo = function(){};let bar = {};bar::foo // foo.bind(bar);```verses```let bar = { foo(){} };::foo.bar // foo.bar.bind(foo);```I think both cases theoretically would be awesome to work as you described. Just fuzzy on how it would look underneath.On Wed, Nov 11, 2015 at 11:14 AM, Andrea Giammarchi wrote:Yeah, I've got that, my point is that whenever you need it you just `obj::method`Your example indeed says that currently the proposal is that `obj::method` is similar to `obj.method.bind(obj)` which is indeed always different and indeed you want something that makes method always the same/unique bound one, which I believe is universally the preferred way.What are two different bound of the same method useful for? Pretty much nothing, IMHO, while having a shortcut to lazily obtain a single bound version of that method for that object can be useful in many ways, as example `obj.on('event', anotherObj::method)` where it's always possible at that point to `obj.removeListener('event', anotherObj::method)` in case its needed.Having a shortcut that all it does is replace something already short to write like a `.bind` feels to me like a missed opportunity.Moreover, with this improvement you won't need/care to have self-bound methods at all```jslet obj = { method(){} };// and whenever needed you useobj::method;```Hope my POV is more clear now.RegardsOn Wed, Nov 11, 2015 at 4:01 PM, JD Isaacks wrote:I think what you are suggesting already exists with `::obj.method` which evaluates to `obj.method.bind(obj)` However, this creates a new function each time so `::obj.method !== ::obj.method`, not sure how `::obj.method === ::obj.method` would work.I sort of agree with you that using it that way would be preferred. However if the community wants bound methods attached to objects, there is currently no way to do that with an object literal.You would have to do something like:```let obj = {};obj.method = function(){}.bind(obj);```With my proposal you can.```let obj = { ::method(){} };```On Wed, Nov 11, 2015 at 10:20 AM, Andrea Giammarchi wrote:Just my thoughts, I wouldn't put any self-bound thing in the class and rather improve that `::` proposal so that whenever you `obj::method` it creates a uniquely bound callback so that `obj::method === obj::method` and at that point whenever you need to export, pass, or use such method you just `obj::method` or `obj::method()` or `let method = obj::method` and bring the pattern whenever it's needed instead of being slightly different per each "place" (class rather than objects)That would make it lazy, usable for events (in order to be able to also remove them) and easily transpilable for smoother migration.Having `class A { ::method() {} }` feels like somebody is playing too much with the protoype or "accidentally" polluting the constructorRegardsOn Wed, Nov 11, 2015 at 2:50 PM, JD Isaacks wrote:Andrea, Sort of. I am talking about adding an additional place where that operator `::` can be used -- with concise methods.Currently they cannot be used in the way I described above but I think there are several reasons why it makes sense. _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Re: Concise Method Binding

 Pardon, I meant:```let bar = { foo(){} };::bar.foo // bar.foo.bind(bar);```in my last example.On Wed, Nov 11, 2015 at 11:23 AM, JD Isaacks wrote:Yes your point of view is more clear now, I like this is a lot.But I do not know how that would be transpiled or what the desugared version would look like. However, that would be awesome as you described.A thing to note. You keep using `obj::method` which is different from `::object.method` the former is when method is not already attached to the object, the later is for then it is.An example:```let foo = function(){};let bar = {};bar::foo // foo.bind(bar);```verses```let bar = { foo(){} };::foo.bar // foo.bar.bind(foo);```I think both cases theoretically would be awesome to work as you described. Just fuzzy on how it would look underneath.On Wed, Nov 11, 2015 at 11:14 AM, Andrea Giammarchi wrote:Yeah, I've got that, my point is that whenever you need it you just `obj::method`Your example indeed says that currently the proposal is that `obj::method` is similar to `obj.method.bind(obj)` which is indeed always different and indeed you want something that makes method always the same/unique bound one, which I believe is universally the preferred way.What are two different bound of the same method useful for? Pretty much nothing, IMHO, while having a shortcut to lazily obtain a single bound version of that method for that object can be useful in many ways, as example `obj.on('event', anotherObj::method)` where it's always possible at that point to `obj.removeListener('event', anotherObj::method)` in case its needed.Having a shortcut that all it does is replace something already short to write like a `.bind` feels to me like a missed opportunity.Moreover, with this improvement you won't need/care to have self-bound methods at all```jslet obj = { method(){} };// and whenever needed you useobj::method;```Hope my POV is more clear now.RegardsOn Wed, Nov 11, 2015 at 4:01 PM, JD Isaacks wrote:I think what you are suggesting already exists with `::obj.method` which evaluates to `obj.method.bind(obj)` However, this creates a new function each time so `::obj.method !== ::obj.method`, not sure how `::obj.method === ::obj.method` would work.I sort of agree with you that using it that way would be preferred. However if the community wants bound methods attached to objects, there is currently no way to do that with an object literal.You would have to do something like:```let obj = {};obj.method = function(){}.bind(obj);```With my proposal you can.```let obj = { ::method(){} };```On Wed, Nov 11, 2015 at 10:20 AM, Andrea Giammarchi wrote:Just my thoughts, I wouldn't put any self-bound thing in the class and rather improve that `::` proposal so that whenever you `obj::method` it creates a uniquely bound callback so that `obj::method === obj::method` and at that point whenever you need to export, pass, or use such method you just `obj::method` or `obj::method()` or `let method = obj::method` and bring the pattern whenever it's needed instead of being slightly different per each "place" (class rather than objects)That would make it lazy, usable for events (in order to be able to also remove them) and easily transpilable for smoother migration.Having `class A { ::method() {} }` feels like somebody is playing too much with the protoype or "accidentally" polluting the constructorRegardsOn Wed, Nov 11, 2015 at 2:50 PM, JD Isaacks wrote:Andrea, Sort of. I am talking about adding an additional place where that operator `::` can be used -- with concise methods.Currently they cannot be used in the way I described above but I think there are several reasons why it makes sense. _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Re: Concise Method Binding

 In reply to this post by JD Isaacks The way it could work is similar to the following one:```js(function (wm){'use strict';  // just to show the possible internal slot mechanism  Object.prototype.boundTo = function (method) {    // since I've used this for ages now in eddy.js, just replicating    var fn = typeof method === 'function' ? method : this[method];    var bound = wm.get(this);    if (!bound) wm.set(this, bound = {fn:[], bound:[]});    var i = bound.fn.indexOf(fn);    if (i < 0) bound.bound[i = bound.fn.push(fn) - 1] = fn.bind(this);    return bound.bound[i];  };}(new WeakMap));// examplevar obj = {method: function () { return this; }};// now, whenever neededobj.boundTo(obj.method);// will create the slot and set it up with obj.method// so that the following is trueobj.boundTo(obj.method) === obj.boundTo('method') &&obj.boundTo('method')() === obj;// if it's about another method// the equivalent of this::obj.anotherMethod// whould beobj.boundTo(anotherMethod);```The string fallback is not needed or relevant, it's just a semantic shortcut in my example to reach the method through the object without repeating the object nameRegardsOn Wed, Nov 11, 2015 at 4:23 PM, JD Isaacks wrote:Yes your point of view is more clear now, I like this is a lot.But I do not know how that would be transpiled or what the desugared version would look like. However, that would be awesome as you described.A thing to note. You keep using `obj::method` which is different from `::object.method` the former is when method is not already attached to the object, the later is for then it is.An example:```let foo = function(){};let bar = {};bar::foo // foo.bind(bar);```verses```let bar = { foo(){} };::foo.bar // foo.bar.bind(foo);```I think both cases theoretically would be awesome to work as you described. Just fuzzy on how it would look underneath.On Wed, Nov 11, 2015 at 11:14 AM, Andrea Giammarchi wrote:Yeah, I've got that, my point is that whenever you need it you just `obj::method`Your example indeed says that currently the proposal is that `obj::method` is similar to `obj.method.bind(obj)` which is indeed always different and indeed you want something that makes method always the same/unique bound one, which I believe is universally the preferred way.What are two different bound of the same method useful for? Pretty much nothing, IMHO, while having a shortcut to lazily obtain a single bound version of that method for that object can be useful in many ways, as example `obj.on('event', anotherObj::method)` where it's always possible at that point to `obj.removeListener('event', anotherObj::method)` in case its needed.Having a shortcut that all it does is replace something already short to write like a `.bind` feels to me like a missed opportunity.Moreover, with this improvement you won't need/care to have self-bound methods at all```jslet obj = { method(){} };// and whenever needed you useobj::method;```Hope my POV is more clear now.RegardsOn Wed, Nov 11, 2015 at 4:01 PM, JD Isaacks wrote:I think what you are suggesting already exists with `::obj.method` which evaluates to `obj.method.bind(obj)` However, this creates a new function each time so `::obj.method !== ::obj.method`, not sure how `::obj.method === ::obj.method` would work.I sort of agree with you that using it that way would be preferred. However if the community wants bound methods attached to objects, there is currently no way to do that with an object literal.You would have to do something like:```let obj = {};obj.method = function(){}.bind(obj);```With my proposal you can.```let obj = { ::method(){} };```On Wed, Nov 11, 2015 at 10:20 AM, Andrea Giammarchi wrote:Just my thoughts, I wouldn't put any self-bound thing in the class and rather improve that `::` proposal so that whenever you `obj::method` it creates a uniquely bound callback so that `obj::method === obj::method` and at that point whenever you need to export, pass, or use such method you just `obj::method` or `obj::method()` or `let method = obj::method` and bring the pattern whenever it's needed instead of being slightly different per each "place" (class rather than objects)That would make it lazy, usable for events (in order to be able to also remove them) and easily transpilable for smoother migration.Having `class A { ::method() {} }` feels like somebody is playing too much with the protoype or "accidentally" polluting the constructorRegardsOn Wed, Nov 11, 2015 at 2:50 PM, JD Isaacks wrote:Andrea, Sort of. I am talking about adding an additional place where that operator `::` can be used -- with concise methods.Currently they cannot be used in the way I described above but I think there are several reasons why it makes sense. _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Concise Method Binding

 In reply to this post by Andrea Giammarchi-2 Andrea Giammarchi schrieb: > Just my thoughts, I wouldn't put any self-bound thing in the class and > rather improve that `::` proposal so that whenever you `obj::method` it > creates a uniquely bound callback so that `obj::method === obj::method` This was considered: https://github.com/zenparsing/es-function-bind/issues/17 - it's quite unexpected that an operator would return the same result every time, and there are security considerations as well. Also it would be quite complicated to spec - how and where did you store the memoisation. Feel free to join the discussion! Using the `::` operator in the class declaration itself makes sense to me. It conveys "this method will always be bound" very effectively, and you wouldn't even need special syntax to access it. ```js class Xample {    ::myListener(…) {…} } ``` should desugar to ```js class Xample {    // a getter on the prototype    get myListener() {      // with per-instance memoisation      return this.myListener = (…) => {        // that returns a bound method        …      };    } } ``` It might be equivalently done via a custom decorator of course: ```js class Xample {    @autobind    myListener(…) {…} } ``` Regards,   Bergi _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Re: Concise Method Binding

 In reply to this post by Andrea Giammarchi-2 I like this very much. I would prefer this to my recommendation. So how to we go about proposing it as a change to an existing proposal?On Wed, Nov 11, 2015 at 11:45 AM, Andrea Giammarchi wrote:The way it could work is similar to the following one:```js(function (wm){'use strict';  // just to show the possible internal slot mechanism  Object.prototype.boundTo = function (method) {    // since I've used this for ages now in eddy.js, just replicating    var fn = typeof method === 'function' ? method : this[method];    var bound = wm.get(this);    if (!bound) wm.set(this, bound = {fn:[], bound:[]});    var i = bound.fn.indexOf(fn);    if (i < 0) bound.bound[i = bound.fn.push(fn) - 1] = fn.bind(this);    return bound.bound[i];  };}(new WeakMap));// examplevar obj = {method: function () { return this; }};// now, whenever neededobj.boundTo(obj.method);// will create the slot and set it up with obj.method// so that the following is trueobj.boundTo(obj.method) === obj.boundTo('method') &&obj.boundTo('method')() === obj;// if it's about another method// the equivalent of this::obj.anotherMethod// whould beobj.boundTo(anotherMethod);```The string fallback is not needed or relevant, it's just a semantic shortcut in my example to reach the method through the object without repeating the object nameRegardsOn Wed, Nov 11, 2015 at 4:23 PM, JD Isaacks wrote:Yes your point of view is more clear now, I like this is a lot.But I do not know how that would be transpiled or what the desugared version would look like. However, that would be awesome as you described.A thing to note. You keep using `obj::method` which is different from `::object.method` the former is when method is not already attached to the object, the later is for then it is.An example:```let foo = function(){};let bar = {};bar::foo // foo.bind(bar);```verses```let bar = { foo(){} };::foo.bar // foo.bar.bind(foo);```I think both cases theoretically would be awesome to work as you described. Just fuzzy on how it would look underneath.On Wed, Nov 11, 2015 at 11:14 AM, Andrea Giammarchi wrote:Yeah, I've got that, my point is that whenever you need it you just `obj::method`Your example indeed says that currently the proposal is that `obj::method` is similar to `obj.method.bind(obj)` which is indeed always different and indeed you want something that makes method always the same/unique bound one, which I believe is universally the preferred way.What are two different bound of the same method useful for? Pretty much nothing, IMHO, while having a shortcut to lazily obtain a single bound version of that method for that object can be useful in many ways, as example `obj.on('event', anotherObj::method)` where it's always possible at that point to `obj.removeListener('event', anotherObj::method)` in case its needed.Having a shortcut that all it does is replace something already short to write like a `.bind` feels to me like a missed opportunity.Moreover, with this improvement you won't need/care to have self-bound methods at all```jslet obj = { method(){} };// and whenever needed you useobj::method;```Hope my POV is more clear now.RegardsOn Wed, Nov 11, 2015 at 4:01 PM, JD Isaacks wrote:I think what you are suggesting already exists with `::obj.method` which evaluates to `obj.method.bind(obj)` However, this creates a new function each time so `::obj.method !== ::obj.method`, not sure how `::obj.method === ::obj.method` would work.I sort of agree with you that using it that way would be preferred. However if the community wants bound methods attached to objects, there is currently no way to do that with an object literal.You would have to do something like:```let obj = {};obj.method = function(){}.bind(obj);```With my proposal you can.```let obj = { ::method(){} };```On Wed, Nov 11, 2015 at 10:20 AM, Andrea Giammarchi wrote:Just my thoughts, I wouldn't put any self-bound thing in the class and rather improve that `::` proposal so that whenever you `obj::method` it creates a uniquely bound callback so that `obj::method === obj::method` and at that point whenever you need to export, pass, or use such method you just `obj::method` or `obj::method()` or `let method = obj::method` and bring the pattern whenever it's needed instead of being slightly different per each "place" (class rather than objects)That would make it lazy, usable for events (in order to be able to also remove them) and easily transpilable for smoother migration.Having `class A { ::method() {} }` feels like somebody is playing too much with the protoype or "accidentally" polluting the constructorRegardsOn Wed, Nov 11, 2015 at 2:50 PM, JD Isaacks wrote:Andrea, Sort of. I am talking about adding an additional place where that operator `::` can be used -- with concise methods.Currently they cannot be used in the way I described above but I think there are several reasons why it makes sense. _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss
Open this post in threaded view
|

## Re: Re: Concise Method Binding

 Ahh, good point Bergi. Thanks for brining that up.On Wed, Nov 11, 2015 at 11:55 AM, JD Isaacks wrote:I like this very much. I would prefer this to my recommendation. So how to we go about proposing it as a change to an existing proposal?On Wed, Nov 11, 2015 at 11:45 AM, Andrea Giammarchi wrote:The way it could work is similar to the following one:```js(function (wm){'use strict';  // just to show the possible internal slot mechanism  Object.prototype.boundTo = function (method) {    // since I've used this for ages now in eddy.js, just replicating    var fn = typeof method === 'function' ? method : this[method];    var bound = wm.get(this);    if (!bound) wm.set(this, bound = {fn:[], bound:[]});    var i = bound.fn.indexOf(fn);    if (i < 0) bound.bound[i = bound.fn.push(fn) - 1] = fn.bind(this);    return bound.bound[i];  };}(new WeakMap));// examplevar obj = {method: function () { return this; }};// now, whenever neededobj.boundTo(obj.method);// will create the slot and set it up with obj.method// so that the following is trueobj.boundTo(obj.method) === obj.boundTo('method') &&obj.boundTo('method')() === obj;// if it's about another method// the equivalent of this::obj.anotherMethod// whould beobj.boundTo(anotherMethod);```The string fallback is not needed or relevant, it's just a semantic shortcut in my example to reach the method through the object without repeating the object nameRegardsOn Wed, Nov 11, 2015 at 4:23 PM, JD Isaacks wrote:Yes your point of view is more clear now, I like this is a lot.But I do not know how that would be transpiled or what the desugared version would look like. However, that would be awesome as you described.A thing to note. You keep using `obj::method` which is different from `::object.method` the former is when method is not already attached to the object, the later is for then it is.An example:```let foo = function(){};let bar = {};bar::foo // foo.bind(bar);```verses```let bar = { foo(){} };::foo.bar // foo.bar.bind(foo);```I think both cases theoretically would be awesome to work as you described. Just fuzzy on how it would look underneath.On Wed, Nov 11, 2015 at 11:14 AM, Andrea Giammarchi wrote:Yeah, I've got that, my point is that whenever you need it you just `obj::method`Your example indeed says that currently the proposal is that `obj::method` is similar to `obj.method.bind(obj)` which is indeed always different and indeed you want something that makes method always the same/unique bound one, which I believe is universally the preferred way.What are two different bound of the same method useful for? Pretty much nothing, IMHO, while having a shortcut to lazily obtain a single bound version of that method for that object can be useful in many ways, as example `obj.on('event', anotherObj::method)` where it's always possible at that point to `obj.removeListener('event', anotherObj::method)` in case its needed.Having a shortcut that all it does is replace something already short to write like a `.bind` feels to me like a missed opportunity.Moreover, with this improvement you won't need/care to have self-bound methods at all```jslet obj = { method(){} };// and whenever needed you useobj::method;```Hope my POV is more clear now.RegardsOn Wed, Nov 11, 2015 at 4:01 PM, JD Isaacks wrote:I think what you are suggesting already exists with `::obj.method` which evaluates to `obj.method.bind(obj)` However, this creates a new function each time so `::obj.method !== ::obj.method`, not sure how `::obj.method === ::obj.method` would work.I sort of agree with you that using it that way would be preferred. However if the community wants bound methods attached to objects, there is currently no way to do that with an object literal.You would have to do something like:```let obj = {};obj.method = function(){}.bind(obj);```With my proposal you can.```let obj = { ::method(){} };```On Wed, Nov 11, 2015 at 10:20 AM, Andrea Giammarchi wrote:Just my thoughts, I wouldn't put any self-bound thing in the class and rather improve that `::` proposal so that whenever you `obj::method` it creates a uniquely bound callback so that `obj::method === obj::method` and at that point whenever you need to export, pass, or use such method you just `obj::method` or `obj::method()` or `let method = obj::method` and bring the pattern whenever it's needed instead of being slightly different per each "place" (class rather than objects)That would make it lazy, usable for events (in order to be able to also remove them) and easily transpilable for smoother migration.Having `class A { ::method() {} }` feels like somebody is playing too much with the protoype or "accidentally" polluting the constructorRegardsOn Wed, Nov 11, 2015 at 2:50 PM, JD Isaacks wrote:Andrea, Sort of. I am talking about adding an additional place where that operator `::` can be used -- with concise methods.Currently they cannot be used in the way I described above but I think there are several reasons why it makes sense. _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss _______________________________________________ es-discuss mailing list [hidden email] https://mail.mozilla.org/listinfo/es-discuss