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

Push a minimal proposal to Stage 3 asap #140

Closed
igabesz opened this issue Oct 5, 2018 · 39 comments
Closed

Push a minimal proposal to Stage 3 asap #140

igabesz opened this issue Oct 5, 2018 · 39 comments

Comments

@igabesz
Copy link

igabesz commented Oct 5, 2018

Currently I work with TypeScript so I cannot use the Babel plugin. And man, I need this feature so badly. The TS team has a deep discussion of this proposal but I it's unlikely that they will implement anything before Stage 3.

For me it seems that there's still a lot to do with the competing proposals and Stage 3 seems very distant. Wouldn't it be possible to create a minimal proposal first, covering only the basic use-cases that work the same way in all of the complex proposals? Maybe we have no await keyword in this minimal proposal, no template literal support, must use parentheses around arrow functions, etc. -- anyways, we've got the basic usage which is sufficient for many real-life use-cases. And the TS team could start implementing it, and lots of the developers could start using this feature.

In the meantime you can refine the advanced proposals which will extend the minimal proposal. After a few years (?) when all the issues will be resolved and the complex proposal will be finalized there would be an update to the syntax which would enable the more advanced use-cases that were prohibited in the first version.

So would you create an MVP of this proposal first, then move on to the advanced use-cases? We need this feature badly.

@mAAdhaTTah
Copy link
Collaborator

Yeah, no, they won't, and they shouldn't, as the proposal can still change. I can only imagine the headaches the decorator proposal changes are causing over there.


There are two issues with this suggestion:

  1. Rushing things through committee for a language as widespread as JavaScript and getting it wrong is far more painful than waiting and settling on a good proposal. Once the genie's out of the bottle, you can't put it back in, so it's far more important to be deliberate and do a good job here, as the impacts are significant.

  2. There are aspects of the "advanced" proposals that don't overlap with the "minimal" proposal. The current definition of the Smart Pipeline would preclude some things the Minimal would allow, like x |> f(a) needs to be x |> f(a)(#) in Smart. Additionally, F# is aiming to remove the parens requirement from arrow functions defined in a pipeline. It's not really feasible to define a "minimal" that overlaps with both "advanced" that doesn't potentially circumscribe what either advanced proposal can do.

For these two reasons, I would not be in favor of rushing through a minimal proposal.

Additionally, I think we end up with the pipeline operator we "want" (for whatever that means) faster if we do it whole cloth here and get it right the first time than trying to break it up into steps. This initial process may take longer, but the time to push through a minimal + an advanced later is almost certainly greater than the time required to push through a complete proposal now.

@rpamely
Copy link

rpamely commented Oct 5, 2018

I think the most helpful thing you can do is document your use cases that you need the pipeline operator for so much, and maybe offer a suggestion of which proposal best fits these use cases in your mind.

@igabesz
Copy link
Author

igabesz commented Oct 5, 2018

Pipes are the operators we need but not the ones we deserve. 😄 Jokes aside, I agree with your 1st issue. This is why I suggest to make even bigger cuts in the functionality, to have a proposal free to adapt to reasonable future changes. The only "genie question" in this case is whether it is a good idea to introduce pipes at all.

Regarding the examples in the 2nd one:

  • x |> f(a) -- is this questionable? Let's allow x |> f or x |> (value => f(a)(value)) only, nothing between. (Or something like this, I'm no JS language expert.)
  • Omitting parentheses are allowed in only one of the "advanced propsals"? Let's make them mandatory, we can loosen the requirements later.

So I think this "minimal proposal" is technically viable. Maybe it's even less than the original minimal proposal presented before, but hey, at least something we can use. Because I'm afraid that the advanced proposals might take a few years to get finalized.

You might be right about the timing, but as a developer I believe I would mostly use the features of the minimal proposal. Gut feeling: approx 70-80% of the use-cases. So I'd rather go with this approach.

Plus if the TS community gets the minimal proposal that will generate a huge developer feedback. There are lots of developers waiting this feature to be available. Some of them may even join the discussions here how to finalize the advanced proposal. Note that this could affect timing, maybe in both directions...

@mAAdhaTTah
Copy link
Collaborator

x |> f(a) -- is this questionable? Let's allow x |> f or x |> (value => f(a)(value)) only, nothing between. (Or something like this, I'm no JS language expert.)

At that point, the proposed pipeline would be so restrictive, it would lose a lot of its usefulness, and I'm simply not convinced of the benefits of pushing it through faster vs getting it right the first time. The proposal isn't as large as something like class, which benefitted greatly from incrementalism. This is absolutely something that is small enough in scope to get right the first time.

Plus if the TS community gets the minimal proposal that will generate a huge developer feedback.

We're currently working on Babel plugins for all 3 proposals for this specific purpose. We don't need to rush through a proposal to get feedback.


All that said, I appreciate your enthusiasm! I think we'll get there; we've made a lot of progress, and I don't think any of the particular proposals have show-stopping hangups. We just need to choose one, and I'd rather do the work to choose the right one then lose our opportunity trying to push through an incomplete feature.

@littledan
Copy link
Member

If you want to help, it'd be great to see a Babel implementation of the F# pipeline proposal, and then collect feedback about the four alternatives (bind, F#, smart, don't-add-anything). @mAAdhaTTah maybe we should have a good write-up of this strategy that exposes opportunities for folks to get involved.

@mAAdhaTTah
Copy link
Collaborator

@littledan I'd be into that. The main problem right now is we're blocked on making much progress until this PR is landed: babel/babel#8289 I don't know as we can proceed too much further without getting that landed, as the F# proposal will be working in the same area of the parser. I also still want to play around with paren-less arrow functions, which may require some parser changes as well (although some of those changes may already be in the proposal above). I've poked the babel people on Slack a few times; maybe I need to poke a little harder?

My intention was to get the 3 implementations into babel then go out and do some barnstorming. There's a few meetups in NYC, and least one of them records all their talks, so that'll make for some good material, plus additional blog posts and the like.

@littledan
Copy link
Member

@mAAdhaTTah That sounds like a good plan. While you're blocked on review, maybe start developing the F# proposal on top of the other one (even in the same mega-PR)?

@mAAdhaTTah
Copy link
Collaborator

@littledan Yeah, I've been thinking I should. Also gotta resolve those conflicts, but things have been quite busy for me lately (just switched jobs), so it's been a bit tough. Once things settle down, I'll definitely just start plugging away at that.

@thiagoarrais
Copy link

Just for the record: I am working on the Babel transform for the smart proposal based on @mAAdhaTTah's parser PR.

@dlebedynskyi
Copy link

@mAAdhaTTah for the record, babel/babel#8289 PR has landed in 7.2.0 babel

@littledan
Copy link
Member

This proposal is more taking its time to make sure it's useful enough to "pay for itself" than because it is too big. The committee isn't sold, as a whole, that we should do anything at all. I agree with the above comments from @rpamely and @mAAdhaTTah . There is a minimal proposal, it is the spec text in this repo, and Babel supports it.

@Dabolus
Copy link

Dabolus commented Dec 15, 2018

@igabesz FYI you can actually use the minimal proposal in TypeScript thanks to the Babel TypeScript preset. Check out a bare-bones example here.

@mAAdhaTTah
Copy link
Collaborator

@Dabolus Does that typecheck? My understanding is because TS doesn't support this syntax, it's not going to confirm that the types flowing through the pipeline match as expected, in which case, being able to write TS with the pipeline operator isn't that valuable.

@Dabolus
Copy link

Dabolus commented Dec 15, 2018

@mAAdhaTTah you got it right, and I find it pretty much useless too. However, that's currently the only way to make it work, so maybe the OP might find it useful to start working with it until some pipeline proposal reaches stage 3.

@sarimarton
Copy link

@mAAdhaTTah your arguments come from subjective emphasis.

At that point, the proposed pipeline would be so restrictive, it would lose a lot of its usefulness

Yes, and that is okay.

and I'm simply not convinced of the benefits of pushing it through faster vs getting it right the first time

This is not a versus. You're arguing against a risk, in multiple comments of yours here, which doesn't exist. As mentioned, and you indirectly acknowledged, there is an MVP for this, which means that it's not a dead end for any of the variations. The amount and foreseeable amont of bikeshedding justifies the idea to push through an MVP first.

The proposal isn't as large as something like class, which benefitted greatly from incrementalism.

By what measure do you make this comparison? And why whould incrementalism need justification from such a measurement? Incrementalism is nice in any way. And putting this aside, pipeline operator do seem to have a lot of hidden complexity, which in my view by far measure up to class in whatever regards.

@mAAdhaTTah
Copy link
Collaborator

Any evaluation is subjective. Saying "your arguments are subjective" suggests there's some kind of "objective" way of analyzing this. There isn't. We just have various subjective ways of evaluating things.

To speak to the incrementalism: The main issue there is there are paths that, if we proceed down now, cut us off from potential options later. Disagreements on the nature of arrow functions and what syntax is allowed and isn't between the 3 proposals would limit the potential options if one of them won out now. I outline some of that above; happy to elaborate if any of that isn't clear.

That said, the committee is not going to accept the minimal in its current form unless we've fully ruled out alternatives; specifically, a minimal without await support would be unpalatable without extenuating circumstances (search for bakkot's comments; I believe he makes that argument in a thread here). I'll also refer you to @littledan's comments above.

The risks aren't simply my POV but my understanding of the view of the committee (of which, to be clear, I am not a member and do not speak for). I do agree with them, and I've made those arguments as I've seen them, and as such, I remain opposed to rushing through an incomplete proposal.

@sarimarton
Copy link

I again see a flip-flopping arguing against the MVP. Which one is the case in your opinion?

  1. It doesn't exist
  2. It exists, though it's too restrictive to be useful

(1) is a factual question. I think it obviously exists. If there's disagreement on the nature of arrow functions, then MVP is by definition the most restrictive variation.
(2) is somewhat subjective, but I don't see any reason how a language feature of such demand could be regarded not worth to include, let it be at any rate restrictive. Simply allowing only barebone a |> b is useful already.

@gilbert
Copy link
Collaborator

gilbert commented Jan 17, 2019

You can't count allowing a |> b as incrementalism because it already makes a clear decision on the requirements of parenthesis, something you can't go back on.

@mAAdhaTTah
Copy link
Collaborator

I don't believe I claimed there wasn't an "MVP."

You feasibly could strictly allow bare identifiers, which would be a subset of all the proposals.... but why?

@littledan
Copy link
Member

The big thing we need to push the proposal forward is demonstration that the proposal is broadly useful, in code bases of various styles. We should figure out some way to work together to do this, but I'm not really sure how. Let's see if we can come up with ideas here.

@sarimarton
Copy link

There seems to be a disagreement between @gilbert and @mAAdhaTTah on the existence of an MVP. gilbert says a |> b is not an MVP, because it already shuts some variations out about parenthesis requirement. Gilbert, can you give an example of it, or refer to somewhere I can read about it?

@mAAdhaTTah ,

You feasibly could strictly allow bare identifiers, which would be a subset of all the proposals.... but why?

To achieve the very basic goal pipeline is for: avoid nesting of function applications.

@gilbert
Copy link
Collaborator

gilbert commented Jan 17, 2019

@sarimarton One example: If elixir-style is chosen, then having both a |> b and a |> b() be equivalent is already introducing a wart around the operator.

@sarimarton
Copy link

@gilbert Then restrict it to barebone identifiers, and you get an MVP which contains no irreversible decisions.

@ljharb
Copy link
Member

ljharb commented Jan 17, 2019

Except the irreversible decision of having an incomplete feature in the language (unless we could complete it by arriving at consensus on the rest)

@sarimarton
Copy link

sarimarton commented Jan 17, 2019

Except the irreversible decision of having an incomplete feature in the language (unless we could complete it by arriving at consensus on the rest)

This argument has 2 problems:

  • calling it 'incomplete' is subjective (Edit: and referring to @mAAdhaTTah , no, not every argument is subjective :) )
  • an 'incomplete' (whatever we mean by that) feature is not irreversible by any means. You're arguing against incrementalism in general. (Edit: obviously every addition to the language is irreversible, but in this neutral sense, being 'irreversible' has no significance. Incrementalism is very much about making steps (irreversible steps) without taking any risk of wanting to go back)

@gilbert
Copy link
Collaborator

gilbert commented Jan 17, 2019

Then restrict it to barebone identifiers, and you get an MVP which contains no irreversible decisions.

That was my original point. Such a restriction is the irreversible decision.

@sarimarton
Copy link

That was my original point. Such a restriction is the irreversible decision.

Why would it be irreversible?? Restrictions' very point is to remain flexible about lifting them up. Lifting up a restriction later is a language addition. It's incremental. This happens all the time (think of Template Literal Revision, or first versions of ES6 classes and later additions etc.)

I think we should clarify the term irreversible here. The only meaningful interpretation IMO is that it can produce code which can be broken with a later step. That's not the case with a properly restrictied version.

@mAAdhaTTah
Copy link
Collaborator

It's irreversible in that you can't remove it as well. The committee, as I understand it, is not strictly convinced pipelining is a problem to be solved, nor is it necessarily convinced the pipeline operator is the best way to do it. There's more than a few who would prefer bind :: as the operator to solving pipelining.

I don't think a bare identifier approach is particularly useful either. If you can't do a |> b(), there isn't a lot you could put into the pipeline. You're forced to lift everything up to variables and assign to them before you use the pipeline, which splits up the logic in a way that makes it a bit clumsy. If you attempt to expand the operator beyond that, you've moved into making decisions that limit various futures.

@sarimarton
Copy link

So it's the bind operator which holds it back... Then I guess there should be a discussion of which of these proposals we want to pursue. I have a guess that for the bind operator there would be much much less demand. It's too much domain specific, and actually it itself demands domain specific practices in terms of the overlapping functionality with pipeline: library functions should use this as their data argument, which is horrible... Pipeline on the other hand would bring us one step closer to functional languages and complies with the general - more and more - common sense nowadays that ignore this alltogether.

I admit that this wording might sound too much decided, but to put it short, I think it makes sense nowadays that

  • we don't need this
  • bind operator depends on this
  • we need flat function composition

@ljharb
Copy link
Member

ljharb commented Jan 18, 2019

The bind operator has 3 use cases; pipeline covers 2 of them. It's fine to not have the bind operator and have pipeline instead, but we also need a separate way to do method extraction.

It definitely doesn't make sense that "we don't need this", given that class methods and builtin prototype methods all rely on it.

@littledan
Copy link
Member

@gilbert makes a strong point that, if we go with the F# proposal, then we can't go back and select Elixir, but I wonder if we might be able to start with F# and have a follow-on which supports some kind of placeholders. @js-choi has articulated that there is a "footgun" risk to allow arbitrary expressions on the right hand side of |> in conjunction with placeholders, but I'm not completely sure how bad these hazards would be.

@ljharb I disagree with you that we need to provide these both with one proposal, just because someone previously articulated the different pieces of functionality together. The get-originals proposal (which I think would make sense across environments, assuming it's provided by a built-in module that can be polyfilled/virtualized) can provide access to the original Function.prototype.call, providing this support with something separate from the pipeline operator.

@mAAdhaTTah
Copy link
Collaborator

Then I guess there should be a discussion of which of these proposals we want to pursue.

This is what we've been doing, which is why we can't fast-track a pipeline operator to stage 3. For bind, see #110 and #107.

@gilbert
Copy link
Collaborator

gilbert commented Jan 18, 2019

Why would it be irreversible?? ... I think we should clarify the term irreversible here. The only meaningful interpretation IMO is that it can produce code which can be broken with a later step.

Right, that's the meaning we're using here. If you allow a |> b, but later allow a |> b() as an equivalent, then you can't remove the former without breaking existing code.

@ljharb
Copy link
Member

ljharb commented Jan 18, 2019

@littledan that’s not what i claimed; as i stated in the meeting when pipeline went to stage 1, i consider it a stage 2 requirement to establish how a different proposal could reasonably handle method extraction, since pipeline going to stage 2 effectively blocks the bind operator. The get-originals proposal would have to be part of the language, and also allow for polyfilling, in order to supply that use case sufficiently, and i don’t believe it’s currently intended to be proposed for the language.

@zenparsing
Copy link
Member

@ljharb I intend to address method extraction with a separate proposal at some point.

@ljharb
Copy link
Member

ljharb commented Jan 18, 2019

That’s great :-) id love to see the shape of it, and ideally have it at stage 1, before pipeline progresses.

@littledan
Copy link
Member

@zenparsing The more I think about your -> pipeline idea, the more I am excited about it. I'd encourage you to follow @jschoi and @mAAdhaTTah 's lead in accompanying an explainer with a Babel implementation so we can get more feedback from JS developers.

@karptonite
Copy link

karptonite commented Jun 26, 2019

For spectators just trying to follow this, the -> pipeline idea mentioned above can be found here, I believe: #143 (comment)

@tabatkins
Copy link
Collaborator

Closing this issue, as the proposal has advanced to stage 2 with Hack-style syntax.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 11, 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