Guidelines on RFCs and feature requests

Continuing the discussion from Pre-RFC: Named arguments:

I reckon rust ought to have clear guidelines as to what design guidelines it follows and which features it would therefore consider. We should not entertain all possible ideas just because someone thought it be cool.

Do we have such criteria defined and officially listed anywhere? Also, should we list ideas that have been rejected or those that are controversial and therefore do not have sufficient consensus to be added?

Where do we define what is acceptable cost wise (implementation effort, added complexity, etc) and likewise how would a feature going to be evaluated to be worth it?

Also, what guidelines do we have on providing feedback? I strongly disagree with the above statement that we should allow discussion of any feature. To my mind, this leads people on to invest their time and effort to draft the RFC for something that may very well be rejected outright due to not matching the above. Also, people get more emotionally invested the more they work on something.

This is also frustrating on the other side of the discussion. When am I allowed to object?? When the RFC has been submitted already is too late and is very emotionally exhausting to argue against. This is also compounded by the multiple times the same ideas are raised and one feels they need to keep fighting to protect against a tide of complexity brought forward by newcomers that just want to port their previous languages and experiences wholesale. Where do we draw the line here?

4 Likes

Two useful things to reference could be the lang team design notes as well as the closed RFCs.

(Closed ≈ we don't think this is a problem rust needs to solve; postponed ≈ we agree this is a problem we could address, but this isn't an approach we want to take right now.)

1 Like

FWIW, I had a long conversation with @khionu following up from that post, and I wanted to offer some (unofficial) clarifications regarding pre-RFC policy. I'm one of many people in the Rust Project who reviews RFCs (and sometimes pre-RFCs), but this isn't any kind of official policy, just thoughts on what differentiates productive pre-RFC/RFC discussions vs long and frustrating ones:

  • It's fine to (respectfully) express sentiment or arguments against an idea in the pre-RFC phase. We do want to know how the community feels about something, and hear about the arguments against as well as those in support.
  • However, the goal of any such arguments isn't to push someone to stop proposing an idea. Rather, much as with an RFC, the goal should be to encourage capturing and summarizing alternatives, tradeoffs, advantages, drawbacks, values, and similar. (It may be that a side effect is that the proposer is themselves convinced, and either switches to an alternative or stops driving the proposal, but even if they're not convinced, that's not a reason to repeat the same arguments.)
  • In support of that, arguments about a pre-RFC should be in service of collaboratively building a clear explanation of possibilities, alternatives, tradeoffs, advantages, drawbacks, values, and similar.
  • Even if a proposal is not pursued, there may be value in recording the reasons why not in a design note, for reference if a similar proposal arises again. If the result of a pre-RFC thread is an RFC with clearly documented alternatives and drawbacks, that's great; if the result is a document explaining why we probably don't want to do something, that's great too.
  • Repeating the same arguments isn't helpful; linking back to an argument that hasn't been summarized into the text, and/or proposing text for a drawbacks/alternatives section, is much more helpful. Resist the temptation to keep arguing as long as you see people who disagree with you; try to arrive at a document to which you can say "that summary accurately reflects my position" (whether your position favors an alternative, or favors the null alternative due to drawbacks/tradeoffs/values).
  • Remember that neither the proposer nor the arguers in a pre-RFC thread are out to harm Rust; assume good faith, and assume that everyone is attempting to make Rust better but disagrees about how to do so, or holds different values or differently weighted values. (If there is ever reason to believe either that someone is making proposals in bad faith, or is not applying an appropriate level of care to respect the time of other participants, that's a separate matter, to be reviewed and addressed separately.)
  • Please keep arguments and sentiments respectful. If someone does not agree with your arguments for or against something, that doesn't make it acceptable to attack or insult them. It is often easy to cross the line from "this person isn't agreeing with me that this would harm Rust" to "you must know that this would harm Rust since it's so obvious to me and anyone reasonable would agree with me, and yet you unreasonably seem to want to do it anyway", and reason onward from there. Stated that way it sounds ludicrous, and yet this failure mode comes up often. Consider instead what the crux of the disagreement is: what value do you weight differently than them, or what evidence do you find credible that they do not or vice versa? Challenge yourself to write a comment for which someone you disagree with will say "yes, I agree that that's what we're disagreeing on and why", or ask them if you're successfully getting closer to such a crux; that's something you can collaborate to find.
20 Likes

What I would say is that objecting, on its own, is rarely valuable. Whether some Ridley Random on the internet likes or dislikes an RFC isn't really a material input to language decisions.

Here's a couple of common patterns to improve an RFC of which you're not a fan:

  • Provide a missing drawback. For example, the first post in Pre-RFC: Named arguments has an oddly-short drawbacks section. (I didn't check if there's an extended one elsewhere.) Almost every RFC should include the drawback of "this makes things more complicated", which a discussion of why the author considers the extra complexity worth it -- and the more complicated the RFC the more important that section becomes. If there's a drawback that's not acknowledged in the text of the RFC, that's an update that the author should make.

  • Ask for additional rationale. Common questions don't need to be answered in the Guide or Reference sections, but a strong RFC will preemptively answer "Why did this RFC pick _______?" And indeed, figuring out what those common questions are is one of the most useful things that can happen in a pre-RFC phase.

  • Raise other alternatives. The author has some pain point that they're trying to improve. And clearly, that is a pain point to them, so arguing that it's not painful isn't productive. But adding extra alternatives again make the RFC better. That could be "hey, there's this simpler thing that gets most of the good", but it can also be "I don't think this is helpful enough on its own, and should include more", depending on the proposal.

At a meta-level, if you're opposed to something what you want is to get your concerns into the text of the RFC, because that's the best way to either (1) find out that the author has a great answer and you're no longer worried, or (2) make those people who have to make the decision on it go "oh, that really is concerning about this".

2 Likes

That's a good set of suggestions to apply for new ideas. However this does not address the issue at hand at all.

Rust has already made deliberate design choices in the past such as not having ad-hoc function overloading, not having inheritance, etc. Those are already chosen tradeoffs which are core to Rust. Once in a while someone joins Rust from a language with these features and they start yet another round of debate on issues that have been already settled on for a long time. Sometimes quite rudely claiming Rust is inferior to another language due to "obvious and glaring" omissions.

There is no benefit here to collect alternatives as you suggest. This has been already debated and settled on. Changes to these decisions ought to require a very high bar demonstrating a sufficient change in circumstances to warrant reopening those decisions for debate.

That's very different imo from genuinely new ideas where we should do as you suggest and explore and document all possible alternatives so that we come up with the optimal design for Rust.

1 Like

Anecdotal remark:

My recent pre-RFC for sealed traits (via #[sealed]) was reasonably well written and clear, but there was still the question of whether it was even the right design. I, of course, thought it was, but I was convinced that there was a much more flexible way in an off-handed comment. Was the comment thorough or detailed? Not at all. It was just "hey, this might work", and it absolutely does work. If comments like this aren't allowed, I fear more casual comments may be withheld, limiting discussion of possible alternatives that could be vastly superior.

9 Likes

That emphasis is entirely misplaced and does not address my concerns at all. I did not ask to object just for the sake of it, and have quite clearly documented the reasons for providing negative feedback. My question was, again:

When is it allowed to provide genuine feedback? Which includes more than just being agreeable to anything suggested.

As to your other points, I've already agreed that those are valuable for genuinely new ideas and suggestions.

Last edit:

Imo this is poor process as It puts the onus on the wrong party. The status quo ought to be the default state of affairs and I've called above to have more clearly stated guidelines for precisely that.

Imo there should be an official guide that explains the process of requesting a new feature, which should have a prominent FAQ section that explains why certain design choices have been made in the past and what would be required to change to open these for debate.

We have stability guarantees, those should include imo core design decisions. Things like having C-like syntax with braces, not significant whitespace. I shouldn't need to raise wanting to keep these as concerns on a new RFC drafted by yet another newcomer that hasn't yet adopted idiomatic Rust design and style

2 Likes

I am not part of the relevant teams, so I may have the wrong impression here.

But (after getting it cleared with T-lang) I think such a "core design language" document could fit into the design-notes part of the T-lang repo.

But it wouldn't just be "this is decided, stop asking" (reduced to absurdity). The point of the document would be twofold:

  • Documenting the core, cross-cutting, universal design choices in Rust, as well as
  • more importantly, documenting the rationale for the design choice, and the burden of proof for a proposal diverging from it.

The goal of such a document explicitly shouldn't be about carving certain design choices as inaliable and immovable. It should be to make clear the rationale and benefit of the current position, so that the design isn't just held as sacred, but that there is a defined point at which it becomes possible that a change could outweigh the benefit of staying with the existing.

The burden of proof would of course be very large. And the doc should probably mention the possibility of compile-to-Rust languages being an option for highly invasive changes to be explored. But there is a point where fundamental choices are challenged, and we shouldn't forget about that.

7 Likes

It is, though. That's why it's not infrequent that we end up unaccepting even features that had approved RFCs and were implemented -- https://github.com/rust-lang/rust/issues/44524#issuecomment-988260463 is one example.

I think it's appropriate that on IRLO there's a bit of a bias for action. There needs to be a place to explore what things might look like, and I'm much rather that be here than in the RFCs repo. When that goes well, it can even convince someone that something they like isn't worth doing.

It's certainly true that there's long-standing concerns about increasing complexity. Some I could find in a quick search include

(Actually, those are all 2018, so maybe things have settled a bit since that edition?)

But as far as I know this is a constant tension in all languages. Complexity essentially never decreases in any language with enough of a stability guarantee that people are willing to use it extensively.

I would certainly like to see something like rustfmt's fmt-rfcs/principles.md at master · rust-dev-tools/fmt-rfcs · GitHub for the language, though -- the way we expect various things to behave that are generally just not going to change. I've occasionally been attempting to reverse-engineer some of those, like when it makes sense for something to use braces vs parens (other than just K&R precedent).

Hmm, rfcs/lang_changes.md at master · rust-lang/rfcs · GitHub is pretty terse right now. I wonder what people are finding before opening things?

At the same time, I think that there isn't really that much noise about the really big things like whitespace-syntax. Those end relatively quickly, the the documentation would probably mostly mean a link to include. (I don't know that documenting "no, we're not doing that" would keep certain things from being opened, because I don't know any single programming language that would actually entertain switching from braces to whitespace or vice versa. Either they have always supported both, or they're going to stick with their choice.)

Some of the ones that stick out to me as persistently noisy are the ones like "what exactly should matching mean?" or "how exactly should we be doing around error handling?", where I think things aren't really settled yet, so even though it's often painful to make progress on them, I don't think there's any "core design decisions" that are controlling there just yet.

Maybe named arguments are in that list too -- after all, there's Wishlist: functions with keyword args, optional args, and/or variable-arity argument (varargs) lists · Issue #323 · rust-lang/rfcs · GitHub still open from 2014 expressing explicit interest in something in that area.

1 Like

I think that there are at least two broad classes of negative feedback to a new feature idea: can we do it and should we do it. The former tend to be easier to have productive conversations about them, especially if the parties engaged are aligned on the question whether the feature should be added. In that case, it's people working towards a common goal.

Whether we should do something or not is a much thornier type of critical feedback. Sometimes it can be phrased in terms of something reasonably concrete that can be addressed. But in other cases, sometimes it mostly just comes down to some fundamental difference of opinion on whether the new feature itself breaks a "complexity budget." That in turn is a difficult conversation to have. There might not even be agreement that the new feature adds complexity in the first place. Or maybe there might not be agreement on what the "right" complexity budget is.

I personally always have a hard time with "when do I express reservations" about something, particularly when it comes to concerns about "complexity." (I use "complexity" in scare quotes because it can mean different things to different people.) By the time something gets to an RFC phase, it's usually the case that someone has already spent a lot of work writing that RFC. There may have even been a working group spun up to do the work necessary to write the RFC. Because of that, it seems very appropriate to me to be able to express that sort of critical feedback before it gets to that point.

I'm just not sure when or how exactly. In particular, conversely to expressing critical feedback, I think it is also very appropriate to allow folks the room to explore and brainstorm ideas for a feature without having to constantly contend with folks arguing that the feature shouldn't exist in the first place. Those sorts of discussions tend to dominate the conversation and they are easy to spiral out of control. In particular, they tend to be discussions about values and experiences, and those are tricky to have.

Ideally it would be nice if the parameters of the conversation could be established somehow. And if folks want to veer off course into a discussion of "should," maybe it can be done in a separate topic. And if you aren't sure, you can always ask: "are you open to discussing whether we should add this feature or not in this thread, or shall I open a new thread?" But, this is something that is easy to say but typically hard to do in practice, for a lot of reasons.

4 Likes

I'm not sure there is a solution, because I think the current RFC process structure is fundamentally adversarial and puts the wrong burdens on the wrong people. The structure also doesn't lend itself to making decisions about what not to add, like the OP correctly pointed out in my opinion.

The current process:

  • Tends to focus on whatever proposal in some sphere is the newest one, redirecting all related discussion towards that proposal.
  • Makes it important for those that see downsides, better alternatives, blockers and so on to get in early and make themselves known, as they need to get their downsides listed in the RFC, requiring them to convince the author and the wider community.
  • Makes it important for the RFC author to defend their proposal against the incoming assertions of downsides, suboptimality and blockers.
  • Has the totality of the discussion spread across multiple places, which makes it hard to follow, hard to summarize, hard to get an overview. Most of the spaces where you can find discussions again are unthreaded and thus tend towards chaos instead of organizing themselves organically into subtopics.

The points above make it, in my opinion, so that there is always an adversarial and stressful relation between the RFC authors and the community. This is a perfect biome for emotions to take over and hostilities to emerge. That doesn't even really take into account yet that I find the process has a hard time to deal with things that are fundamentally subjective.

I'm not sure how easy it is for the various team members to get an overview of any given problem's/discussion's current state, and how confident they can be that they aren't missing anything without asking someone they trust and who is keeping closer tabs. But I'm sure it's not a picnic for them either.

I have my own idea on how named arguments could work without adding a new "feature axis" to Rust, aimed at being minimal. But I don't think there's any place right now where it would be productive for me to actually propose or even just publish it.

What I'd love instead would be a system based on position papers. Where solutions are proposed, and can be proposed (and are encouraged to be proposed) in parallel. So instead of a list of alternatives that has to somehow appear at the end of an RFC document, we'd have parallel exploration and actually contrast the solutions. The leadership would then make big and small decisions once the dust has settled so to speak. Those decisions being for example hard requirements making some solutions not fit, accepting solutions, postponing things officially as a whole while waiting for some other things to shake out, or stating what features are considered out-of-scope.

The downsides are often not specific to proposals, but general in the problem space. In the case of named arguments, the "should existing argument names become part of the API surface" is a common point that keeps coming back. It seems like the "to which degree is the Rust project willing to require stability from APIs that previously didn't expect to provide it" would for example seem to me like a good candidate to discuss and have positions on in general. Things like this would decrease the design space, and provide a way for more accurate community expectations.

In summary, I'm not sure any guideline would really help here. No matter how many "Pre-"s are in front of the word "RFC", if it's a community wide discussion that's where the minds will meet. And I think the current process lacks the emergence of specifics where the project could say "that's a hard requirement to have/not have for the foreseeable future unless something unexpectedly changes somewhere else".

7 Likes

One small thing I've seen done is separating "this is a pain point we care about" from "this is a solution to the pain point." Discussing the latter is fruitless if you don't agree on the former.

But there's clearly no silver bullet here. There needs to be a space for "out there" proposals, or else design gets bogged down in survivorship bias and tradition, and can fail to discover a "choose three" solution. But at the same time, people's time is finite (but interested newcomers are infinite), so it's a fruitless endeavor to engage every off-the-cuff idea equally.

That's why I frame it relative to burden of proof.

2 Likes

I'm reminded of a proposal in some former year (either on GitHub or on IRC) to have an explicitly written-down, but mutable, set of principles by which to evaluate proposals to change the language, and then to require language change proposals to be evaluated in terms of those principles rather than individual commenters' ad-hoc, essentially subjunctive preferences. I suppose that wasn't a realistic proposal. The closest actual effort towards such a thing of which I know is the unfinished

although that doesn't seem to have quite the same focus on evaluating RFCs.

1 Like

This hasn't been dropped, and we're still working on that.

Are "this" and "that" the Rustacean Principles or the old meta-proposal I vaguely remember? (Or both?)

More so a set of language design principles rather than anything else; various incarnations of proposals have been floated in the last few years. We still care about shipping some version of language design principles.

3 Likes

One common counter argument here is that we want to allow exploration of the design space and not stifle innovation. I'm going to push back on that idea since in practice people do that regardless. There have been numerous blog posts with subsequent discussions here and on r/rust and also threads that started directly here where they usually start of with "I'd like to explore an idea without seriously proposing to change Rust". There's plenty of these posts exploring what-if scenarios and alternatives and that's perfectly ok!

The issue is precisely when people do start a pre-rfc (and indeed it doesn't matter how many "pre"s there are in the title) they have already implicitly assumed "this is a pain point we care about" and the RFC process itself is therefore really about exploring how to address it. The stated intention is what matters here.

In other words, we do have a separation between "should we do this" and "how should we do this". Just that the first part is often skipped and just assumed to be true.

Having a design principles document would provide a framework and context to direct the conversion in a more productive direction without resorting to "he said, she said" kind of arguments.

1 Like