Although I expect you're presenting a contrived example, I find that syntax horrible. In your example it provides no additional value, and requires more typing. And more thinking to parse.
The partial application operator clearly wins over bind, IMO, which is currently the way you'd do that [ addTwo = add.bind(this, 2) ] if only because you don't need to specify the this parameter. It also gives the option to "bind" to other parameters than the leftmost.
The pipeline operator in that example is a little contrived, but coming from any functional background it makes a ton of sense. Depending on what I was piping, I might also format it more like:
x = 5
|> addTwo
|> add(?, 10)
...which would probably resonate with anyone used to promise chains: x = Promise.resolve(5)
.then(addTwo)
.then(add(?, 10)) // or v => add(v, 10)
It's still contrived, but it is a reasonably familiar flow in JS. It would also clean up async/await syntax a lot assuming they could be used together: x = await foo(await bar(2, await baz(3)))
...becomes... x = await baz(3)
|> await bar(2, ?)
|> await foo(?)
...which honestly is a more accurate representation of what's happening.In JS you can do stuff like this:
const rules = parsedTags
.split(';')
.map(item => item.trim())
.filter(item => !!item);
But in some functional languages you would have to do something like this: Array.filter(Array.map(String.split(parsedTags, ';'), item => String.trim(item)), item => !!item);
Which makes it a lot more difficult to write/understand. (Note the order in which the functions will be called).With a pipe operator you can do something like this:
parsedTags
|> Array.split(';')
|> Array.map(item => String.trim(item))
|> Array.filter(item => !!item);
Now that people are writing more functional JS, a pipe operator becomes much more useful since you can't always chain function calls like the JS example above.