Example of real world usage of function bind syntax

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

Re: Example of real world usage of function bind syntax

Jussi Kalliokoski
On Thu, Jun 11, 2015 at 5:31 PM, Kevin Smith <[hidden email]> wrote:
I'm not entirely sure if it's appropriate, but I just published a library called Trine[1] that takes advantage and displays the power of the proposed function bind syntax. Consider this my upvote for the proposal. :)

It's definitely appropriate, as long as it's clear to users that the `::` syntax is experimental, non-standard and subject to change.  This is actually the kind of usage feedback we were hoping to get : )

Great!
 
Has there been any discussion of anyone championing this proposal for ES2016? I would very much like to see it land, especially given that I've already been using it extensively in production via Babel. :P

Not sure you should use it in production, just yet...

It's okay, it's used in a very small product and the worst that can happen is that it will bind (heh) us to a specific version of babel until the syntax is removed from the codebase.
 
I'm the champion for this proposal, and I plan on pursuing it.  I'm not sure that it will fit into the ES2016 timeline though, given the time remaining and other priorities (like async/await).  To be honest, I'm not overly worried about which "train" it leaves on.

Since you brought it up...

I've been considering reducing the scope of the proposal, focusing on the "immediate apply" aspect of the operator, while leaving open the option of adding the other features at a later time.  Specifically, 

- Remove the prefix form of the operator.
- Restrict the syntax such that an argument list is required after the right operand.

In other words, these forms would no longer be valid under the proposal (although they could be re-introduced in another proposal):

    let bf1 = ::obj.foo.bar;
    let bf2 = obj::foo;

But this would still be OK:

    obj::foo(bar);

Given your experience with the operator and your use cases, would you still be in favor of such a minimal proposal?

I see the most benefits in the immediate invocation forms of the proposal, and have used that more extensively than the other forms. However, working with React, I've found that the prefix form is also very nice thing to have for all the ::this.onClick, etc. things. So yes, I would still be in favor, but to me the prefix form is still a pretty cool nice to have.

Looking at the discussion about partial application thought of as a blocker for the syntax, I'd prefer to keep the two separate - for example the proposal I made for partial application [1] is compatible with or without the bind syntax: `foo::bar(qoo, ???)` would be the same as doing `bar.bind(foo, qoo)`.

However, if there's even the remote possibility of getting the non-immediate forms of the bind syntax do a light binding (i.e. always returning the referentially same function), that would be IMO worth blocking the non-immediate forms over to see if it could lead anywhere. Currently as far as I understand, for example React considers all my event listeners changed on every render and removes the listeners and adds them again, because they're bound at render-time.

As a slight offtrack, the slim arrow function would be very handy with this style of programming. ;) Also, one thing I noticed while writing this library is that being able to name `this` might be interesting. Currently even in syntax extensions such as flow, there's no natural way to type annotate `this` in standalone functions. However, say we had a syntax like this:

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

Where the `this` argument would be accessible in the a parameter, it could be simply type annotated as

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

Regarding polymorphism, I don't think the bind syntax changes things much, it just (possibly) makes polymorphism happen more at the `this` slot. Also, I wonder if in the case of the bind operator the engines could actually hold an inline cache in the shape of the object instead of the function itself. I'm also uncertain if the engines currently consider things such as

function getFromUnknownType (key, value, has, get) {
  if ( has(key) ) { return get(key); }
  return null;
}

polymorphic or if they're able to statically verify that actually the types in there remain the same regardless of the type of the `key` and `value` passed in (unless the passed functions are inlined of course).

I wouldn't be *too* worried about polymorphism though, since the advantages of the syntax allow us to "add" methods to iterables, which means we can do

products
  ::quickSort(function (b) { return this.price - b.price; })
  ::head(k);

versus

products
  .sort(function (a, b) { return a.price - b.price; })
  .slice(0, k);

which is a difference of O(kn) versus O(n²) in worst case time complexity.

- Jussi
 

Thanks!


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

Re: Example of real world usage of function bind syntax

Jussi Kalliokoski
On Fri, Jun 12, 2015 at 8:35 AM, Jussi Kalliokoski <[hidden email]> wrote:
On Thu, Jun 11, 2015 at 5:31 PM, Kevin Smith <[hidden email]> wrote:
I'm not entirely sure if it's appropriate, but I just published a library called Trine[1] that takes advantage and displays the power of the proposed function bind syntax. Consider this my upvote for the proposal. :)

It's definitely appropriate, as long as it's clear to users that the `::` syntax is experimental, non-standard and subject to change.  This is actually the kind of usage feedback we were hoping to get : )

Great!
 
Has there been any discussion of anyone championing this proposal for ES2016? I would very much like to see it land, especially given that I've already been using it extensively in production via Babel. :P

Not sure you should use it in production, just yet...

It's okay, it's used in a very small product and the worst that can happen is that it will bind (heh) us to a specific version of babel until the syntax is removed from the codebase.
 
I'm the champion for this proposal, and I plan on pursuing it.  I'm not sure that it will fit into the ES2016 timeline though, given the time remaining and other priorities (like async/await).  To be honest, I'm not overly worried about which "train" it leaves on.

Since you brought it up...

I've been considering reducing the scope of the proposal, focusing on the "immediate apply" aspect of the operator, while leaving open the option of adding the other features at a later time.  Specifically, 

- Remove the prefix form of the operator.
- Restrict the syntax such that an argument list is required after the right operand.

In other words, these forms would no longer be valid under the proposal (although they could be re-introduced in another proposal):

    let bf1 = ::obj.foo.bar;
    let bf2 = obj::foo;

But this would still be OK:

    obj::foo(bar);

Given your experience with the operator and your use cases, would you still be in favor of such a minimal proposal?

I see the most benefits in the immediate invocation forms of the proposal, and have used that more extensively than the other forms. However, working with React, I've found that the prefix form is also very nice thing to have for all the ::this.onClick, etc. things. So yes, I would still be in favor, but to me the prefix form is still a pretty cool nice to have.

Looking at the discussion about partial application thought of as a blocker for the syntax, I'd prefer to keep the two separate - for example the proposal I made for partial application [1] is compatible with or without the bind syntax: `foo::bar(qoo, ???)` would be the same as doing `bar.bind(foo, qoo)`.

Forgot to mention that Trine actually implements the placeholder syntax I proposed: parseInt::partial(_) // returns a unary version of parseInt
 

However, if there's even the remote possibility of getting the non-immediate forms of the bind syntax do a light binding (i.e. always returning the referentially same function), that would be IMO worth blocking the non-immediate forms over to see if it could lead anywhere. Currently as far as I understand, for example React considers all my event listeners changed on every render and removes the listeners and adds them again, because they're bound at render-time.

As a slight offtrack, the slim arrow function would be very handy with this style of programming. ;) Also, one thing I noticed while writing this library is that being able to name `this` might be interesting. Currently even in syntax extensions such as flow, there's no natural way to type annotate `this` in standalone functions. However, say we had a syntax like this:

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

Where the `this` argument would be accessible in the a parameter, it could be simply type annotated as

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

Regarding polymorphism, I don't think the bind syntax changes things much, it just (possibly) makes polymorphism happen more at the `this` slot. Also, I wonder if in the case of the bind operator the engines could actually hold an inline cache in the shape of the object instead of the function itself. I'm also uncertain if the engines currently consider things such as

function getFromUnknownType (key, value, has, get) {
  if ( has(key) ) { return get(key); }
  return null;
}

polymorphic or if they're able to statically verify that actually the types in there remain the same regardless of the type of the `key` and `value` passed in (unless the passed functions are inlined of course).

I wouldn't be *too* worried about polymorphism though, since the advantages of the syntax allow us to "add" methods to iterables, which means we can do

products
  ::quickSort(function (b) { return this.price - b.price; })
  ::head(k);

versus

products
  .sort(function (a, b) { return a.price - b.price; })
  .slice(0, k);

which is a difference of O(kn) versus O(n²) in worst case time complexity.

- Jussi
 

Thanks!



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

Re: Example of real world usage of function bind syntax

Isiah Meadows
In reply to this post by Isiah Meadows

Yeah, I am. Oops. Sorry about that.


On Fri, Jun 12, 2015, 13:41 Brendan Eich <[hidden email]> wrote:
Any chance you could reply so that your messages show up in thread? Are
you reading by digest mode, possibly?

/be

Isiah Meadows wrote:
> I need to be using this library! I, myself, used the syntax for
> virtual methods quite a bit, and personally replicated a third of your
> library without realizing it. Also, it's a lot easier and nicer to
> type `foo.map(::this.bar)` than `foo.map(this.bar.bind(this))` or
> `foo.map(x => this.bar(x))`. I also (ab)used it to create my own DSL
> for conditionals that would be equivalent to a condition-less `switch`
> in CoffeeScript and the like, but that was more of an experiment than
> anything else.
>
>     ---------- Forwarded message ----------
>     From: Jussi Kalliokoski <[hidden email]
>     <mailto:[hidden email]>>
>     To: es-discuss <[hidden email]
>     <mailto:[hidden email]>>
>     Cc:
>     Date: Thu, 11 Jun 2015 15:19:28 +0300
>     Subject: Example of real world usage of function bind syntax
>     I'm not entirely sure if it's appropriate, but I just published a
>     library called Trine[1] that takes advantage and displays the
>     power of the proposed function bind syntax. Consider this my
>     upvote for the proposal. :)
>
>     Has there been any discussion of anyone championing this proposal
>     for ES2016? I would very much like to see it land, especially
>     given that I've already been using it extensively in production
>     via Babel. :P
>
>     [1] https://github.com/jussi-kalliokoski/trine
>     _______________________________________________
>     es-discuss mailing list
>     [hidden email] <mailto:[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
12