TypeScript support for ES Next pipeline operator
github.com
github.com
I’ve always wanted a clojure style thread operator [1] in other languages :)
In Clojure, the threading macros are awesome and they are not even a language construct, just some ~10 lines of code per macro! [1]
In ML, the pipe operator is even shorter:
`let (|>) x f = f x`
1: https://github.com/clojure/clojure/blob/4ef4b1ed7a2e8bb0aaaa...Fortunately the simple version is easily approximated, I have this sprinkled in various files where it's useful:
const pipeline = (val, ...funcs) => funcs.reduce((a, b) => b(a), val);
[1] https://babeljs.io/blog/2018/07/19/whats-happening-with-the-... handleChange = e => this.setState({ value: e.currentTarget.value })I can't imagine that there would EVER be a good reason not to have a method bound to the class. Now we've all been forced to learn this new property initializer syntax and add yet another babel dependency to facilitate it.
And if you've got a list of tens or hundreds of items, and you want a click handler for each, you quickly get to the point where all the extra overhead matters.
Like, for instance, in a React render function you could have
{things.map(thing => {
return <Thing onClick={e => this.handleClick(thingId) } />
})}
or {things.map(thing => {
return <Thing onClick={this.handleClick.bind(this, thingId)} />
})}
But option #1 would be a lot less efficient if you've got lots of things, since it's creating a new closure that calls the instance method instead of just pointing at the instance method like snipper #2 does.I still see lots of people recommending #1 for this exact scenario, though. Maybe I'm just wrong, or maybe stuff like this is why I see so many SPAs consuming shocking amounts of memory.
I grant that using the fat arrow is probably fine for the scenario you mentioned though, with something like a text field. I don't think I've seen many pages with so many text fields that the extra overhead would even make a difference.
To avoid it, you can do (sorry for bad formatting):
class Thing extends React.Component {
handleClick = (thingId) => {
this.setState(/*stuff*/);
}
render() {
return <div>{things.map(thing => <Thing onClick=
{this.handleClick} />)}</div>
}
}
You can also bind handleClick inside the constructor without the arrow. constructor(...args) {
super(...args);
this.handleClick = this._handleClick.bind(this);
}
_handleClick(thing) {
// stuff
}It gradually got simplified but nobody could agree about the behaviour of if this would _just work_ with existing functions via the `this` or the first argument, I think eventually the proponents if it grew tired of the battle, they couldn't get unified support for one way or the other.. interesting the pipeline operator has basically gone through the exact same issues, but seems to have had much more attention to it.
Ultimately I believe the bind operator was just too soon, generally at the time people were still trying to come to terms with what was a lot of new syntax coming to javascript, as well as react and similar things, now I think these chaining operators make a lot more sense to a lot more people.
@autobind
handleClick: () -> { return this.member }
The whole binding in the constructor seems like needless noise to meAnyway, which style do you prefer?
const foo = pipeline(
bar,
baz,
x => x + 1,
)
foo(42) pipeline : (...fns : Function[]) => FunctionDon't get me wrong, I'm super excited for this functionality because I love it in languages like F# and Elixir, but it looks like the pipe proposal is still stage 1.
So, first the runtimes/compilers implement it and then it gets into the spec.
TypeScript sees itself as a superset of ECMAScript, so its ECMAScript parts are just another implementation of the spec, like Node, Babel and the browser engines.
Yes, this appears to be just a tracking issue, not an impending implementation (and definitely not a PR). The "Waiting for TC39" label added even has the tooltip "Unactionable until TC39 reaches some conclusion".
All of the new syntax is technically optional, but at least some percentage of it just makes it easier for newer/less-experienced devs to write things: e.g. classes as simplified syntactic sugar around prototype-based inheritance models, or function parameter spread operators to make learning how to arguments.whatever unnecessary and generally make code for dynamic argument lengths easier to understand.
No matter when you started learning Javascript there would have been parts too complex or obscure to learn immediately (the prototype-based inheritance model is something I think a lot of full-time professional JS devs don't fully grok). There was always things you learn first and things you learn later. With the new syntax, I think now the things* you learn first are just more likely to be immediately useful.
* where "things" excludes learning how to master every trending new library—that is a part of Javascript that isn't improving unfortunately.
Those are incredibly powerful, and as a lot to the language, whereas this just seems like fairly simple syntactic sugar.