Example of real world usage of function bind syntax

Jussi Kalliokoski jussi.kalliokoski at gmail.com
Fri Jun 12 05:35:50 UTC 2015


On Thu, Jun 11, 2015 at 5:31 PM, Kevin Smith <zenparsing at gmail.com> 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


[1] https://esdiscuss.org/topic/syntax-sugar-for-partial-application


>
> Thanks!
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150612/2d356021/attachment-0001.html>


More information about the es-discuss mailing list