-
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
I think it would be prudent to walk away from this proposal entirely #297
Comments
Complete respect to @tabatkins and folks working on the proposal. They've fought a lot and done a lot of VERY hard work. I'm just humbly begging we put it on ice. I'm unconvinced the current incarnation is a good idea. |
I would add this comment on Promises spec, where we can see clearly how committee acts against functional programming paradigm in JavaScript. promises-aplus/promises-spec#94 (comment) #edit I also like Hack pipelines, and i really think its way better than F# because it allows the usage of class methods and other operations that aren't unary functions. It would bring imperative/OOP to funcional way of expressing things. Hack is waaaaaay less cursed than F#. const createUsersCache = (users: User[]): Map<number, User> =>
users
|> #.filter(Boolean)
|> #.map((user) => [user.id, user] as const)
|> new Map(#) const createUsersCache = (users: User[]): Map<number, User> =>
users
|> ((users: User[]) => users.filter(Boolean))
|> ((users: User[]) => users.map((user) => [user.id, user] as const))
|> ((tuples: readonly [number, User]) => new Map(tuples)) |
The above response is fairly off-topic. Whether or not the committee "acts against functional programming" isn't the issue. The issue is this proposal is controversial, and IMO, it's better to add nothing at all. The examples were odd too. const createUsersCache = (users: User[]): Map<number, User> =>
users
|> (users) => users.filter(Boolean)
|> (users) => users.map((user) => [user.id, user] as const))
|> (tuples) => new Map(tuples) But also, all examples above should be rejected at code review, because it's a silly way to use a pipe: const createUsersCache = (users: User[]) =>
new Map(users.filter(Boolean).map(user => [user.id, user])) |
I agree with this sentiment. Given that the Hack pipeline operator has the potential to cause a divide in the (already small) functional programming community*, and reduces the chances that we'll ever get better HoFP support, I'd rather not see it make it into the language at all.
|
Most resistance I've seen boils down to either "This should just be a function, not a new operator" or "F# version is better". I think the former argument has been pretty well refuted in issues like #293. Are there issues that show how Hack leads to a worse situation than where we are now, i.e. no built-in "blessed" way to pipeline function calls or other expressions at all? I liked F# (especially with the separate partial application proposal) more too. But now I just hope that we get something. I encounter a situation where this would make my code cleaner like once a week at least (although admittedly about half of those would also need #198). Sure I could import some "pipe" helper function and write a bunch of piped lambdas. But I won't. Or I could use one useless helper variable instead of several "const steps" and make that a "poor man's pipe operator". But I won't. It's just not how I've gotten used to writing JavaScript and it's not how my teammates have gotten used to seeing JavaScript, and it's just not worth it if I have to worry about questions like "will using these helper functions make my code slower" or "does this make things harder to read or debug" or "how many steps should a pipeline have before it's worth it to import and use that function". Simpler to just write the damned assignments to intermediate consts. Ease of use and familiarity makes or breaks a feature like this, which is why I would very much love to have it baked into the language, in one form or another. Taking this as an example const createUsersCache = (users: User[]) =>
new Map(users.filter(Boolean).map(user => [user.id, user])) I don't think I'd ever write import pipe from 'mypipelib'
const createUsersCache = (users: User[]) =>
pipe(
users.filter(Boolean).map(user => [user.id, user]),
_ => new Map(_)
) but I think I do actually like this version very much const createUsersCache = (users: User[]) =>
users
.filter(Boolean)
.map(user => [user.id, user])
|> new Map(%) 🤷 IMO that's easier to both read and write from left to right, without having to go back to wrap the whole thing in |
Based on what? The small inconvenience with today's pipeable libraries? So, instead of adding a feature that would work with all paradigms and libraries we should cancel everything and wait for something to happen in the future that will only help writing code with libraries like rx, fp-ts etc? |
I will assume that is a rational question asked in good faith. Based off of how contentious this discussion has been. I disagree that this works well with all paradigms. But that's beside the point. The point is the community is clearly divided on this, with the exception of a powerful minority. And that's no way to run things. |
currying and unary functions are only used in 3rd party libraries, most of the language's existing features would not benefit from a pipeline in that way I really struggle to understand the point of those who prefer the F# style |
@lucacavallaro …I would strongly refrain from the absolute language stating what is essentially the most common and simplest way to use functions with input & output that can be used by another function (or final result) is “only” used in 3rd party libraries… The most essential means of composing, chaining, and communicating working with functions is functions with the arity of one (unary functions). The fact that hack-style makes this essential means of working with functions the most tedious to write is one of the primary reasons it is so contentious with an obviously very powerful minority essentially hand-waving that’s okay. It’s been clearly communicated in #217 that it’s not to very meaningful segments of the JS community. It accordingly seemingly doesn’t seem it’s in the best interest for this proposal to be continued as is considering the seemingly far smaller ecosystem-impacting reasons standards pivoted from a certain direction (IIRC smoosh-gate). It can be argued that Hack-style is continuing exploiting the unceremonious means it’s been pushed by a powerful minority with JS members giving in only because it seems it’s it OR nothing at all. That’s almost as contentious as you can get without abandoning a standard. As far as I’m aware, it’s unprecedented the most essential and most purest way of doing a computation is less tedious than using its operator in JS—can you point us to an example in the language another operator does this to what it’s supposed to make more easier and clearer to write? Finally, a great deal of the language has methods that aren’t and weren’t intended to be composed in a data pipelining manner that is disingenuous to bring up as they’re often as they are in these matters. Such methods are usually rewritten with fascade variants oriented/optimized for chaining to be less tedious to write in everyday codebases. |
There is no more disagreeement now than there ever was. There continues to be a population of authors who use a lot of higher-order functions and want a pipe that caters to them, to replace the pipe() function they're currently using. The "F#-style" pipeline was explicitly rejected by the committee. The committee's reasoning is documented in this repository, and none of the champions see a way around those objections, nor do they particularly want to pursue that direction in any case. Anyone wanting to pursue a proposal in that direction is welcome to, but they are very likely to fail for the exact same reasons it failed in the past. This proposal will continue in the current direction. The champions have been working on other things so work has been paused, but not stopped. As has been stated before, a proliferation of topics re-litigating the exact same issues doesn't help anyone. We have a few topics covering the various angles of this; please use those for discussion if there is new information to be had. Do not revive the threads if there is no new information, however; review the existing posts first and, if the points you wanted were already made, leave it be. I'll be closing this issue. |
This isn’t relitigating any issue. This is pointing out that there’s a big disagreement in the community, and that the best course of action is probably to do nothing. This is dismissive. I suppose I have to pay for entry. |
Looking at #91, and remembering several other threads. There is just too much disagreement. Anecdotally, I went from being beyond excited about the possibility of adding this feature, to now begging the committee to stop it and do nothing instead, in the hopes that someday JavaScript developers will have something better.
Given standardizing the current proposal would eliminate the chance for a pipeline operator that behaves in a way that's more useful to existing functional pipe using libraries and users (which generally leverage currying or unary functions). And given the fact there has been years of strong, valid resistance to the Hack style operator proposal. IMO, it would be best to do nothing instead. It's far better to keep the status quo than to add something questionable.
The objections to the Hack-style proposal are well documented in this repository. Like it or not, this proposal is an example of why some folks feel the committee imposes their will on the community rather than being a part of it. In fact, I don't really expect this issue to be taken seriously. I'd wager by the time some folks have read to this sentence, there are emotions filling their hearts if they disagree with what I'm saying. I just think it's a mistake to proceed... and better to wait until we have a unanimous agreement. Which may never come, and I'm okay with that.
The text was updated successfully, but these errors were encountered: