Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support proposed ES Next "::" bind operator #3508

Closed
loucyx opened this issue Jun 14, 2015 · 78 comments
Closed

Support proposed ES Next "::" bind operator #3508

loucyx opened this issue Jun 14, 2015 · 78 comments
Labels
ES Next New featurers for ECMAScript (a.k.a. ESNext) Revisit An issue worth coming back to Suggestion An idea for TypeScript Waiting for TC39 Unactionable until TC39 reaches some conclusion

Comments

@loucyx
Copy link

loucyx commented Jun 14, 2015

Edit from @DanielRosenwasser: Since this issue was filed, a separate proposal for :: was created called "extensions".

https://github.com/tc39/proposal-extensions


It will be great if TypeScript had an implementation of the "::" bind operator of ECMAScript 7. Some examples of this operator and the implementation in ES5:
Bind

// ES5
var log = console.log.bind(console);

// ES7
let log = ::console.log;

Call

// ES5
var forEach = Array.prototype.forEach,
    elements = document.querySelectorAll("div");

forEach.call(elements, div => { console.log(div); })

// ES7
let forEach = Array.prototype.forEach,
    elements = document.querySelectorAll("div");

elements::forEach(div => { console.log(div) });

[ref] [more examples]

@DanielRosenwasser DanielRosenwasser added Suggestion An idea for TypeScript ES7 Relates to the ES7 Spec labels Jun 15, 2015
@DanielRosenwasser
Copy link
Member

I keep seeing this being called an ES7 operator. The strawman proposal has been up on the wiki for quite a while, but I don't see any proposal for it right now. I've tentatively marked this issue as ES7 anyway, but perhaps someone else can weigh in on this.

@kitsonk
Copy link
Contributor

kitsonk commented Jun 15, 2015

They implemented it in Babel but even they say it is highly experimental. While it might be a good idea, it is far away from being a standard and no runtime has implemented it.

@sebmck
Copy link

sebmck commented Jun 15, 2015

@DanielRosenwasser It was discussed at the March TC39 meeting (notes here). AFAIK it isn't being actively proposed as more feedback is required (The Babel implementation is a part of that feedback process).

@ivogabe
Copy link
Contributor

ivogabe commented Jun 15, 2015

I think this is the best way to implement extension methods (#9), since with this proposal the emit isn't based on type info.

Also this will (partially) solve #212 (bind, call & apply are untyped), since we can use the :: operator to bind methods:

// Bind
func.bind(obj);
obj::func;

// Call
func.call(obj, 42);
obj::func(42);

// Apply
func.apply(obj, arr);
obj::func(...arr);

We don't need bind, call and apply any more if we use the bind operator. The only missing feature of the bind operator would be currying, but I'm not sure whether that's used a lot. Personally I'm not using it.

Besides that, maybe we can emit a function expression instead of a bind call. Using bind() isn't good for performance and it isn't supported in ES3. I've written some code that could be generated. I've added temporary variables as the expression (console.log in this example) should be evaluated once I guess. My vote would be for the function expression / lambda approach.

// Source
foo = ::console.log;

// .bind (ES5, 6)
foo = (_a = console, _a.log.bind(_a));
var _a, _b;

// lambda (ES6)
foo = (_a = console, _b = _a.log, (...args) => _b.apply(_a, args));
var _a, _b;

// Function expression (ES3, 5)
foo = (_a = console, _b = _a.log, function() { _b.apply(_a, arguments); });
var _a, _b;

About function expression, I'm not sure whether .apply() accepts an ArrayLike, so we might need to wrap arguments inside Array.prototype.slice.call() to convert it to an array.

Since this feature is not standardized yet, we could add it first under an --experimentalBind flag.

@HerringtonDarkholme
Copy link
Contributor

I personally think supporting a new feature without type safety is desirable. FYI, #1985

@filipstachura
Copy link

Here is more detailed description of the bind operator strawman:
https://github.com/zenparsing/es-function-bind

I must say that syntax proposed by Trine (https://github.com/jussi-kalliokoski/trine) looks way better than anything I saw before. I would love to write code in such functional form.

@RyanCavanaugh RyanCavanaugh added the In Discussion Not yet reached consensus label Jun 29, 2015
@rbuckton
Copy link
Member

rbuckton commented Jul 9, 2015

This feature would work well with an ability to specify the type of this in a function declaration (#229).

@Artazor
Copy link
Contributor

Artazor commented Aug 3, 2015

@rbuckton are there any chances to parse the following syntax: #1985 (comment) ?

@RyanCavanaugh RyanCavanaugh added Revisit An issue worth coming back to and removed In Discussion Not yet reached consensus labels Aug 5, 2015
@RyanCavanaugh
Copy link
Member

Our policy on ES7 features is to wait until they're in Stage 1. Someone should chime in here when that happens for this feature.

@loucyx
Copy link
Author

loucyx commented Aug 5, 2015

Great @RyanCavanaugh ! ... I'll try to check daily until is on Stage 1 :)

@mhegazy
Copy link
Contributor

mhegazy commented Sep 16, 2015

related to #3694

@basarat
Copy link
Contributor

basarat commented Sep 18, 2015

Note : @rbuckton has done some work on this : 8521632 (mentioning it for community knowledge 🌹)

@donaldpipowitch
Copy link
Contributor

Looking forward to this. I hope this will become the de facto standard how future libraries like Lodash will work so we can do this [ 1, 2, 3, 4].map(i => i * i)::chunk(2); instead of something like _.chunk or Array.prototype.chunk.

@rbuckton
Copy link
Member

The problem with :: is that there's disagreement on how it should work. One camp believes that the left-hand side of the :: operand should be provided as the this value to the function on the right-hand side. Another camp believes it should be provided as the first argument, to be compatible with existing libraries like lodash, etc. I chose to implement :: using the same semantics as Babel; however, we could both be wrong by the time this feature reaches Stage 2.

@basarat
Copy link
Contributor

basarat commented Sep 22, 2015

Note that the implementation done is : provided as the first argument. Of course lets wait for the spec to finalize.

@donaldpipowitch
Copy link
Contributor

My number one use case for :: are future forward polyfills which can change and therefor shouldn't pollute prototype. E.g. I'd like to go to MDN and take any polyfill (like map) and it should behave in the same way with :: or without (say [].map === []::map).

Like:

  1. We want to polyfill an unstable spec → use foo::polyfilledFunctionBar.
  2. We want to polyfill a stable spec → use foo.polyfilledFunctionBar.
  3. Switch to the native implementation, if available → use foo.nativeFunctionBar.

@jods4
Copy link

jods4 commented Oct 15, 2015

@basarat

Note that the implementation done is : provided as the first argument.

but @rbuckton said

I chose to implement :: using the same semantics as Babel

Babel is (currently) providing the left-hand side as this so I find basarat's precision rather confusing.
Looking at the code it seems to me that TS currently binds to this.

@basarat
Copy link
Contributor

basarat commented Oct 15, 2015

Babel is (currently) providing the left-hand side as this so I find basarat's precision rather confusing.
Looking at the code it seems to me that TS currently binds to this.

@jods4 You are right : TypeScript and also the babel version both work by binding this.

Don't know why I read it wrong. Sorry 🌹

@sebmck
Copy link

sebmck commented Oct 16, 2015

Just to clear things up. The semantics are not "Babel" or "TypeScript". They're what are included in the current proposal.

@prabirshrestha
Copy link
Member

What about supporting this feature under an experimental flag similar to experimentalDecorators? Would really love to start using this feature in TS.

In order to support either this or the first arg a flag similar to --jsx react/preserve could be used.
--experimentalBind arg/this.

@tejacques
Copy link

I'd love to have this in under an experimental flag. If the TypeScript team would be open to that I think it's very likely the community would assist with the feature.

I know that this feature would be incredibly useful to RxJs as well as providing an extremely nice and intuitive way of dealing with extension methods.

@kitsonk
Copy link
Contributor

kitsonk commented Nov 12, 2015

I think the desire to keep things that haven't progressed far enough in the TC39 stages is wise, because you never know when the rug will get pulled out from you.

@jeffbcross
Copy link

We could really use this feature on Angular and RxJS-Next. More so for users' benefit than for the frameworks themselves, so we can encourage users to use Observable operators as functions instead of having a large Observable prototype.

@kitsonk
Copy link
Contributor

kitsonk commented Nov 14, 2015

Best to rally the troops in TC39 then...

@bloadvenro
Copy link

@Yogu Aaah, now I see, thank you!

@kbtz
Copy link

kbtz commented Aug 10, 2017

Apparently this is the only issue mentioning the pipeline operator. Could we have a thread for this operator specifically to keep track of its status on TS?!

@graingert
Copy link

@cvsguimaraes #17718

@mhegazy
Copy link
Contributor

mhegazy commented Jul 30, 2018

Closing this issue. The :: operator proposal is not active any longer, #17718 tracks the pipeline |> operator proposal.

@schibrikov
Copy link

@mhegazy according to tc39 it is active and still stage-0.
Why is it closed?
This issue prevents transition to TS for me (operator is widely presented in the codebase) and I would like to reopen it.

@graingert
Copy link

@sHooKDT you should run Babel with only the bind operator plugin enabled on your source, and save the output over the top

@schibrikov
Copy link

@sHooKDT you should run Babel with only the bind operator plugin enabled on your source, and save the output over the top

Yes, I tried today, but I'm not sure how to do this. Without other plugins like decorators babel is unable to parse my sources. I would be glad if you help me ;)

Anyway, the main point is not my transition, but the proposal that is still active. I see no reasons to close this now.

@ljharb
Copy link
Contributor

ljharb commented Jan 22, 2019

It would be a mistake for TS to add support for any feature prior to stage 3 - decorators and class fields being prime examples of why it’s a bad idea.

@DanielRosenwasser
Copy link
Member

We'll revisit this if the proposal proceeds to stage 1.

@DanielRosenwasser DanielRosenwasser added Revisit An issue worth coming back to Waiting for TC39 Unactionable until TC39 reaches some conclusion and removed In Discussion Not yet reached consensus labels Jan 23, 2019
@microsoft microsoft locked and limited conversation to collaborators Jan 23, 2019
@DanielRosenwasser
Copy link
Member

Since locking this, https://github.com/tc39/proposal-extensions has reached stage 1. We still will not ship anything like this at stage 1, but I'll try to keep my word and reopen this issue for discussion.

If all we get are comments about when we're planning to ship the feature, I will lock the issue again, so please keep the conversation constructive

@RyanCavanaugh
Copy link
Member

Closing since there's nothing to do until TC39 gets this to Stage 3

@RyanCavanaugh RyanCavanaugh closed this as not planned Won't fix, can't repro, duplicate, stale Mar 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ES Next New featurers for ECMAScript (a.k.a. ESNext) Revisit An issue worth coming back to Suggestion An idea for TypeScript Waiting for TC39 Unactionable until TC39 reaches some conclusion
Projects
None yet
Development

No branches or pull requests