-
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
Where does the F# and Smart proposal conflict? Let's split them up into two proposals, one predicate on the other. #134
Comments
The main concern is that there are currently behaviors that allowed under the F# Pipeline that are currently The other is that F# is likely to proceed with a solution that doesn't require parentheses around arrow functions in the pipeline, which would be another conflict. So the two proposals aren't strictly a sub/superset of each other, such that we can't really proceed with F# and land Smart as a follow-on. |
Thanks for the clarification. From a distance it appears that if the F# proposal move forward, another proposal that is Smart-like can still arise; yet the Smart prevents a style some prefer (point-free and currying) where the partial variables are provided, for example const add = a => b => a + b
const foo = 5
|> add(5) Under the Smart plan it would be const add = a => b => a + b
const foo = 5
|> add(5)(#) However, a future Smart-ish proposal can make the above default presumption unless the user provides an explicit One often see this Decoupling these proposals, even if they should compete, better proves the stronger proposal. An F# proposal complemented with a general placeholder proposal (arriving at a later time) may or may not prove to be better than the Smart proposal. Currently, however, the weakest dependency between the tangled proposals becomes parasitic to the other(s). |
All of that is generally true, but you glossed over the "parens around arrow functions" issue. I also suspect that if a Smart pipeline doesn't advance, a solution for placeholders will end up being more general than Smart's implementation. Smart's major benefit / drawback is how much other syntax can be built on top of it in follow-on proposals. If you fail to introduce placeholders in the initial pipeline proposal, I suspect you won't see Smart advancing as a follow-on. |
Why exactly can't presuming a partially applied curried function (presuming a final |
It can; the reason for the restriction is to avoid footguns and reduce ambiguity over the developer intention. Some languages pass the argument to the first position, like Elixir, so this:
is desugared to this:
Requiring a placeholder makes it explicit that it would desugar to this:
and not
as syntactically, you'd need to include the |
I agree in that it can be confuse to someone just learning; yet it is a consistent behavior within the language. I've had to explain to beginners what As for footguns, the untyped nature of JavaScript enables a plethora of ways to generate runtime errors. What you are suggesting can be address by configuring a linter as needed. Another useful tool is TypeScript; which easily catch these kinds of errors upfront. I personally don't think it is confusing and read code written in this way all the time. It best to not entangle the progress of the pipeline operator with the considerations the Smart proposal exposes. |
@mAAdhaTTah Would code like the following (which is valid in the minimal version implemented in Babel) work in the F# proposal? const parseCreateVMOutput = s =>
s
|> Str.split("\n")
|> Arr.map(Str.split(":"))
|> Arr.filter(xs => xs.length === 2)
|> Arr.foldMap(Obj)(([k, v]) => Obj.embed(k)(Str.trim(v))); Last time I read through it I wasn't able to suss out exactly which expressions are and are not allowed on the RHS of a |
@masaeedu All of those are valid in F#. None are valid in Smart. |
So what does it take for this to advance? How and who settles what moves forward--smart or F#? Is the next TC39 meeting where this gets hashed out? The Elixir behavior The Smart Operator proposal looks useful because JavaScript lacks a built-in syntax for placeholders. It is of course possible to have a placeholder function right now const myDivide = placeholder( divide )
pipeline(
100,
myDivide( __ , 2)
) where 100
|> divide( #, 2) yet this benefit is somehow entangled with a prescription for some perceived ailment in JavaScript--that functions returning functions is confusing. Actually this is even clearer 100
|> divideBy( 2 ) Yet not allowed in the Smart Operator as medicine. I disagree here. I like the Smart Operator and would like to see it separated out a benefit JavaScript in general. I dislike the noise of adding 100
|> divideBy( 2 )( # )
|> powerOf( 2 )( # )
|> multiplyBy( -1 )( # )
// .... and so on with the tail (#) (#) (#)... In fact it would work just fine with a general placeholder syntax because To prescribe this to all developers as required minute-by-minute, hour-by-hour, daily programming medicine is a misdiagnosis--many don't need or want it. Do away with this mandate or please let us just have F# and move forward. A general placeholder proposal solves what Smart Operator solves anyway. |
We're currently working on Babel implementations of all 3 proposals, which we'll use to gather real-world feedback from developers to inform our decision. |
Here's an even more simplified approach, a very basic implementation, the intersection (or even less) of the 2 current proposals and have it released asap. Man, if we could start using pipes with simple functions on the RHS then it's already a huge win. |
For what it’s worth, the trade-offs of the current smart-pipe proposal are not set in stone. They’re fluid and subject to change. For instance, Either way, that’s a fundamental trade-off that might or might not be worth it for different developers in different places and times. There’s another trade-off involving non-function expressions (such as When it comes to trade-offs such as these, all the proposals have opinions, but these opinions are not strongly held. Every decision and pros and cons, nothing is set in stone, and the final result cannot help but be a compromise between fundamental trade-offs…hopefully an optimal compromise for developers in general. The proposals can and should and will be tweaked, based on feedback after the plugins are implemented and the syntaxes actually tried out. As the author of the current smart-pipe spec, I also want to publicly thank @mAAdhaTTah, who is himself the author of the current simple/F#-pipe spec, for taking the time to reply to questions here about both proposals while I’ve been busy these past months. He is super great. And on behalf of both of us (and everyone else involved), I’d also like to thank everyone here for their patience. |
Closing this issue, as the proposal has advanced to stage 2 with Hack-style syntax. |
Clearly stating if and where these two proposal conflict would go long way. It would seem that the F# is the minimal proposal and that it doesn't conflict with the Smart proposal. So why not make them separate proposals? Let the simpler proposal go through and the Smart enhancement get added. If the value is there, maybe we'll get both at once, otherwise, at lease we'll have some kind of pipeline operator.
Thing is, there A LOT of people looking for this to move forward. In my circles this is like the #1 anticipated feature. Many in the Typescript community is also waiting for this to move forward.
It seems that the hang ups over the specifics of the Smart operator are going to delay this moving forward. Should we use a # character or ? character, etc. How does this play with a general placeholder proposal, etc-- It would be nice to have but not having any pipeline operator is worse than the ergonomics that the Smart operator offers.
The text was updated successfully, but these errors were encountered: