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

What is this for? #30

Closed
jonathanKingston opened this issue Jan 2, 2016 · 12 comments
Closed

What is this for? #30

jonathanKingston opened this issue Jan 2, 2016 · 12 comments

Comments

@jonathanKingston
Copy link

As I stated in another thread: #23 (comment)

Can play devils advocate and ask based purely on all of this discussion is it really worth being added to the language (The discussion indicates developer cognitive load when being used)?
As much as I syntactic sugar can be useful there isn't much this adds that a simple function could. This would add an extra function call in the expression though.

Some explanation here:
https://gist.github.com/jonathanKingston/4df71289a2cd8dd8306a

And also: #23 (comment)

The proposal isn't invalidated by having functional equivalents in current Javascript.

I agree totally as functionally most new features can be written in JavaScript pretty simply with the exception of features like Workers and Crypto.

But this is all besides the point — the proposal is about developer ergonomics, isn't it?

I agree also, I'm worried however that we end up with more operators used that languages like Perl which are often criticised in having far too many operators making the language harder to read like lengthy RegEx.
I'm also aware of the argument "if you don't want it - don't use it", I'm not sure how much that helps personally.
I would much rather browsers concentrate on fixing current hard issues like for example RegEx character classes which requires large libraries to use: http://xregexp.com/plugins/

Again sorry for playing devils advocate etc 😅

Can we carry on this discussion here?

@nmn
Copy link

nmn commented Jan 2, 2016

While I personally would really like the idea of a pipeline operator, there is something to be said about language simplicity.

Further, a pipeline operator can be achieved by piggy-backing on the :: proposal.

usually ::methodName() is passed the argument as this. This can simply be fixed with a simple function.

function pipe(fn, ...vals){
  return fn(this, ...vals)
}

Now, |> fnName can be replaced with ::pipe(fnName)

value
  ::pipe(fn)
  ::pipe(fn2)

Now, while it adds some extra junk to deal with and probably has some run-time cost, it does side-step the many outstanding issues with this proposal. This works today with babel, and side-steps many of the parsing issues around other operators.

@igl
Copy link

igl commented Mar 16, 2016

For the case of language simplicity i favor |> over ::.
For cognitive load i would also favor |> since many other functional languages have function composition operators while :: is something i have not seen before.

I keep coming back to wanting this in JS.
Any time i have to create a pointless intermediate variable or count braces while refactoring.

@nmn
Copy link

nmn commented Mar 16, 2016

@igl I prefer |> to :: too. But currently the :: proposal has way more traction.

@stormpat
Copy link

The biggest issue i have with :: is the fact that is more complex, and uses this. I think the benefits gained from |> would be more inline with where javascript development seems to be heading, a easy way to do more functional style of programming, and encouraging side-effect free functions.

@nmn The bind proposal predates the pipe proposal, but as for traction (both proposals starred almost equally on GH) i think the pipe operator could win. Just need some marketing. Could be big if some of the bigger library authors started promoting it.

@igl
Copy link

igl commented Mar 17, 2016

Contact your congressman lobbyist now!

@barneycarroll
Copy link

FWIW after eagerly adopting :: months ago and being initially dubious of |> as too close to something which I was treating as de facto implemented (the Babel delusion), I've found that the bind operator has very limited legitimate use cases, while suggesting roundabout hacks to fulfil what the pipe operator does.

IMO the bind operator is a deceptive band aid on the zombie corpse of Javascript OO APIs. While appearing in the abstract to offer a less restrictive and more flexible way of dealing with objects in a way that superficially 'feels' legit to the OOP aesthetic, in practice the subject::verb( object ) grammar does not produce inherently more reasonable code — in fact its rigid signature suggests unreliable semantics while allowing for all sorts of convoluted usage. You end up with the kind of API that OOP advocates will end up writing presentations about purely on the basis of 'best practice'.

Pipe operator is far more flexible, has no pretentions of 'intended usage', and reads better. The lack of implicit abstract semantics makes it less liable to encourage bad derivative code too.

@egeozcan
Copy link

I implemented piping with a little syntax overhead, here: https://github.com/egeozcan/ppipe

Any thoughts?

@nmn
Copy link

nmn commented May 12, 2016

@egeozcan your project inspired me to try to do the same. My solution is tiny in comparison, and I like its simplicity:

var p = (value) => (fn) => fn ? pipe(fn(value)) : value

/* eslint-disable */
p(2)
  (add1)
  (square)
  (n => n/3)
  () // 3

// OR to make it look more like an operator.
p(2
  )( add1
  )( square
  )( n => n - 2
  )() // 7

IMO handling promises should be external. So, something like this:

const wait = (fn) => (val) => val instanceof Promise ? val.then(fn) : fn(val)

// Now..
p('cats'
  )( n => 'funny ' + n
  )( fetchGifUrl
  )( wait(createImg)
  )() // <img src='funny-cat.gif' />

@jasmith79
Copy link

Much as I appreciate your efforts, there are existing solutions if one is willing to endure syntactic overhead...
http://ramdajs.com/docs/#pipe

@egeozcan
Copy link

egeozcan commented May 12, 2016

@nmn cool! actually returning the value when no arguments passed is a good great idea!

@jasmith79 I use ramda very often, but those didn't cover my needs. I'm passionate about mixing normal functions and promise factories. Also, the lack of composability of a single function call and the unary requirement with no way to decide how to pass the results... I agree that mine is a bit hacky but it's more like "this is what I need, and I'd love to have some convenient syntax around this" - definitely not a library to rule them all =)

@jasmith79
Copy link

jasmith79 commented May 12, 2016

@egeozcan

const bindP = fn => promise => promise.then(value => fn(value));

Apply it to any function to turn it into one that accepts and returns Promises. Or you could define fmap over Promises. But yes, I could see how Ramda would not meet every need for sure.

@littledan
Copy link
Member

I agree that we probably just want one of |> and ::. We discussed the alternatives and the motivation for this proposal at the September 2017 TC39 meeting. The proposal is still at Stage 1, so it might be excluded for these motivation reasons. I'm not sure what more to discuss here, so closing the issue for now.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 24, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants