-
Notifications
You must be signed in to change notification settings - Fork 107
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
Alternative implementation idea using comma operator. #308
Comments
I have no idea reason to have it and we have already function foo() {
return (console.log('hi'), 1)
}
const result = foo() // output console log: 'hi'; result = 1 If you want |
I listed a few benefits in the OP, but I would be happy to answer any specific questions that you have. Also I am aware of the comma operator already, as I used it several times in the OP as well as explicitly referencing "the existing comma operator." |
I'm not sure about the benefits of this proposal, but it got me thinking though... What if... actionUri
|> %.tolower()
|> baseUri + %
|> await fetch(%)
|> JSON.parse(%) Would be similar to (let $= actionUri
,$= $.tolower()
,$= baseUri + $
,$= await fetch($)
,$= JSON.parse($)
) Not that much more noise if you ask me... Also you can use your own topic token as long as it can be an identifier. |
@Jopie64 I think it wouldn't work well with TypeScript as |
@Jopie64 That is what I'm proposing. I'm just using the |> operator to make the syntax closer to F# and reduce boilerplate. |
What exactly you mean by "achieving the pipeline functionality"? I'm asking because
|
This would become
Technically it does not. But, because the variables are scoped to the expression, you could just name them all |
Why not just use the comma operator as the pipe operator? It already has nearly the same semantics as the pipe, except for the ability to "refer to the previous value". Then the only tweak to ECMAScript would be allowing I.e.: would become:
Seems a lot more palatable to me to build off of the existing syntax like this than introducing two new operators. |
I don't think it's palatable at all to reuse the verboten comma operator, personally. |
Yes that is what I am suggesting. There is only one new operator, the |
That's the beauty of this idea. The comma operator is verboten because it can only be used to do questionable things. This feature would allow it to be useful for something. |
@ljharb I somewhat agree, but I do think it would be more palatable than introducing two new operators when one of them (halfway) already exists. 50% of the reason comma is verboten is that its existing use-cases are not compelling enough to merit usage. Perhaps that would change if its semantics became slightly more powerful. @haydenlauer I see, however I think it would be pretty verbose without that extra const c1 = d(1), b1 = c(c1), a1 = b(b1, 3);
const result = a(a1) (which doesn't actually use the comma operator at all, since we are just doing multiple assignments on one line). What I'm saying is that if the comma operator were augmented with the additional power of const result = (d(1), c(%), b(%, 3), a(%)) |
I don’t think it’s better to take something with a harmful meaning and give it an additional beneficial one. |
@ljharb but the only harm in its current meaning is its lack of being compellingly beneficial. If you consider the existing semantics of the comma operator harmful, then by extension, the semantics of any pipe operator would be at least as harmful since it would include all the semantics of the comma operator, plus additional semantics. Or do you mean harmful syntax? I could possibly get behind an argument for harmful syntax, but then again, that's what linters are for. |
My two cents: I like the fact that this idea, |
It also seems to work vertically. getPersistedJWT()
, Maybe.fromNullish(%)
, Maybe.chain(%, decodeJWT)
, TaskEither.fromMaybe(%, new AuthenticationError())
, TaskEither.chain(%, fetchUser)
, TaskEither.chain(%, persistUser)
, TaskEither.mapLeft(%, resolveToToastMessage)
, TaskEither.do(%, showToast, navigateToProfile) |
Another bonus of comma: it would leave the Comma on the other hand seems very naturally suited to the hack-style, since that's what it already does. If that eventuality ever came to pass, we could have the "smart mix" without any of the syntactic ambiguity concerns inherent in having one operator do both things. I'd imagine this would get the anti-hacktivists who moved into the "do nothing" camp back on board, since now we are talking about an extremely tiny tweak to the language for the hack style--not even really a "new" language feature in my book, just a tiny enhancement to a previously worthless feature to provide insane value! Heck, this comma idea has even got someone like myself who originally hated both proposals (no offense) very intrigued. There is nothing more satisfying than repurposing trash (i.e., the comma operator) as art :) It's like when ASCII eventually grew wings and metamorphosed into the breathtaking UTF-8, as if that had been its plan all along. Pure elegance ❤️ |
You could possibly even generalize this idea, and say that the chosen "topic token" simply returns the value of the last executed expression in the same scope, in similar fashion to how EDIT: hm I guess that'd complicate something like |
I'm going to go ahead and close this. We're not interested in pursuing a comma operator for this functionality. Jordan has given some of the reasoning already (the comma operator is already generally a bad part of the language), and the awkward interaction of it with arglists, array literals, object literals, etc. is another. |
@tabatkins I did consider that there would be some syntactic ambiguities to the idea (albeit no less than what already exists), but figured that all such ambiguities could easily be resolved in the worst-offending cases via explicit parentheses. Personally not a huge fan of adding 2 new operators to the language for one convenience feature when 1 out of those 2 already exists with virtually identical semantics (only real difference being operator precedence 1 level offset from initially proposed, so yes more parentheses)... but, oh well 😕 |
The math here isn't as simple as "count the operators". 2 operators isn't inherently worse than 1, if it ends up with a better DX outcome. |
It would be helpful to elaborate on exactly how the DX could be worse. We have some well-described pros in this issue, but the cons are not clear, at least to me. |
@ljharb I don't think my sentiment is quite as superficial as you make it out to be--but every new operator does add a tax of sorts on the language, so the number of new operators added per feature is certainly something to be conscious of. Especially when there is an existing operator that already performs the same function. Would the DX really be so negatively affected by augmenting the existing one that it would outweigh the disadvantage of adding a new operator to do the same thing? I'm somewhat skeptical of the claim that it would. To my mind, there are 2 possible cases here where there is surface area for ambiguity:
So in summary, I'd echo @gustavopch's slight confusion as to what the most significantly disadvantageous cons you see would be. |
2 different syntaxes that do the same thing immediately indicates poor design. It's not a good idea to complicate the syntax without a real need. C++ has already proved it. |
Note to casual passers-by: the proposal in the issue description does not represent the syntax we are now discussing. The original issue suggests a syntax that nearly everyone here agrees is a bad idea. Would it be worth opening a new issue to discuss the subsequent proposal, starting at this comment, to ensure it gets a fair shake with all the pros and cons listed before being closed? I worry that the later idea has not received due consideration (possibly in part from the clutter/confusion of the context of the original issue description). |
@HansBrende I was thinking the same thing. IMO, it would be great if you could open a new issue summarizing the points that are actually relevant to avoid confusion. If possible, pass it through o1 and Sonnet 3.5 to further scrutinize the idea (like, ask them to behave as TC39 members) so that the new issue can immediately contain as much consideration as possible about pitfalls and pain points, including examples of real-world usage. To be clear: I'm not saying this idea must be pursued, I just think pros and cons should be clear before it's dismissed, even if only for historical and documentation purposes. |
@gustavopch glad for the positive feedback! I will begin crafting this issue later in the week if I do not hear objections from those with close privileges. (As, I wouldn't want to invest that amount of time into composing such a document if it would result in another quick closure without allowing the community a "clean-slate" opportunity to examine more deeply the relative benefits and specific, tangible, & precise drawbacks of the proposal.) |
Instead of making a pipeline operator we make an expression-scoped variable assignment operator, and then use the comma operator to achieve the pipeline functionality. I think this may give us the best of both worlds.
This lets you name variables like the F# style but also lets you use arbitrary expressions like the hack style. As an added benefit, you can access any previously defined variable like so:
Also because it uses the existing comma operator, any performance issues or conflicts with other proposals are pre-existing. The only performance hit would be from expression-scoped variables which I would think should be equivalent to this:
Side note: it would be nice if the |> could be used without commas, but that might be harder to implement:
The text was updated successfully, but these errors were encountered: