Named `this` and `this` destructuring

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Named `this` and `this` destructuring

Jussi Kalliokoski
It's probably a bit early for this, but I figured I'd put it out there (I already proposed this as a tangent in the function bind syntax thread). This syntax proposal is purely about convenience and subjective expressiveness (like any feature addition to a Turing complete language).

As I've been building Trine, I noticed that the "`this` as data" pattern is extremely powerful and expressive, however the code in the functions doesn't convey the intent very clearly. For example:

function add (b) { return this + b; }
function * map (fn) { for ( let item of this ) { yield item::fn(); } }

vs.

function add (a, b) { return a + b; }
function * map (iterator, fn) { for ( let item of iterator ) { yield item::fn(); } }


Also currently neither Flow or TypeScript support type annotating this. There's discussion [1] [2] in both the projects for allowing `this` to be specified as a parameter to allow annotating it, e.g.

function add (this : number, b : number) : number { return this + b; }

This leads to my current proposal, i.e. being able to make the first parameter of the function an alias for `this` by using a special prefix (&). This would not only allow aliasing `this`, but also destructuring and default values (as well as type annotation in language extensions).

The different forms and their desugarings:

function add (&a, b) {
  return a + b;
}

// would desugar to

function add (b) {
  var a = this;
  return a + b;
}


function multiplyTuple (&[a, b], multiplier) {
  return [a * multiplier, b * multiplier];
}

// would desugar to
function multiplyTuple (multiplier) {
  var [a, b] = this;
  return [a * multiplier, b * multiplier];
}


function multiplyPoints (&{ x1: x, y1: y }, { x2: x, y2: y }) {
  return { x: x1 * x2, y: y1 * y2 };
}

// would desugar to
function multiplyPoints (_p2) {
  var { x1: x, y1: y } = this;
  var { x2: x, y2: y } = _p2;
  return { x: x1 * x2, y: y1 * y2 };
}


// allow passing the element for mocking in tests
function isQsaSupported (&dummyElement = document) {
  return typeof dummyElement.querySelectorAll !== "undefined";
}


This proposal would also be consistent with the type annotation proposals for `this` mentioned earlier.

WDYT?

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Named `this` and `this` destructuring

C. Scott Ananian
Could you include some examples of *calling* functions defined this way?  The most obvious way uses `Function#call` and would be terribly awkward.  Perhaps I'm just overlooking some ES6 feature which makes passing a specific `this` value easy?

It seems curious that you are not using methods instead of functions.
  --scott

On Wed, Jun 17, 2015 at 2:41 AM, Jussi Kalliokoski <[hidden email]> wrote:
It's probably a bit early for this, but I figured I'd put it out there (I already proposed this as a tangent in the function bind syntax thread). This syntax proposal is purely about convenience and subjective expressiveness (like any feature addition to a Turing complete language).

As I've been building Trine, I noticed that the "`this` as data" pattern is extremely powerful and expressive, however the code in the functions doesn't convey the intent very clearly. For example:

function add (b) { return this + b; }
function * map (fn) { for ( let item of this ) { yield item::fn(); } }

vs.

function add (a, b) { return a + b; }
function * map (iterator, fn) { for ( let item of iterator ) { yield item::fn(); } }


Also currently neither Flow or TypeScript support type annotating this. There's discussion [1] [2] in both the projects for allowing `this` to be specified as a parameter to allow annotating it, e.g.

function add (this : number, b : number) : number { return this + b; }

This leads to my current proposal, i.e. being able to make the first parameter of the function an alias for `this` by using a special prefix (&). This would not only allow aliasing `this`, but also destructuring and default values (as well as type annotation in language extensions).

The different forms and their desugarings:

function add (&a, b) {
  return a + b;
}

// would desugar to

function add (b) {
  var a = this;
  return a + b;
}


function multiplyTuple (&[a, b], multiplier) {
  return [a * multiplier, b * multiplier];
}

// would desugar to
function multiplyTuple (multiplier) {
  var [a, b] = this;
  return [a * multiplier, b * multiplier];
}


function multiplyPoints (&{ x1: x, y1: y }, { x2: x, y2: y }) {
  return { x: x1 * x2, y: y1 * y2 };
}

// would desugar to
function multiplyPoints (_p2) {
  var { x1: x, y1: y } = this;
  var { x2: x, y2: y } = _p2;
  return { x: x1 * x2, y: y1 * y2 };
}


// allow passing the element for mocking in tests
function isQsaSupported (&dummyElement = document) {
  return typeof dummyElement.querySelectorAll !== "undefined";
}


This proposal would also be consistent with the type annotation proposals for `this` mentioned earlier.

WDYT?

_______________________________________________
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
Reply | Threaded
Open this post in threaded view
|

Re: Named `this` and `this` destructuring

Andrea Giammarchi-2
Mostly every Array extra in ES5 would work with those functions, e.g.

```js
function multiplyPoints (_p2) {
  var { x1: x, y1: y } = this;
  var { x2: x, y2: y } = _p2;
  return { x: x1 * x2, y: y1 * y2 };
}

var multiplied = manyPoints.map(multiplyPoints, centralPoint);
```

It's not that common pattern but it gives you the ability to recycle functions as both methods or filters or mappers or forEachers and vice-versa.

I personally use those kind of functions quite a lot to be honest, most developers keep ignoring Array extra second parameter as context though, they probably use a wrapped fat arrow within an IFI with call(context) :D

Best Regards


On Wed, Jun 17, 2015 at 3:53 PM, C. Scott Ananian <[hidden email]> wrote:
Could you include some examples of *calling* functions defined this way?  The most obvious way uses `Function#call` and would be terribly awkward.  Perhaps I'm just overlooking some ES6 feature which makes passing a specific `this` value easy?

It seems curious that you are not using methods instead of functions.
  --scott

On Wed, Jun 17, 2015 at 2:41 AM, Jussi Kalliokoski <[hidden email]> wrote:
It's probably a bit early for this, but I figured I'd put it out there (I already proposed this as a tangent in the function bind syntax thread). This syntax proposal is purely about convenience and subjective expressiveness (like any feature addition to a Turing complete language).

As I've been building Trine, I noticed that the "`this` as data" pattern is extremely powerful and expressive, however the code in the functions doesn't convey the intent very clearly. For example:

function add (b) { return this + b; }
function * map (fn) { for ( let item of this ) { yield item::fn(); } }

vs.

function add (a, b) { return a + b; }
function * map (iterator, fn) { for ( let item of iterator ) { yield item::fn(); } }


Also currently neither Flow or TypeScript support type annotating this. There's discussion [1] [2] in both the projects for allowing `this` to be specified as a parameter to allow annotating it, e.g.

function add (this : number, b : number) : number { return this + b; }

This leads to my current proposal, i.e. being able to make the first parameter of the function an alias for `this` by using a special prefix (&). This would not only allow aliasing `this`, but also destructuring and default values (as well as type annotation in language extensions).

The different forms and their desugarings:

function add (&a, b) {
  return a + b;
}

// would desugar to

function add (b) {
  var a = this;
  return a + b;
}


function multiplyTuple (&[a, b], multiplier) {
  return [a * multiplier, b * multiplier];
}

// would desugar to
function multiplyTuple (multiplier) {
  var [a, b] = this;
  return [a * multiplier, b * multiplier];
}


function multiplyPoints (&{ x1: x, y1: y }, { x2: x, y2: y }) {
  return { x: x1 * x2, y: y1 * y2 };
}

// would desugar to
function multiplyPoints (_p2) {
  var { x1: x, y1: y } = this;
  var { x2: x, y2: y } = _p2;
  return { x: x1 * x2, y: y1 * y2 };
}


// allow passing the element for mocking in tests
function isQsaSupported (&dummyElement = document) {
  return typeof dummyElement.querySelectorAll !== "undefined";
}


This proposal would also be consistent with the type annotation proposals for `this` mentioned earlier.

WDYT?

_______________________________________________
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



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Named `this` and `this` destructuring

Allen Wirfs-Brock

On Jun 17, 2015, at 8:09 AM, Andrea Giammarchi wrote:

Mostly every Array extra in ES5 would work with those functions, e.g.

```js
function multiplyPoints (_p2) {
  var { x1: x, y1: y } = this;
  var { x2: x, y2: y } = _p2;
  return { x: x1 * x2, y: y1 * y2 };
}

var multiplied = manyPoints.map(multiplyPoints, centralPoint);
```

It's not that common pattern but it gives you the ability to recycle functions as both methods or filters or mappers or forEachers and vice-versa.

I personally use those kind of functions quite a lot to be honest, most developers keep ignoring Array extra second parameter as context though, they probably use a wrapped fat arrow within an IFI with call(context) :D


It seems to me that  we already can quite nicely express in ES6 the use of a function as a method:

```js
function multiplyPoints({x1, y1}, {x2,y2}) {
    return { x: x1 * x2, y: y1 * y2 }
}

class Point {
   multiply(p2) {return multiplyPoints(this, p2)}
}
```

or, perhaps a bit more OO

```js
class Point {
   static multiply({x1, y1}, {x2,y2}) {
      return new Point(x1 * x2, y1 * y2 )  //or new this(...) if you care about subclassing Point
   }

   multiply(p2) {return Point.multiply(this, p2)}

   constructor(x,y) {
      this.x = x;
      this.x = y;
   }
}
```

Regardless of how you express it, if you want the same function to be used both as a standalone function and as an method, you are going to have to have a line or two of code to install the function as a method.  To me, the one-line method definitions used above are about as concise and much clearer in intent than `Point.prototype.multiply=multiplyPoints;` or whatever other expression you would use to install such a function as a method.  And I would expect any high perf JIT to use inlining to completely eliminate the indirection so, where it matters, there probably wound't be any performance difference.

Many JS programmers have historically been confused about the JS semantics of `this` because it is over-exposed in non-method functions. Things like the current proposal increases rather than mitigates the potential for such confusion. if you are programming in a functional style, don't write functions that use `this`.  If you need to transition from to/from OO and functional styles, be explicit as shown above.

`this` is an OO concept.  FP people, `this` is not for you;  don't use it, don't try to "fix it". 

Allen



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Named `this` and `this` destructuring

Andrea Giammarchi-2
I forgot to mention that those functions I use as both methods and map/filters are most of the time **private** , and yet we haven't introduced private methods within current class specification.

Functions with a `this` are very portable/handy within closures, combined with Array extras and .call/.apply to use them as private methods has been very well known and used pattern since ES3

I'm not saying this proposal improve much in current ES6 specification, I'm saying there are very valid use cases for having a `this` in a non method function.

Regards


On Wed, Jun 17, 2015 at 5:13 PM, Allen Wirfs-Brock <[hidden email]> wrote:

On Jun 17, 2015, at 8:09 AM, Andrea Giammarchi wrote:

Mostly every Array extra in ES5 would work with those functions, e.g.

```js
function multiplyPoints (_p2) {
  var { x1: x, y1: y } = this;
  var { x2: x, y2: y } = _p2;
  return { x: x1 * x2, y: y1 * y2 };
}

var multiplied = manyPoints.map(multiplyPoints, centralPoint);
```

It's not that common pattern but it gives you the ability to recycle functions as both methods or filters or mappers or forEachers and vice-versa.

I personally use those kind of functions quite a lot to be honest, most developers keep ignoring Array extra second parameter as context though, they probably use a wrapped fat arrow within an IFI with call(context) :D


It seems to me that  we already can quite nicely express in ES6 the use of a function as a method:

```js
function multiplyPoints({x1, y1}, {x2,y2}) {
    return { x: x1 * x2, y: y1 * y2 }
}

class Point {
   multiply(p2) {return multiplyPoints(this, p2)}
}
```

or, perhaps a bit more OO

```js
class Point {
   static multiply({x1, y1}, {x2,y2}) {
      return new Point(x1 * x2, y1 * y2 )  //or new this(...) if you care about subclassing Point
   }

   multiply(p2) {return Point.multiply(this, p2)}

   constructor(x,y) {
      this.x = x;
      this.x = y;
   }
}
```

Regardless of how you express it, if you want the same function to be used both as a standalone function and as an method, you are going to have to have a line or two of code to install the function as a method.  To me, the one-line method definitions used above are about as concise and much clearer in intent than `Point.prototype.multiply=multiplyPoints;` or whatever other expression you would use to install such a function as a method.  And I would expect any high perf JIT to use inlining to completely eliminate the indirection so, where it matters, there probably wound't be any performance difference.

Many JS programmers have historically been confused about the JS semantics of `this` because it is over-exposed in non-method functions. Things like the current proposal increases rather than mitigates the potential for such confusion. if you are programming in a functional style, don't write functions that use `this`.  If you need to transition from to/from OO and functional styles, be explicit as shown above.

`this` is an OO concept.  FP people, `this` is not for you;  don't use it, don't try to "fix it". 

Allen




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Named `this` and `this` destructuring

Jussi Kalliokoski
In reply to this post by Allen Wirfs-Brock


On Wed, Jun 17, 2015 at 7:13 PM, Allen Wirfs-Brock <[hidden email]> wrote:

On Jun 17, 2015, at 8:09 AM, Andrea Giammarchi wrote:

Mostly every Array extra in ES5 would work with those functions, e.g.

```js
function multiplyPoints (_p2) {
  var { x1: x, y1: y } = this;
  var { x2: x, y2: y } = _p2;
  return { x: x1 * x2, y: y1 * y2 };
}

var multiplied = manyPoints.map(multiplyPoints, centralPoint);
```

It's not that common pattern but it gives you the ability to recycle functions as both methods or filters or mappers or forEachers and vice-versa.

I personally use those kind of functions quite a lot to be honest, most developers keep ignoring Array extra second parameter as context though, they probably use a wrapped fat arrow within an IFI with call(context) :D


It seems to me that  we already can quite nicely express in ES6 the use of a function as a method:

```js
function multiplyPoints({x1, y1}, {x2,y2}) {
    return { x: x1 * x2, y: y1 * y2 }
}

class Point {
   multiply(p2) {return multiplyPoints(this, p2)}
}
```

or, perhaps a bit more OO

```js
class Point {
   static multiply({x1, y1}, {x2,y2}) {
      return new Point(x1 * x2, y1 * y2 )  //or new this(...) if you care about subclassing Point
   }

   multiply(p2) {return Point.multiply(this, p2)}

   constructor(x,y) {
      this.x = x;
      this.x = y;
   }
}
```

Regardless of how you express it, if you want the same function to be used both as a standalone function and as an method, you are going to have to have a line or two of code to install the function as a method.  To me, the one-line method definitions used above are about as concise and much clearer in intent than `Point.prototype.multiply=multiplyPoints;` or whatever other expression you would use to install such a function as a method.  And I would expect any high perf JIT to use inlining to completely eliminate the indirection so, where it matters, there probably wound't be any performance difference.

Many JS programmers have historically been confused about the JS semantics of `this` because it is over-exposed in non-method functions. Things like the current proposal increases rather than mitigates the potential for such confusion. if you are programming in a functional style, don't write functions that use `this`.  If you need to transition from to/from OO and functional styles, be explicit as shown above.

`this` is an OO concept.  FP people, `this` is not for you;  don't use it, don't try to "fix it".

But I already am [1][1], and it allows for a much nicer syntax than functions that don't use `this`, and also composes well with built-ins (other than Object.*) This proposal is building on the proposed function bind syntax [2][2].

More examples of the power of the bind syntax can be found in the links, but the bind syntax combined with my proposal would for example allow this:

```JS
function add (&a, b) { return a + b; }

2::add(3) // 5


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Named `this` and `this` destructuring

Andrea Giammarchi-2
OK **that one** I've no idea what supposes to improve exactly ... I should have tried to realize your proposal better, apologies.

After seeing that, I probably agree with Allen at this point we don't really need that kind of syntax around JS (still IMHO, of course)

Best Regards

On Wed, Jun 17, 2015 at 6:01 PM, Jussi Kalliokoski <[hidden email]> wrote:


On Wed, Jun 17, 2015 at 7:13 PM, Allen Wirfs-Brock <[hidden email]> wrote:

On Jun 17, 2015, at 8:09 AM, Andrea Giammarchi wrote:

Mostly every Array extra in ES5 would work with those functions, e.g.

```js
function multiplyPoints (_p2) {
  var { x1: x, y1: y } = this;
  var { x2: x, y2: y } = _p2;
  return { x: x1 * x2, y: y1 * y2 };
}

var multiplied = manyPoints.map(multiplyPoints, centralPoint);
```

It's not that common pattern but it gives you the ability to recycle functions as both methods or filters or mappers or forEachers and vice-versa.

I personally use those kind of functions quite a lot to be honest, most developers keep ignoring Array extra second parameter as context though, they probably use a wrapped fat arrow within an IFI with call(context) :D


It seems to me that  we already can quite nicely express in ES6 the use of a function as a method:

```js
function multiplyPoints({x1, y1}, {x2,y2}) {
    return { x: x1 * x2, y: y1 * y2 }
}

class Point {
   multiply(p2) {return multiplyPoints(this, p2)}
}
```

or, perhaps a bit more OO

```js
class Point {
   static multiply({x1, y1}, {x2,y2}) {
      return new Point(x1 * x2, y1 * y2 )  //or new this(...) if you care about subclassing Point
   }

   multiply(p2) {return Point.multiply(this, p2)}

   constructor(x,y) {
      this.x = x;
      this.x = y;
   }
}
```

Regardless of how you express it, if you want the same function to be used both as a standalone function and as an method, you are going to have to have a line or two of code to install the function as a method.  To me, the one-line method definitions used above are about as concise and much clearer in intent than `Point.prototype.multiply=multiplyPoints;` or whatever other expression you would use to install such a function as a method.  And I would expect any high perf JIT to use inlining to completely eliminate the indirection so, where it matters, there probably wound't be any performance difference.

Many JS programmers have historically been confused about the JS semantics of `this` because it is over-exposed in non-method functions. Things like the current proposal increases rather than mitigates the potential for such confusion. if you are programming in a functional style, don't write functions that use `this`.  If you need to transition from to/from OO and functional styles, be explicit as shown above.

`this` is an OO concept.  FP people, `this` is not for you;  don't use it, don't try to "fix it".

But I already am [1][1], and it allows for a much nicer syntax than functions that don't use `this`, and also composes well with built-ins (other than Object.*) This proposal is building on the proposed function bind syntax [2][2].

More examples of the power of the bind syntax can be found in the links, but the bind syntax combined with my proposal would for example allow this:

```JS
function add (&a, b) { return a + b; }

2::add(3) // 5



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Named `this` and `this` destructuring

Jussi Kalliokoski
On Wed, Jun 17, 2015 at 10:35 PM, Andrea Giammarchi <[hidden email]> wrote:
OK **that one** I've no idea what supposes to improve exactly ... I should have tried to realize your proposal better, apologies.

After seeing that, I probably agree with Allen at this point we don't really need that kind of syntax around JS (still IMHO, of course)

To each their own. :) I personally really like the bind syntax and have received a tremendously positive feedback on it - the Trine project alone has received over 1000 stars on GitHub, in under a week since release (last Thursday), and it's just showcasing a part of the power of the proposed syntax.
 

Best Regards

On Wed, Jun 17, 2015 at 6:01 PM, Jussi Kalliokoski <[hidden email]> wrote:


On Wed, Jun 17, 2015 at 7:13 PM, Allen Wirfs-Brock <[hidden email]> wrote:

On Jun 17, 2015, at 8:09 AM, Andrea Giammarchi wrote:

Mostly every Array extra in ES5 would work with those functions, e.g.

```js
function multiplyPoints (_p2) {
  var { x1: x, y1: y } = this;
  var { x2: x, y2: y } = _p2;
  return { x: x1 * x2, y: y1 * y2 };
}

var multiplied = manyPoints.map(multiplyPoints, centralPoint);
```

It's not that common pattern but it gives you the ability to recycle functions as both methods or filters or mappers or forEachers and vice-versa.

I personally use those kind of functions quite a lot to be honest, most developers keep ignoring Array extra second parameter as context though, they probably use a wrapped fat arrow within an IFI with call(context) :D


It seems to me that  we already can quite nicely express in ES6 the use of a function as a method:

```js
function multiplyPoints({x1, y1}, {x2,y2}) {
    return { x: x1 * x2, y: y1 * y2 }
}

class Point {
   multiply(p2) {return multiplyPoints(this, p2)}
}
```

or, perhaps a bit more OO

```js
class Point {
   static multiply({x1, y1}, {x2,y2}) {
      return new Point(x1 * x2, y1 * y2 )  //or new this(...) if you care about subclassing Point
   }

   multiply(p2) {return Point.multiply(this, p2)}

   constructor(x,y) {
      this.x = x;
      this.x = y;
   }
}
```

Regardless of how you express it, if you want the same function to be used both as a standalone function and as an method, you are going to have to have a line or two of code to install the function as a method.  To me, the one-line method definitions used above are about as concise and much clearer in intent than `Point.prototype.multiply=multiplyPoints;` or whatever other expression you would use to install such a function as a method.  And I would expect any high perf JIT to use inlining to completely eliminate the indirection so, where it matters, there probably wound't be any performance difference.

Many JS programmers have historically been confused about the JS semantics of `this` because it is over-exposed in non-method functions. Things like the current proposal increases rather than mitigates the potential for such confusion. if you are programming in a functional style, don't write functions that use `this`.  If you need to transition from to/from OO and functional styles, be explicit as shown above.

`this` is an OO concept.  FP people, `this` is not for you;  don't use it, don't try to "fix it".

But I already am [1][1], and it allows for a much nicer syntax than functions that don't use `this`, and also composes well with built-ins (other than Object.*) This proposal is building on the proposed function bind syntax [2][2].

More examples of the power of the bind syntax can be found in the links, but the bind syntax combined with my proposal would for example allow this:

```JS
function add (&a, b) { return a + b; }

2::add(3) // 5




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Named `this` and `this` destructuring

Andrea Giammarchi-2
the ::bind syntax is OK (I don't really like that double colon 'cause it's not semantic at all with the single colon meaning but I can live with it) but having potential bitwise-like operators around to adress a possible context ... well, I wouldn't probably use/need that in the short, or even long, term.

Again, just my opinion, listen to others ;-)

On Wed, Jun 17, 2015 at 8:40 PM, Jussi Kalliokoski <[hidden email]> wrote:
On Wed, Jun 17, 2015 at 10:35 PM, Andrea Giammarchi <[hidden email]> wrote:
OK **that one** I've no idea what supposes to improve exactly ... I should have tried to realize your proposal better, apologies.

After seeing that, I probably agree with Allen at this point we don't really need that kind of syntax around JS (still IMHO, of course)

To each their own. :) I personally really like the bind syntax and have received a tremendously positive feedback on it - the Trine project alone has received over 1000 stars on GitHub, in under a week since release (last Thursday), and it's just showcasing a part of the power of the proposed syntax.
 

Best Regards

On Wed, Jun 17, 2015 at 6:01 PM, Jussi Kalliokoski <[hidden email]> wrote:


On Wed, Jun 17, 2015 at 7:13 PM, Allen Wirfs-Brock <[hidden email]> wrote:

On Jun 17, 2015, at 8:09 AM, Andrea Giammarchi wrote:

Mostly every Array extra in ES5 would work with those functions, e.g.

```js
function multiplyPoints (_p2) {
  var { x1: x, y1: y } = this;
  var { x2: x, y2: y } = _p2;
  return { x: x1 * x2, y: y1 * y2 };
}

var multiplied = manyPoints.map(multiplyPoints, centralPoint);
```

It's not that common pattern but it gives you the ability to recycle functions as both methods or filters or mappers or forEachers and vice-versa.

I personally use those kind of functions quite a lot to be honest, most developers keep ignoring Array extra second parameter as context though, they probably use a wrapped fat arrow within an IFI with call(context) :D


It seems to me that  we already can quite nicely express in ES6 the use of a function as a method:

```js
function multiplyPoints({x1, y1}, {x2,y2}) {
    return { x: x1 * x2, y: y1 * y2 }
}

class Point {
   multiply(p2) {return multiplyPoints(this, p2)}
}
```

or, perhaps a bit more OO

```js
class Point {
   static multiply({x1, y1}, {x2,y2}) {
      return new Point(x1 * x2, y1 * y2 )  //or new this(...) if you care about subclassing Point
   }

   multiply(p2) {return Point.multiply(this, p2)}

   constructor(x,y) {
      this.x = x;
      this.x = y;
   }
}
```

Regardless of how you express it, if you want the same function to be used both as a standalone function and as an method, you are going to have to have a line or two of code to install the function as a method.  To me, the one-line method definitions used above are about as concise and much clearer in intent than `Point.prototype.multiply=multiplyPoints;` or whatever other expression you would use to install such a function as a method.  And I would expect any high perf JIT to use inlining to completely eliminate the indirection so, where it matters, there probably wound't be any performance difference.

Many JS programmers have historically been confused about the JS semantics of `this` because it is over-exposed in non-method functions. Things like the current proposal increases rather than mitigates the potential for such confusion. if you are programming in a functional style, don't write functions that use `this`.  If you need to transition from to/from OO and functional styles, be explicit as shown above.

`this` is an OO concept.  FP people, `this` is not for you;  don't use it, don't try to "fix it".

But I already am [1][1], and it allows for a much nicer syntax than functions that don't use `this`, and also composes well with built-ins (other than Object.*) This proposal is building on the proposed function bind syntax [2][2].

More examples of the power of the bind syntax can be found in the links, but the bind syntax combined with my proposal would for example allow this:

```JS
function add (&a, b) { return a + b; }

2::add(3) // 5





_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Named `this` and `this` destructuring

Allen Wirfs-Brock
In reply to this post by Jussi Kalliokoski

On Jun 17, 2015, at 10:01 AM, Jussi Kalliokoski wrote:
...
>
> More examples of the power of the bind syntax can be found in the links, but the bind syntax combined with my proposal would for example allow this:
>
> ```JS
> function add (&a, b) { return a + b; }
>
> 2::add(3) // 5
> ```
>
and why that better than:
```js
function add(a,b) {return a+b}

add(2,3);
```

Every new feature increases the conceptual complexity of a language and to justify that it needs to provide a big pay back.  This doesn't seem to have much of a pay back. Adding the & and :: doesn't eliminate the need for JS programmer to learn about `this` in functions for the various already existing ways to call a function with an explicit `this` value.  It just add more new syntax that needs to be learned and remembered are move feature interactions that have to be understood.

JS doesn't need more syntax and semantics piled on to `this`. Ideally some would be taken away.  However, the latter is not possible.

Allen

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Named `this` and `this` destructuring

Jason Kuhrt
In reply to this post by Jussi Kalliokoski
Exactly what Allen said.

Adding syntax to work around a bad feature is an awful idea. We should be trying to reduce and remove usage of `this` by reducing resistance to other ways of programming in JavaScript.

Minimal API Surface areas apply to languages, not just libraries.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Named `this` and `this` destructuring

Jussi Kalliokoski
In reply to this post by Andrea Giammarchi-2


On Wed, Jun 17, 2015 at 10:45 PM, Andrea Giammarchi <[hidden email]> wrote:
the ::bind syntax is OK (I don't really like that double colon 'cause it's not semantic at all with the single colon meaning but I can live with it) but having potential bitwise-like operators around to adress a possible context ... well, I wouldn't probably use/need that in the short, or even long, term.

Again, just my opinion, listen to others ;-)

Ah sorry, my bad, I misunderstood you. :) To clarify, I've only heard positive feedback from people of the bind syntax; as for this proposal, this thread is the first time I hear feedback and it doesn't seem overtly positive. :P
 

On Wed, Jun 17, 2015 at 8:40 PM, Jussi Kalliokoski <[hidden email]> wrote:
On Wed, Jun 17, 2015 at 10:35 PM, Andrea Giammarchi <[hidden email]> wrote:
OK **that one** I've no idea what supposes to improve exactly ... I should have tried to realize your proposal better, apologies.

After seeing that, I probably agree with Allen at this point we don't really need that kind of syntax around JS (still IMHO, of course)

To each their own. :) I personally really like the bind syntax and have received a tremendously positive feedback on it - the Trine project alone has received over 1000 stars on GitHub, in under a week since release (last Thursday), and it's just showcasing a part of the power of the proposed syntax.
 

Best Regards

On Wed, Jun 17, 2015 at 6:01 PM, Jussi Kalliokoski <[hidden email]> wrote:


On Wed, Jun 17, 2015 at 7:13 PM, Allen Wirfs-Brock <[hidden email]> wrote:

On Jun 17, 2015, at 8:09 AM, Andrea Giammarchi wrote:

Mostly every Array extra in ES5 would work with those functions, e.g.

```js
function multiplyPoints (_p2) {
  var { x1: x, y1: y } = this;
  var { x2: x, y2: y } = _p2;
  return { x: x1 * x2, y: y1 * y2 };
}

var multiplied = manyPoints.map(multiplyPoints, centralPoint);
```

It's not that common pattern but it gives you the ability to recycle functions as both methods or filters or mappers or forEachers and vice-versa.

I personally use those kind of functions quite a lot to be honest, most developers keep ignoring Array extra second parameter as context though, they probably use a wrapped fat arrow within an IFI with call(context) :D


It seems to me that  we already can quite nicely express in ES6 the use of a function as a method:

```js
function multiplyPoints({x1, y1}, {x2,y2}) {
    return { x: x1 * x2, y: y1 * y2 }
}

class Point {
   multiply(p2) {return multiplyPoints(this, p2)}
}
```

or, perhaps a bit more OO

```js
class Point {
   static multiply({x1, y1}, {x2,y2}) {
      return new Point(x1 * x2, y1 * y2 )  //or new this(...) if you care about subclassing Point
   }

   multiply(p2) {return Point.multiply(this, p2)}

   constructor(x,y) {
      this.x = x;
      this.x = y;
   }
}
```

Regardless of how you express it, if you want the same function to be used both as a standalone function and as an method, you are going to have to have a line or two of code to install the function as a method.  To me, the one-line method definitions used above are about as concise and much clearer in intent than `Point.prototype.multiply=multiplyPoints;` or whatever other expression you would use to install such a function as a method.  And I would expect any high perf JIT to use inlining to completely eliminate the indirection so, where it matters, there probably wound't be any performance difference.

Many JS programmers have historically been confused about the JS semantics of `this` because it is over-exposed in non-method functions. Things like the current proposal increases rather than mitigates the potential for such confusion. if you are programming in a functional style, don't write functions that use `this`.  If you need to transition from to/from OO and functional styles, be explicit as shown above.

`this` is an OO concept.  FP people, `this` is not for you;  don't use it, don't try to "fix it".

But I already am [1][1], and it allows for a much nicer syntax than functions that don't use `this`, and also composes well with built-ins (other than Object.*) This proposal is building on the proposed function bind syntax [2][2].

More examples of the power of the bind syntax can be found in the links, but the bind syntax combined with my proposal would for example allow this:

```JS
function add (&a, b) { return a + b; }

2::add(3) // 5






_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Named `this` and `this` destructuring

Jussi Kalliokoski
In reply to this post by Allen Wirfs-Brock
On Wed, Jun 17, 2015 at 11:38 PM, Allen Wirfs-Brock <[hidden email]> wrote:

On Jun 17, 2015, at 10:01 AM, Jussi Kalliokoski wrote:
...
>
> More examples of the power of the bind syntax can be found in the links, but the bind syntax combined with my proposal would for example allow this:
>
> ```JS
> function add (&a, b) { return a + b; }
>
> 2::add(3) // 5
> ```
>
and why that better than:
```js
function add(a,b) {return a+b}

add(2,3);
```

Poor example, sorry.

Because of chaining in a way that preservers the natural read order of JS and fitting in well with the builtins:

```JS

flatten(
    items // <- data here
        .filter(isOk)
        .map(toOtherType)
).join(" ");

```

vs.

```JS

items // <- data here
    .filter(isOk)
    .map(toOtherType)
    ::flatten()
    .join(" ");

```


As for fitting in (composing) well with the builtins, for example Trine allows you to do this:

```JS
[["a", "b", "c"], ["e", "f", "g"]]::map([].slice); // yields copies of the arrays
["foo", "bar"]::map("".repeat::partial(3)) // yields "foofoofoo", "barbarbar"
```

because all the functions take data in the `this` slot, as most of the builtins and framework methods do too.
 

Every new feature increases the conceptual complexity of a language and to justify that it needs to provide a big pay back.

I wholeheartedly agree on this, which is why I stated that it might be too early for my proposal.
 
This doesn't seem to have much of a pay back.

Have no comments to that for my proposal. As for Kevin's proposal, I disagree; the payback seems great in that one.
 
Adding the & and :: doesn't eliminate the need for JS programmer to learn about `this` in functions for the various already existing ways to call a function with an explicit `this` value.  It just add more new syntax that needs to be learned and remembered are move feature interactions that have to be understood.

Agreed, however "not having to learn `this`" isn't the goal of either of the proposals mentioned in this thread.
 

JS doesn't need more syntax and semantics piled on to `this`.

Arguably JS hasn't "needed" anything since it became turing complete. That doesn't mean that adding some of the things added since was a bad idea. It's always a tradeoff, but that's nothing specific to this proposal.
 
Ideally some would be taken away.  However, the latter is not possible.

Agree on this too. (As a tangent I'd be curious to know what you'd take away, were it possible?)
 

Allen



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss