RFC: Reserve throw and fail as keywords in edition 2018

🖼 Rendered
📝 Summary
Reserve throw and fail in edition 2018.
🎵 Note
This RFC separates out the urgent question of keyword reservation from RFC #2426.
It does not prescribe actually adding a fail expr or throw expr construct to the language.

These keyword reservations are starting to get frighteningly close to home.
$ rg '^[^/]*[^\[/]\bfail\b'
src/tasks/config/lib.rs
329:    #[serde(default = "self::defaults::ev_loop::fail")]
330:    pub fail: bool,
380:        pub(crate) fn fail() -> bool { true }

src/tasks/cmd/relaxation.rs
193:                    if self.config.fail {
415:    fail: f64,
423:            sc_token.deconstruct(fail, supercell)?

(I'm surprised I don't have any closures named fail).
Oh, about the [^\[/] in that regex... it's a good thing failure hasn't made its 1.0 release yet. (cc @withoutboats)

it's a good thing failure hasn't made its 1.0 release yet. (cc @withoutboats)

I double checked failure now and it doesn't use fail as an identifier anywhere :)

@ExpHP Hmm... are attributes affected by keywords?

Okay, so I did a proper test of this.
#[macro_use] extern crate serde_derive;
extern crate serde;

#[derive(Serialize)]
#[if]
struct Foo {
    #[serde(rename_all = "lolol")]
    a: i32,
}

I expect one of two outcomes:

If rustc tries too eagerly to parse the attribute name as a path and rejects keywords, this will fail before calling the serde derive.
Otherwise, it will call the serde derive, and THAT should fail

   Compiling playground v0.0.1 (file:///playground)
error: expected identifier, found keyword `if`
 --> src/main.rs:5:3
  |
5 | #[if]
  |   ^^ expected identifier, found keyword

error: proc-macro derive panicked
 --> src/main.rs:4:10
  |
4 | #[derive(Serialize)]
  |          ^^^^^^^^^
  |
  = help: message: called `Result::unwrap()` on an `Err` value: ParseError(Some("failed to parse derive input: failed to parse"))

error: aborting due to 2 previous errors

...okay, that's not what I expected to see, but due to the first error I'd say this falls under the first bullet.  My guess is keywords are currently forbidden here to simplify proc_macro path resolution.

The throw RFC seems to be quite unpopular:

Is there any reason that this unpopularity will change within the next three years?
Also, reserving throw would make a throw! macro impossible which centril himself suggested (unless it is contextual for some definition of that term).

The throw RFC seems to be quite unpopular [...] Is there any reason that this unpopularity will change within the next three years?

I have every confidence some people who dislike the existing error sugar or would rather not use concurrency sugar either will remain opposed to sugar in this area in the future too.
But there are plenty of things that could change.  There may be people who

:-1:'d it as throw but like fail
Dislike the particular semantics proposed there, but like a different version
Want to see a more holistic proposal than just adding the one construct
Change their mind as use of the language evolves
Etc.

And, of course, RFCs aren't a popularity contest anyway.

Also, reserving throw would make a throw! macro impossible

I disagree, just like reserving try doesn't necessarily block try!, and https://github.com/rust-lang/rfcs/pull/2394 reserved await while still having await!.

RFCs aren't a popularity contest anyway.

Surely, the merge descision of an RFC shouldn't sway if there as 30 upvotes and 29 downvotes and now two more people downvote the RFC. But here the number of downvotes is five times larger than the upvotes. That's plenty of room for a sizeable amount of people to change their mind or who are only :-1:  because of the keyword choice.
The statement "RFCs aren't a popularity contest" is technically correct, but doesn't imply that popularity, especially unpopularity, doesn't play any role at all.
Note that for most RFCs, even those which get refused by the language team, there is a "popularity bonus": the number of :+1:  is often larger than the number of :-1:. So if there is an RFC where the number of :-1:  is so much bigger than the number of :+1: , it is a clear sign that the community dislikes it.

I disagree, just like reserving try doesn't necessarily block try!

Right after the try {} RFC was merged @Centril didn't even list that question as unresolved in the tracking issue, he simply assumed that try! would be broken. So why should I believe you when you claim that you want to keep throw! a legal macro? Maybe you don't want that at all and just want the RFC to be merged?

@scottmcm okay I've redacted that particular statement.

Note that for most RFCs, there is a "popularity bonus"

I think that dyn makes an interesting case here:

https://github.com/rust-lang/rfcs/pull/1603, May 2016, 35 :+1: to 58 :-1:
https://github.com/rust-lang/rfcs/pull/2113, Aug 2017, 38 :+1: to 9 :-1:

At the core, those are the same feature with the same syntax.  But over those 15 months, experience and tweaking took dyn from one of the most heavily :-1:'d PRs in this repo to one with broad support.
Will that happen for throw?  Maybe, maybe not.  I've made no secret that I'd be happy if it did.  But I also acknowledge that right now it's contentious, and maybe it will remain that way.

@scottmcm that difference is obviously only because of my early and strong support for #1223 (I was the first to :+1: it) :p. But seriously, that's a good point.

I don't particularly like to debate 👍 and 👎s. I find there are more important things to do.
But since it was brought up, I'd like to point out that the numbers cited by @est31 re. the first throw are not necessarily accurate.
There were a number of people who were in favor of the proposal who didn't use GitHub's "voting" system.
There were others who did 👎 who have said they'd be OK with using fail since it is less evocative of exceptional terminology.
Honestly, at this point, I'd like to revisit @nikomatsakis's point about letting @rfcbot remove 👎s from RFCs with the core team's blessing since these "vote tallies" are being used as arguments from time to time.
But to not fill this RFC with too much off-topic material, I'll raise it in another avenue.

Anyway, there are currently no arguments against reserving fail, only arguments against reserving throw, right?  And some concerns about ecosystem breakage due to reserving fail.

I am not sure about throw and think that overall reaction regarding it is negative, but reserving fail sounds reasonable, but again not ideal, because in my opinion try blocks and try fns should be usable not only with Option, but with custom types as well through successor of Try trait. Thus I think it will be better if reserving fail and throw will be in different RFCs, which ideally should include analysis on how many crates will be affected on migration to 2018 edition, which is especially important for fail.

Several comments in #2426 are concerned that, by developing try functionality incrementally, we're disregarding the error-handling feature at large. This RFC continues this approach, insofar as it splits the throw RFC into a keyword reservation and a language feature. The reasons for doing this are sound--the 2018 epoch gives us an opportunity to modify keywords, and it should be capitalized on. Continuing this approach, however, perpetuates a practice that has been questioned and not adequately addressed.
Several people (myself included) have proposed a from_ok variant of throw/fail (most commonly called pass). I'd like to widen this RFC to include the from_ok variant. There are a few reasons for this:

from_ok and from_err are intrinsically related. They both model early-exits, implicitly convert, and reinforce the "It's just data" nature of result propagation.
The symmetry of these concepts can assist learnability. One of the more compelling arguments for fail, in this regard, is that pass (or another antonym) is clearly related to both the try and fail concepts.
Reserving a from_ok keyword acknowledges that early-exiting keywords are open for debate. It avoids giving preferential treatment to one side of the discussion.

@rfcbot fcp merge
This was discussed in the meeting today; let's move forward pending a concern I'll add...

@rfcbot concern use in macros and attributes
To ensure that this doesn't effect failure, please update the RFC to, like try!, allow these keywords to be used in macro calls (like throw!) and in attributes (like [fail]).

@rfcbot resolved use in macros and attributes
Thanks for always being quick!

I hope we can more often get consensus before merging unpopular RFCs.

@scottmcm: are there any minutes for the meeting? If not, could you recap the parts that relate to this RFC? {I assume the concern about macro calls was raised?)

Should we reserve pass too until the error-handling issue has been settled? Just asking..

@illustrious-you Not a lot of notes, but see the lang team's agenda document for the notes that do exist.
@repax My guess is that such an RFC would not be accepted since it is my impression that there doesn't seem to be much support for it in the language team; but if you want pass or success or something like that reserved, feel free to write an RFC about it.

@illustrious-you This RFC is based on @joshtriplett's https://github.com/rust-lang/rfcs/pull/2426#issuecomment-386137030, and there were no fundamental objections to the reservations.  There were some voices sad that it was only a reservation, not the full feature, but those also acknowledged that the feature was not currently feasible.  (None of those 4 things should be a surprise to anyone who's been following these RFCs.)  So the only discussion was about where the keywords would want to be used in absence of the feature, and what should be done to keep the reservations low-impact, particularly in relation to rust-lang-nursery/failure.

Current reactions on RFC 2426:

So we have 11 :+1: votes vs 93 :-1:  votes.
Also I'd argue that the question of keyword reservation is not urgent as there is the 2021 epoch. We very well can start evolving it right after the 2018 epoch got released. So no need to reserve them inside the 2018 epoch. The lang team itself has postponed RFC 2426 which is basically saying that for now, implementing throw is a bad idea.

@est31 once again:
reactions have no affect on decisions made, and are 100% irrelevant

Also I'd argue that the question of keyword reservation is not urgent as there is the 2021 epoch. We very well can start evolving it right after the 2018 epoch got released.

We cannot do this. All of the things that may break must be in when the edition is introduced. It is important and urgent to reserve keywords now, not later.
(what those keywords are and should be is a different topic, of course)

@est31 Please stop -- this focus on emoji reactions is actively damaging, making every conversation come back to process issues and emotional knee-jerk reactions, rather than the meat of the issues.
The point of separating this keyword reservation RFC is precisely to leave the design space open, no more and no less. The Lang Team as a whole has enough interest in this space that we want to keep options open within the 2018 Edition. And as with all of the proposed keyword reservations, @Centril has done due diligence in assessing the ecosystem effects.

I disagree with calling GitHub reactions knee jerk. Eventually this entire discussion is very meta because it is about whether there should be an opportunity to do A not whether to do A or not. What to do with reactions is best discussed in a separate venue...
Anyway, thanks for replying. I'm not feeling strongly about this "opportunity" RFC in particular anyway so I intend this to be my final comment on this RFC thread. shrug

@aturon What you described as "knee-jerk reactions" is actually quite common in industrial programming environment, especially mission-critial ones. A lot of "nopes" coming from intuition are not signs of being afraid of new things, but aversions of seeing typical bad things that appear over and over again in practice. A lot of these original design decisions are actually the source of the love for Rust, like using Result not throw, no inheritance, optimize for correctness but faster writing (mut as default, etc). These are hard to argue in theory. In some sense, this reaction is more valid than speculations of "some feature may benefit the beginner" because it is formed by a lot of painful experience in mission-critical production environment. It is somewhat simiar to people "learning" through past experiences where the pain is proportional to the severness of the eventual problematic outcome. Disparging the reaction of those who do not have the time to follow all RFCs or the stamina to argue with a stream of RFCs is also not beneficial to create an inclusive community. Like the my comment above, I really hope we can handle unpopular proposals more carefully to avoid alienating a significant portion of the community. I don't want to see "Code of Conduct" or other forum rules are used to justify silencing community members that feel frustrated by the team proceeding without giving proper weight of disagreeing opinions.

@illustrious-you Thanks for your carefully-considered comment; I agree that pass was not given sufficient discussion in this thread, and appreciate you holding the team accountable on that front.
Rather than discuss pass specifically, though, I want to take a step back and raise concerns about the entire keyword reservation project.
Rust 2018 is our first new Edition, and we're trying to figure out how best to use the transition. There are a handful of features that are on the "radar" as possibilities before the next Edition, and the thinking was that it would be prudent to go ahead and reserve the most likely keywords for those features, so that we're in the strongest position should we decide to go forward with those features. It feels like a very conservative stance.
While that makes sense in an abstract sort of way, I think it puts us into an impossible position for discussion: as a community, we haven't agreed on whether we even want these features, but we have to bikeshed them in advance while treating the features themselves as out of scope for discussion. It's no wonder that things keep getting heated!
And anyway, this feels like a problem Editions are supposed to solve, not create. It's seeming to me like the best way to "keep our options open" is to avoid having to reserve anything up front, and instead have a clear way to transition to new keywords after a feature is accepted. Concretely, that might look like having a suboptimal initial syntax (like throw! or do throw) that is "upgraded" to a full keyword at the subsequent Edition.
TL;DR: I think we should establish a comprehensive methodology for growing the keyword set without pre-reservation, so that we can avoid having to "pre-bikeshed" features we haven't yet established consensus for.

FWIW, @aturon, I agree. Something has been bugging me about this whole "keyword reservation" concept and I think you put your finger on it here:

And anyway, this feels like a problem Editions are supposed to solve, not create.

@aturon I agree wholeheartedly with your statement and sentiment regarding keyword reservation.
The C standard, and most web standards, follow a process by which you need at least one and potentially multiple implementations, along with practical experience with those implementations, before even considering including something in the standard. We attempt to do something similar, through the process of first introducing unstable features and subsequently making them stable. But for keywords, in particular, I do think it seems reasonable to first introduce features using macros or similar mechanisms that do not break existing programs, and only consider "promoting" those to full language keywords after substantial experience with them.
Even with the long timescale of editions, we should avoid generating the feeling of "I have to catch this train, I can't wait for the next one". That creates problems. (The Linux kernel has a similar issue, of people rushing to get their code into a kernel version that will become the next LTS kernel, reducing the stability of that kernel.) Our process should be open, welcoming, straightforward, but still deliberative rather than rapid, especially when it comes to language features and keywords. We don't want to be slow, but we should not value speed of making a feature available over careful consideration of whether we should have that feature at all. (Emphasis on "whether", not just "how".)
Even when we see a problem and say "that problem seems relevant", we need to step back, consider other possible solutions, and consider whether we're over-valuing a proposed solution in front of us and under-valuing the current state of the language and things people value that the proposed solution may not.

TL;DR: I think we should establish a comprehensive methodology for growing the keyword set without pre-reservation, so that we can avoid having to "pre-bikeshed" features we haven't yet established consensus for.

This is the well-reasoned approach I've come to expect from the Rust leadership. 💯
You guys are under a lot of pressure, and, in my experience, that always leads to (well-intentioned) myopia. Thank you for listening. ❤
Focusing on the immediate problem: what's the plan for the existing reserve RFCs while this process is fleshed out?
Here's a (likely incomplete) list of the RFCs that propose reservations for 2018:
#2443 RFC: Reserve f(a = b) in Rust 2018**
#2441 RFC: Reserve throw and fail as keywords in edition 2018 (yo dawg)
#2429 RFC: Reserve delegate as a keyword in edition 2018
I assume that async/await (#2394) and try (#2388), both of which completed FCP, are reserved because they're included in the 2018 edition, so there's no need to revisit them?

I assume that async/await (#2394) and try (#2388), both of which completed FCP, are reserved because they're included in the 2018 edition, so there's no need to revisit them?

Now that you mention it, I was under the impression try {} and its many related proposals are still far too controversial to stabilize, so I just assumed they would not be tied to the new edition. Could someone on the official teams clarify what the status of try {} is?

@Ixrec The current status is that try will be reserved as a keyword in edition 2018 and do catch { .. } will become try { .. } in the nightly compiler, but it is nowhere near stabilization and won't be stable in edition 2018 compilers.

what's the plan for the existing reserve RFCs while this process is fleshed out?

Assuming that the Lang Team overall is on board, I think they should be closed and we should work toward a single RFC providing a general mechanism that obviates the need for pre-reservation.

As an aside: I'd like to single out @Centril, who has been doing a ton of legwork trying to help get the Edition in shape, and took on these keyword issues (including doing extensive research) -- and has received the brunt of the pushback that was really about the underlying process. Thanks @Centril!

@lxrec

Now that you mention it, I was under the impression try {} and its many related proposals are still far too controversial to stabilize, so I just assumed they would not be tied to the new edition.

The arguments against it amount to disliking its relation with exceptions. try has its faults, but it's a pragmatic choice. It's familiar to newcomers, compatible with throw/fail/pass/success, is symmetrical with try_ methods, and lends itself readily to a syntactic-sugar match block. In terms of effort and reward, I believe that a the most constructive approach leaves try in place and focuses its argument on flow control, a theme repeated in every RFC and internals discussion on the topic.
@Centril

[try] is nowhere near stabilization and won't be stable in edition 2018 compilers.

In case my prior comment was unclear, when I said that I assume they're in 2018, I meant that I assume the try block will stabilize between the 2018 and 202x edition. As the replacement for do catch, it is necessary to reserve it for 2018 and thus #2388 isn't subject to the to-be-developed keyword stabilization RFC.

I'd like to single out @Centril, who has been doing a ton of legwork trying to help get the Edition in shape, and took on these keyword issues

I second this. These RFCs are heated, and there's additional pressure coming from those that feel blindsided by impl Trait in argument position. Under the same circumstances, I'd be dangerously close to running afoul of the CoC 😨. Not only did @Centril wade into the thick of it, he remained level-headed and inviting as he did so. That matters a lot to newcomers like me. ❤

I guess my comment is better framed as a "yes and" rather than a "no": I think we should establish a practice for "prekeywords" when we dont have an adequate keyword reserved for a feature, but we should also prereserve keywords for features we consider feasible if it would not cause significant churn, without litigating the feature itself when making that decision.

@withoutboats Setting this particular feature aside, I think the argument here is "we should implement features and evaluate them with as little impact on the language as possible before deciding to make language changes to integrate them, which includes keywords". Rather than "let's decide in advance to reserve keywords, which even without any arguments about the feature still determines much of the shape of the feature and creates bias towards particular approaches (and towards doing something over doing nothing)".

@joshtriplett but we have pre-reserved a bunch of keywords, and the evidence doesn't support that contention: they neither shaped the features we implemented in that area, nor created a bias toward action. To give too particular examples:

we reserved do which would support do notation, but chose to implement higher kinded polymorphism in a manner which is not ideal for supporting do notation, and have no intention as of now (3 years later) to introduce do notation proper.

we reserved become to support tail call optimization, but have never felt any strong impetus toward acting on implementing it.

we reserved virtual, but when we considered using virtual Trait syntax, we still went with the new keyword dyn

There's a big difference between "we reserved a pile of keywords in Rust 1.0 just in case, because we don't know how or if we can introduce new keywords later" and "we're reserving these specific keywords with this specific feature in mind".

@joshtriplett It's certainly true that by reserving keywords we add to the momentum towards particular change-- it enables the change, makes community members aware of the intention, and comes with some amount of mental attachment. I can totally see myself thinking something along the lines of "Oh come on! We reserved the keyword, we're so close! Let's just ship this already!".
Like @withoutboats, though, I think that the flexibility afforded by keyword reservations outweighs the costs, and I don't think I would ever go so far as to make an explicit argument in favor of a change simply because we went to the trouble of reserving a keyword. As @withoutboats noted, there is precedence for us not acting on features with "ready-made, pre-reserved" keywords like do-notation and tail-calls. At the end of the day, I trust myself and the other lang team members (especially you :smile:) to be accountable and not ship features without properly weighing the costs and benefits, regardless of any keyword-related momentum.

this focus on emoji reactions is actively damaging, making every conversation come back to process issues and emotional knee-jerk reactions, rather than the meat of the issues.

If an RFC has overwhelming feedback one way or the other, even if just via emoji, it need not change the team's decision, but I think the team should aim to communicate why they chose to go against that feedback when making a decision on an RFC.
All RFCs have components which cannot be objectively reasoned about: everything from syntax bike-shedding all the way up to the general direction the language should take are highly subjective, and for those subjective decisions, a simple tally provides far more signal than a thread full of vacuous comments reiterating the same opinions from those people that have the time to follow what's going on.
Yes, objective reasoning should be preferred where possible, but it's also possible to make all "objectively correct" decisions and end up with a language that nobody wants to use.
As an example of how this could be applied, take this RFC: the highly negative reaction is likely towards the "throw" feature itself rather than the mere idea of reserving the keyword. Explaining this and re-emphasising that the acceptance of this RFC does not imply any commitment to implementing that feature would have gone a long way towards cooling emotions, even if that statement may end up seeming repetitive from the team's point of view.
I particularly take issue with @steveklabnik's decision to stick in big letters "reactions have no affect on decisions made, and are 100% irrelevant", and @Centril's attempt to introduce a censorship tool to the RFC process through the back door without proper process. They're not only misguided, but they present an extremely hostile view of the Rust project to anyone reading this thread.

the highly negative reaction is likely towards the "throw" feature itself rather than the mere idea of reserving the keyword.

The entire problem with emoji reactions is that you have no idea what the reaction was towards. All you know is that someone at some point in the RFC disliked something about it. Were they objecting to a previous revision of the RFC that has since been fixed? Were they objecting to the "throw" feature itself? Were they objecting to the reservation of tons of keywords "just in case"? There is basically zero useful signal in a 👎 or 👍 or 😕.

a simple tally provides far more signal than a thread full of vacuous comments reiterating the same opinions from those people that have the time to follow what's going on.

Emoji reactions did not exist for the majority of the lifetime of the RFC process. I don't remember massive threads full of vacuous comments during that time period, but I may be suppressing the memory!

@sfackler Just as a "devil's advocate" point, there are various variables not accounted for in that anecdotal comparison:

Rust wasn't as popular then.
The community was skewed more toward early adopters.
We haven't established whether any of those responses evoked a set of reactions comparable to this.

I particularly take issue with @steveklabnik's decision to stick in big letters "reactions have no affect on decisions made, and are 100% irrelevant", and @Centril's attempt to introduce a censorship tool to the RFC process through the back door without proper process. They're not only misguided, but they present an extremely hostile view of the Rust project to anyone reading this thread.

Is your problem with Steve's post that what he said was true, or that he said a true thing out loud? Is it worse censor (really?) people's emojis or to leave them there and give those people a false sense that they're influencing an RFC in a significant way? Would anything be different today if I used a browser extension that just hid them on my end?

@sfackler Good to know, but that still doesn't address the other two points. It's still possible that the slice of the community who use emojis now has a larger proportion of potential vacuous commenters than it did before.
Either way, I think it's a public relations issue.
Feel free to say "we need more than just an emoji to make an informed decision" but saying that they have absolutely no impact makes the Rust community seem less welcoming. At the very least, you want people to be able to assume that a lot of downvotes will make you more focused on seeing out "why" people are downvoting.
Likewise, if nothing else, they serve as a way for for people to safely dissipate emotional "Do something!" reactions (hence their role as a successor to +1/-1 posts), so they shouldn't be removed.

If GitHub had never added the emoji reaction feature, would there be tons of people clamoring for a low effort way to react to RFCs without actually commenting?

At the very least, you want people to be able to assume that a lot of downvotes will make you more focused on seeking out why people are downvoting.

What does that actually look like? The entire point of an RFC is to actively seek out feedback on an idea. We could make a comment that @mentions every person who added a reaction asking for more explicit feedback, but that just gets back to the core idea that we really need people to be explicit about their feelings to get useful information out of it. I could also see people feeling that they're being "called out", which could be kind of scary for someone who's nervous about first poking their toe in the contributing-to-an-open-source-project waters.

Is your problem with Steve's post that what he said was true, or that he said a true thing out loud?

Both:

I don't think it's true, or if is true, I don't think it should be. Reactions should be taken into account. Just because something is taken into account doesn't mean that it has to be the overriding factor in a decision.
The way it was written and formatted comes across as particularly hostile towards the community.

Is it worse censor (really?) people's emojis or to leave them there and give those people a false sense that they're influencing an RFC in a significant way?

I personally believe it is worse. Yes it's only an emoji, but the problem is that you're silently modifying what people think they have posted online, and that feels like much more of a violation than if adding emojis was disabled to begin with. If anything, removing emojis with such a system is far more likely to give a false sense of influence, since the user doesn't even know their reaction has been removed, and you're assuming that they have an inflated sense of the importance of their reaction to begin with.

If GitHub had never added the emoji reaction feature, would there be tons of people clamoring for a low effort way to react to RFCs without actually commenting?

This was precisely the reason github added the feature to begin with: there was an open feature request for this with a lot of support.

This was precisely the reason github added the feature to begin with: there was an open feature request for this with a lot of support.

With support from people specifically with an eye towards rust-lang/rfcs?

If anything, removing emojis with such a system is far more likely to give a false sense of influence, since the user doesn't even know their reaction has been removed, and you're assuming that they have an inflated sense of the importance of their reaction to begin with.

The fact that there aren't any reactions might be something of a hint, but it's at best a hack around the lack of ability to configure reaction support on a repo.
In any case, in what way did Centril try to introduce this thing through a backdoor? As far as I know, no one had decided that this thing was going to actually be used. It hadn't gotten to the point of going through whatever process would be needed! What indication existed that this was just going to start mysteriously happening?

@sfackler

What does that actually look like?

That's the thing. It doesn't overtly "look like" anything unless you make a formal research project out of it to compare behaviour between RFCs with similar attributes, some with emojis and some without... it just allows people to feel some comfort in the sense that they've "helped to guarantee" that those considering the problem won't allow themselves to get lax when considering and deliberating.

We could make a comment that @mentions every person who added a reaction asking for more explicit feedback, but that just gets back to the core idea that we really need people to be explicit about their feelings to get useful information out of it.

I see three problems with that.

I add emoji on the initial post in addition to commenting, in the hope that doing so is the course of action that will present the most representative first impression.
People who only add emojis are likely to be people who are un-practiced in the kind of introspection necessary to tease out the cause for an emotional reaction.
I agree with your concern about the fear of being "called out" being off-putting.

Essentially, you'll shoot yourself in the foot if you try to force a clarification out of people who don't understand why they dislike something until they someone else's comment and it resonates.
(At the very least, you'd want to limit it to people who emoji'd without posting any comments or +1-ing anyone else's comments, and do it as a single comment that mentions every one of them (ie. at the transition to FCP) and asks "Would you mind checking if anyone else's comment puts words to your concern?")

If anything, the ability to make low effort 👎 reactions to RFCs is what is unwelcoming. If what we want to do is encourage participation of people in the design of the language and in particular that they can propose something -- such that it is not the solve preserve of team members with authority, then those type of reactions hurt.
Honestly, if my very first RFC was hammered with 100 👎  reactions and then subsequently closed because of the negative reactions and not due to technical reasons as evaluated by the team, then it might have been my very first, and very last RFC.

Essentially, you'll shoot yourself in the foot if you try to force a clarification out of people who don't understand why they dislike something until they someone else's comment and it resonates.

So I am damned if I do, and damned if I don't. Great. In this scenario, can not ask for clarification, but unsubstantiated reactions must still be given weight by the teams.

So I am damned if I do, and damned if I don't. Great. In this scenario, can not ask for clarification, but unsubstantiated reactions must still be given weight by the teams.

I never said that. I said that:

The sense that "skilled input or nothing" is required is off-putting. (I can attest to this. The term Pre-RFC had enough formality that it scared me away from even considering whether I might be someone who could produce.)

A large number of unsubstantiated reactions should spur further attempts to seek out what concerns said responders might lack the words for.

The sense that "skilled input or nothing" is required is off-putting.

We don't require that input given be right or very elaborate. You can say something that is brief or technically or subjectively wrong in the comment and in the latter case someone will let you know how it was wrong. This way, both sides can actually learn something.

A large number of unsubstantiated reactions should spur further attempts to seek out what concerns said responders might lack the words for.

But how? If the author is not allowed to ask people, who reacted negatively, for feedback, how do you then seek out their concerns? Just leaving a comment asking for clarification, which does not tag the people involved will most likely not be replied to, because thumbsdown are mostly drive-by. Most of the time, the concerns of people leaving negative reactions have also already been addressed.
PS: I suggest this increasingly off-topic line of discussion be moved elsewhere.

It doesn't overtly "look like" anything unless you make a formal research project out of it to compare behaviour between RFCs with similar attributes, some with emojis and some without... it just allows people to feel some comfort in the sense that they've "helped to guarantee" that those considering the problem won't allow themselves to get lax when considering and deliberating.

I'm confused. I thought the purpose of reacting was so people could assume that "a lot of downvotes will make you more focused on seeking out why people are downvoting." If we aren't actually going to do that, then.....?
You aren't going to need a formal research project to figure out roughly why someone would be unhappy with an RFC, but the whole point here is that knowing roughly isn't good enough! The specific reasons have a huge impact on how that impacts the decision being made!
There are multiple plausible reasons I can see off the top of my head for why someone would oppose this RFC:

Someone opposes the idea of reserving throw as a keyword. They commonly use variables or methods named throw and the migration would be painful. If this is a common reason for opposition, then it indicates that we shouldn't merge the RFC, and look into other options (maybe other keywords for the same idea, or trying to make a contextual keyword).
Someone opposes the thing we're going to use throw for, but doesn't have a problem with it becoming a keyword per-se. This is est31's very helpful clarification of their own reaction! In this case, this doesn't really block this RFC at all per-se, as long as we're careful to be clear that the keyword may never be used, or be used for a different purpose. This is a pretty common occurrence in the history of the language - proc, priv, do, become, virtual are all keywords that have never been used.
Someone opposes the "keyword land grab" that has popped up in the lead up to the epoch, as aturon mentioned above. In this case, we need to rethink the whole approach to keywords and epochs, and probably not land both this RFC and other keyword reservation RFCs.

This is exactly why reactions provide ~zero information. We have three plausible reasons someone could oppose this RFC, and each one leads to totally different conclusions about the decision that should be made!
What you end up with is that reactions are at best a sort of placebo that allow people to feel like they've contributed (and may or may not actually no they're not really), and at worst end up being weaponized like Centril mentioned above.

The sense that "skilled input or nothing" is required is off-putting.

There is definitely a barrier to entry to contribute, but it seems more honest to acknowledge that fact and help people into it than to give them a sort of "placebo" button that allows them to feel like they've contributed (but maybe haven't really).

A large number of unsubstantiated reactions should spur further attempts to seek out what concerns said responders might lack the words for.

You're really going to have to outline specifically what that looks like.

I hate to do this again this week, but I'm (temporarily) locking the thread to stop the emoji issue from taking over yet another discussion (and note that the dedicated thread on internals also had to be locked).
I would like to ask everyone to please take a breather after a rather high drama week; I don't think any of us are at our best right now. More specifically, please let's put aside the emoji issue for the next couple of weeks.
I'm going  to minimize the most recent emoji-related comments as off topic, and keep the thread locked for a bit, before we return to discussion about the overall strategy on keyword reservations.

Getting back to the general question of keyword reservation strategy, I wanted to pitch a concrete proposal.
We've long shied away from allowing feature flags on the stable compiler, because we want to avoid stable Rust becoming a collection of slightly-different dialects, with crates typically starting off with a long preamble of dialect tweaks.
Editions already take one step away from this: there is a single overall flag, useable on stable, that switches you into, in some sense, a different dialect. The fact that these "dialects" comprise 2-3 year periods with a monotonic forward march, however, makes it all seem tolerable.
I wonder if we can take one more small step in this direction:

When stabilizing a feature in edition N that requires new keywords, the feature flag is usable on stable and is needed to opt in to the new keyword.
Switching to edition N+1 automatically opts in to all previous feature flags.

Some observations:

This approach allows us to introduce new keywords at any point, obviating the need for reservation

@withoutboats's point still stands, though: registering a keyword early decreases the likelihood that it's used in the wild, thus decreasing migration costs

The migration/interop story is the same as with editions
This approach makes it more possible to use edition N+1 features prior to fully moving to the new edition (which may be a pro or a con)
Within any given edition cycle, there are likely to be a very small number of new keyword introductions, so the set of flags is very small.
The fact that the flags are obsoleted in the next edition means that their usage doesn't grow unboundedly
The effect on compiler complexity is negligible, since all such cases would already require conditional logic; the only change is that the conditional used is broken down by keyword, rather than by edition.

On one hand, this suggestion would solve this "urgency" issue, on the other hand, it would open the gates for more breaking changes.
One problem is the testing story. If you have X features, you have 2^X many different ways to enable/disable them. Testing each variant might prove hard, which might be required though if features are not orthogonal but interact with each other.
It might give Rust a name of a constantly breaking language. Sure, people can just stay on the current edition and not enable any of those features but it might happen that most people don't do that and instead code on the always newest version of the language because that's considered the most idiomatic one. Books containing Rust will get outdated even faster.
Cpp has releases once every three years, while we release once every six weeks. I think that a schedule of performing breaking changes once every three years is absolutely okay.
What we could and should do however IMO is to start evolving the next edition on the nightly channel the moment we release a new edition. Sort of a train model for editions. This way, different things can be tried out by a larger userbase.
While I am mostly critical, I think the idea definitely has merit as it would allow us to experiment with stuff on the stable channel and maybe even decide to avoid or remove features inside the next edition.
E.g. many people were surprised when they heard about impl Trait in argument position or at least the early stabilization of it. If it got shipped behind a stable feature, people might have tried it out earlier and maybe the next edition would have disabled that feature, making it only available on the 2015 edition and only if you opt in. This would deter people from "mixing together" their own favourite language subset. IDK I think I still prefer a liberalization of language frontends where Rust serves as lingua franca.

@est31 note that I am making a narrower proposal here, relating only to features that introduce new keywords (and for which contextual keywords don't work). I would expect there to be a very small number (0-3, say) of these per Edition. It also means that the "testing matrix" can be kept very simple, since we're talking about an extremely narrow part of the front end.
So, for example, this wouldn't have any bearing on something like impl Trait, and the issues there are IMO not related to this discussion.

@aturon While it took some getting used to, I honestly think that we shouldn't use feature gates for this. To some extent, I think it would help to ensure that any new feature has to wait a while before getting a keyword, and has to get by without one for a while (outside of nightly), while gaining experience with the feature.

I definitely like not being forced to reserve a bunch of keywords up front that we may or may not end up using, but it seems like it could end up being kind of confusing to have a couple features work on stable, but the rest not.
Since the only part of the feature that needs special handling is the keyword itself, we could maybe use a separate attribute - #![keywords(throw, async)] for example, that would opt-in to those identifiers being keywords in the crate. The underlying feature itself would always be there, you just couldn't use it unless you opt-into the keyword that it requires.

@joshtriplett I'm personally not comfortable tying our ability to ship features so strongly to the Edition cycle. It already takes a very long time for significant new language features to stabilize; I don't think we need additional roadblocks.
@sfackler agreed, that definitely feels more clear.

There’s something I don’t get. We want to reserve two keywords (throw and fail) for future uses (I guess the RFC on throw blocks / expressions) and we acknowledge that we’ll introduce breaking changes (people having fail functions defined for instance). Then, my question: is the reservation really needed, even if the feature is not there yet? If not, cannot we just wait for the actual feature to be merged in order to take the keywords in the same time? In both situation, there’ll be the same breaking change, so why not postponing the breaking change as much as possible?

If you reserve the keyword right now, you introduce a breaking change without adding an actual feature.
If you take the keyword along with the stabilization of the feature, no breaking change until the actual release of the feature, and once people have fixed their breaking code, they get a new feature as counterpart.

I’m not making a point here, just throwing things out of my mind and wanting to know more about the motive of this reservation.

I like the idea of keyword gates, but it can lead to some community members arguing that "feature" is just as likely going to cause backwards incompabitlies as a "keyword" addition.
think like auto traits, "pin" or possible implicit conversions being added.
@aturon , I was wondering if their were any more documentation on how editions were going to affect RFC Proccess? your own questioning about keyword reservations makes editions, werent super thought out yet in relation to editions

The use of a "keyword gate" seems like a parsimonious solution to the problem of keywords, especially if the gates get "garbage collected" into an edition every few years. The problem of introducing keywords is that it breaks old versions of code that is no longer maintained, by requiring a gate we avoid that problem. And, if we restrict this usage only to keywords, we don't have any of the dialectical explosion problem that we've feared about enabling feature gates on stable. All on all, I think this adequately resolves the problem.

To some extent, I think it would help to ensure that any new feature has to wait a while before getting "promoted" to have a keyword

A keyword is rarely a signifier that a change is particularly significant. Most of the largest changes have involved no new keyword introductions - GATs, const generics, the module system changes, etc. It does not seem correct to me to say that keywords are some highest level of significance that we need more experience with, especially since we will have to support the feature, using the "non-keyword" solution like delegate!, even if we were to decide not to "promote" it to having a keyword.

Apologize for the brevity here, I am extremely jetlagged.

I wonder if we can take one more small step in this direction:

When stabilizing a feature in edition N that requires new keywords, the feature flag is usable on stable and is needed to opt in to the new keyword.
Switching to edition N+1 automatically opts in to all previous feature flags.

This was one of the original models we proposed for editions generally, but was rejected. What's changed since then? It'd be worth re-exploring.
I'm also very wary of doing this now. Yes, the keyword thing is a pain right now. However, this would be making a pretty sweeping change to a system of change we're using for a long time, but the keyword issue will diminish over time. I'm not sure that optimizing for fixing this problem is the right tradeoff.
In the interest of thinking out of the box, here's a super super strawman proposal: take the top ten or fifteen or even twenty languages, and reserve all of their keywords now. It doesn't cost a ton, and would near eliminate this problem.
(Maybe my post-jetlagged brain will think this is a bad idea....)

This is a bit late, and I haven't read all messages, but I personally hate having too many keywords. Encountering a conflict between the name of your variable and the name of a keyword halts your programming for a while just to find a suitable alternative, it breaks your flow.
I really feel like rust is going down that route, and I already find it unfortunate that type isn't just contextual, because there's many times where type is a very useful identifier. fail would heavily conflict with the failure crate most likely, and throw could really just be a macro.
If a clean syntax like throw expr is desired instead of throw!(expr), couldn't one just allow macro invocations of the form macro! argument, such that throw! expr would be legal?

@steveklabnik, I was wondering on exactly what basis was for blocking keyword gates idea?,
there only two problems with your super strawman propasal is

we would have way too many keywords now(most that we wouldnt use anyway!)
deciding what languages to pull from(everyone also likes there own other language)
(my personally recommendation would be take 10 from like the tiobe index)

Holistic treatment of error handling
@illustrious-you You have asked for a more holistic treatment of error handling; I've tried to outline a "master plan" here. I believe this long term proposal makes sense from a monadic perspective. Of course, this is just my current thinking and it by no means is the goal of everyone ;)
Regarding pass, I believe I was the originator of that idea or the keyword at least. I've since changed my mind and I think it is a bad idea. Primarily for the reasons @withoutboats's outlined then to make the "happy path" the normal path (and so pass makes it special...). My point is not to litigate the pass feature here.
I would not personally mind reserving one version of pass as a keyword. However, I do not think it should be done in this RFC. If you want that option open during the next edition, please write such an RFC and I will most likely support it proviso that there has been research done into what keyword(s) are most appropriate and the extent of breakage as done in this RFC.

Regarding #[fail] and throw!
@Laaas quoting the RFC's text:

The keywords will still be permitted as attribute names and as macros, i.e: #[fail] and throw!(..) calls is permissible.

The macro invocation form mac! expr has been discussed and throw! expr is a possibility; But I think we should keep our options open so that we can make that choice one way or the other and not foreclose on possibilities.
On many vs. few keywords

This is a bit late, and I haven't read all messages, but I personally hate having too many keywords.

Not having enough keywords also means that it becomes harder to extract and read meaning from programs because they will reuse the same keywords for many different things. I don't think that helps particularly. The name throw in particular also seems unlikely as an identifier beyond as the name of a macro, but that has already been addressed.

Negative reactions to this RFC
First a note on the negative reactions to this RFC. They mostly seem to be negative reactions to the feature throw or fail would be used for, not for reservation per se. For example, RFC #2429, which aims to reserve delegate, with more or less the same motivation, has had nowhere near the same negative reaction and instead it has been mostly positive.
Continuing with the current plan
Thumbs on the scale?
I think it is worthwhile to consider reservation alone. In my view, we should stay the current course. I wholeheartedly agree with @withoutboats's assessment that: just because we reserve new keywords, that does not at all mean that we must implement a certain feature using that keyword or that it must be implemented at all. It is good to make this clear.
As @aturon put it:

The point of separating this keyword reservation RFC is precisely to leave the design space open, no more and no less. The Lang Team as a whole has enough interest in this space that we want to keep options open within the 2018 Edition.

I do not think that we are, to a notable extent, putting our thumb on the scale in favor of adding such a feature. To the small degree a thumb is put on the scale, it seems well motivated by @aturon's note that the team did have enough interest in this space (and the specific proposal at #2426..). Further, experimentation is already happening in failure with its throw! macro. We are even reserving two keywords just to ensure that we don't bias prematurely in favor of exceptional terminology from Java-like languages (which fail is not..). In fact, not reserving could be construed as the exact opposite: putting the thumb on the scale for making this change harder in the future.
With respect to @steveklabnik's proposal to even go further and reserve more, I personally think that is fine, to the extent it respect's @withoutboats's comment that:

I think we should liberally reserve keywords we see a likelihood of using, our hands stopped only by the impact on the ecosystem (ie how often that keyword is currently being used as a symbol).

@joshtriplett notes that:

There's a big difference between "we reserved a pile of keywords in Rust 1.0 just in case, because we don't know how or if we can introduce new keywords later" and "we're reserving these specific keywords with this specific feature in mind".

I don't particularly agree with this. We can also make a conscious choice to not make such a difference by adopting / maintaining the view due to @withoutboats's mentioned above. As @cramertj noted, I agree, @joshtriplett is exceptionally capable of ensuring this.
I would also like to highlight boat's comment that:

we reserved virtual, but when we considered using virtual Trait syntax, we still went with the new keyword dyn

This provides evidence of the team's capability to make such choices and that the thumb is really not on the scale.
Social reasons for doing this now
First I again want to highlight that pre-reservation intrinsically doesn't seem particularly contentious as I previously discussed wrt. delegate. Rather, most contentiousness seems tied directly to throw/fail expr as a feature.
I also second @steveklabnik's point on being wary of such a change to the edition system at this late point. It seems to me an even more contentious issue to introduce #[keyword(..)] as a flag usable on stable compared to the limited number of reservations this edition. I think it is something to consider for the next edition, and should be given ample time to be considered and not rushed. If such a proposal is also not accepted before edition 2018 lands and this RFC is closed, then there is no way of knowing if that solution will be available for edition 2021.
Editions are the currently accepted mechanism
With respect to editions being or not being the right mechanism for introducing new keywords, I want to highlight Aaron's comment in the epoch RFC:

It's often the case that we know relatively far in advance that we might want a given keyword. We can consider being fairly liberal in reserving additional keywords to carve out space for the next cycle.

The RFC also states that:

Sometimes a feature we want to make available in a new epoch would require backwards-incompatible changes, like introducing a new keyword.
[..]
The simplest example is adding new keywords: the current implementation of catch uses the syntax do catch because catch is not a keyword, and cannot be added even as a contextual keyword without potential breakage.

This applies exactly to throw and fail. They can't be contextual precisely for the same reasons as try (previously catch) can't.
It is true that the RFC states that:

When opting in to a new epoch, existing deprecations may turn into hard errors, [..] This is the only kind of breaking change a epoch opt-in can make.

However, thus far, this has been interpreted as a warning sufficing as "deprecation" with the acceptance of try, async and await, neither of which were deprecated other than by the usual warning:

warning: type await should have a camel case name such as Await

Technical reasons for doing this now
I think the technical case for the solution in this RFC and similar ones is clear generally, and specifically wrt. this coming edition. It causes less churn because we are bundling together small breakage in the form of keyword reservation with large ones in the form of module changes. Having a form of temporary #![keywords(..)] which then becomes incorporated into edition 2021 will also add more technical debt and you'll need to keep the macro based version stable forever. The general conclusion in the keyword policy seemed to be to optimize for reducing technical debt and maintenance, I think it was a sound plan and in my view, we should stick to it. Add to this the argument due to boat's paraphrased by Aaron as:

registering a keyword early decreases the likelihood that it's used in the wild, thus decreasing migration costs

This answers @phaazon's question about why we shouldn't wait and postpone the breakage as much as possible.
Conclusion
I believe that continuing on with the plan so far of a "somewhat liberal, but mindful of breakage"-policy as we have until now by reserving keywords is both the technically and the socially conservative option that is also the currently accepted one as an RFC and is consistent with what we have done so far. There is also support for the feature itself within the language team, which should count for something. During next edition, we can optionally amend the edition process with #![keyword(..)] but the time for that does not seem to be now.

For what it's worth, as someone who is extremely skeptical about all variations of throw/try/etc syntax, I completely support this keyword reservation as a straightforward way to keep our options open going forward. Perhaps more importantly, this is a safe way to let us stop spending so much of everyone's time and energy on this throw/try/etc syntax debate that clearly won't get settled before the new edition needs to ship.
The only real question in my mind is where do we stop. It sounds like the sum total of all current proposals is to reserve throw and fail, but to not reserve pass or delegate (and those four are the only serious candidates I've heard of). Is that correct? If so, is there a specific reason why the first two are in and the other two aren't? (every reason I've seen given so far seems to apply equally to all four)

@Ixrec The keyword delegate is also in FCP merge at the moment. However, @nrc has noted a concern specifically with respect to the extent of breakage for delegate, which does seem relatively more used than the other keywords. So there's a specific technical reasons here why we might not want to reserve it as a keyword. Furthermore, delegate can be contextual in the obvious ways we've thought of using it, whle try / throw / fail / pass can't be contextual. Tho I still think that for the sake of consistency and future proofing, we should reserve it as a real keyword. Let's continue that discussion over at #2429 tho ;)
With respect to pass, I've done an initial technical review:

It is not used as an ident in the standard library.
It is used as the name of a crate, but it has zero reverse dependencies.
Sourcegraph reports that there are 2+ uses which could be part of public API.

While I'm fine with reserving pass myself, I think it might somewhat bias in favor of fail as it is the natural antonym, so that should be considered (should a different synonym like wrap be reserved instead?). pass also means skip in python, which has a sizable user base that can't be ignored. Given the ubiquity of the language as a bash replacement on linux, not causing confusion with it seems important.

I’ll admit I myself was viewing this RFC through the prism of the feature that would eventually be behind these keywords (and had neutral-negative view of the RFC), but I’m definitely fine with just the keyword reservation.

(For the record, I'm fine with the keyword reservation as well in this particular case, though I do share @aturon's concern about falling into this pattern repeatedly for other keyword changes.)

❤

Some random thoughts  to your random suggestion... ;)

As a random suggestion, by way of evocative syntax: what if, instead of keywords, we used ok! and err! macros?

It is an interesting suggestion to entertain going forward; those would have to be macros because both ok and err are taken identifiers as method names of Result. They don't have the advantages of the familiarity of throw but they do have the advantage of familiarity with Result. However, it might be too tied to Result as a type, confusing users in the context of Option<T> for example with:

"Wait what, I thought this returned a Result... why is it returning an Option?"

The trait Try is unstable so the naming of Try::from_ok and Try::from_err don't matter much at this point :)

(And as discussed a few times, we could allow a zero-argument version of ok!() as a synonym for ok!(()).)

Hmm... I recall we discussed a more general mac! expr such that you could write fail! MyError::Foo. That would certainly make macros feel more keyword-y, which would be nice. Tho I think that if async is given the first class feeling of await as a keyword, it makes sense for try to get something too ;) Still macros have drawbacks compared to real keywords -- if you are inside a proc macro, there's no way to know that ok! really refers to the macro, or some other imported one; Source code analysis by IDEs and such also becomes harder.

Thoughts on alternatives to pass:

wrap  -- antonym to "unwrap"; the objection here might be that the naming might "wrap" an "unwrap" (i.e: catch_panic), but I think that is a stretch. It fits well imo.

succeed -- this is clearly longer, but only one character longer than return and one shorter than continue, so it is of acceptable length according to our current set of keywords.

okay -- this is not a verb (unless you okay something), so it is not really a serious suggestion... feel free to ignore this ;)

break -- per my plans outlined here; This fits with the current Ok-wrapping plan (which I'm a fan of..). In a world with try fn and try, it makes refactoring easy because try fn { BODY } is literally
fn ... { try { BODY } }. The main drawback of using break this way is loop { try { break; } }. However, it can be disambiguated with loop { try { break 'loop; } } which should be clear. There is also precedent to divorce break from being tied only to loops with label-break-value. As outlined in the "master plan", break could become the universal "break to closest control flow block" (which then includes fn, try, while, for, loop).

return -- the objection here is that return has a strong association with early return to the function such that try { return 1 } would be confusing. This is the main reason why return 'label expr was rejected.

@Centril

You have asked for a more holistic treatment of error handling; I've tried to outline a "master plan" here. I believe this long term proposal makes sense from a monadic perspective. Of course, this is just my current thinking and it by no means is the goal of everyone ;)

I believe that, while Result is a monad, thinking of the try feature exclusively in monadic terms is too limiting. Rust is an imperative language and there's nothing limiting try/? to pure functions. Monads are instructive, but are too general a guide to the feature--if this weren't the case, we'd be discussing do semantics.
I have a few questions about the "ok wrapping" part of your "master plan":

Adding another keyword seems wasteful and creates problems for Ok-wrapping in the tail position.
...
try and try fn do Ok-wrapping in the tail position.

Am I correct in thinking this is a problem because a user might believe the tail position should be Ok(val) instead of just val?
Have you considered my proposal that there should be a lint for using fail without pass? (I imagine this would be linted at the "allow" level, and promoted if this usage became popular.)
Have you considered that try fn isn't necessary if fail and pass are used for "err wrapping" and "ok wrapping"? (That is, return is for values, top-level pass ok-wraps a value and returns, top-level fail err-wraps a value and returns. All methods that return a type implementing the Try traits would automatically support all three return types, the same way they already support ?. try is a block that scopes ?, pass, and fail)

@Ixrec

It sounds like the sum total of all current proposals is to reserve throw and fail, but to not reserve pass or delegate (and those four are the only serious candidates I've heard of). Is that correct? If so, is there a specific reason why the first two are in and the other two aren't? (every reason I've seen given so far seems to apply equally to all four)

delegate was pulled in only because it relates to the "keyword reservation strategy" @aturon proposed.  I agree with your assessment that the reasons for including throw and fail also cover pass (or its successor).
@Centril

The trait Try is unstable so the naming of Try::from_ok and Try::from_err don't matter much at this point :)

In fact, it's arguable that the early-exit keyword(s) are the x in Try::from_{x}. (That's an assumption I left unstated in my "dialectical ratchet" argument for pass.)
Finally, with regard to further bikeshedding of pass, I'd like to refer back to "@withoutboats 's Razor":

[Liberally] reserve keywords we see a likelihood of using, our hands stopped only by the impact on the ecosystem (ie how often that keyword is currently being used as a symbol).

An argument for an alternative keyword to pass is an argument to add said alternative to throw, fail, and pass. So long as the concept of a pass keyword is preserved, add as many variations as is prudent.

While I'm fine with reserving pass myself, I think it might somewhat bias in favor of fail as it is the natural antonym, so that should be considered (should a different synonym like wrap be reserved instead?).

Lest we forget, try already FCP'd. I could argue the bias swings in the other direction, but would rather believe that the RFC process can avoid bias by making decisions on the merits.
Those merits fall to semantics: Is try about error handling, or is it about control flow.

@illustrious-you

Am I correct in thinking this is a problem because a user might believe the tail position should be Ok(val) instead of just val?

You are indeed correct. That is, in fact, my position; try should not wrap its return value.

Have you considered that try fn isn't necessary if fail and pass are used for "err wrapping" and "ok wrapping"?

Agreed.

Am I correct in thinking this is a problem because a user might believe the tail position should be Ok(val) instead of just val?
Have you considered my proposal that there should be a lint for using fail without pass? (I imagine this would be linted at the "allow" level, and promoted if this usage became popular.)
Have you considered that try fn isn't necessary if fail and pass are used for "err wrapping" and "ok wrapping"?

All these are sub-parts of the broader disagreement here, between

The mental model position (MM), where try/? is about moving along being success, and
The control flow position (CF), where try/? is about a scoped conditional return-like construct.

Looking again at the questions:

MM believes that val is sufficient, because the value from the last expression is obviously success, since it didn't break early, so mentioning the constructor explicitly is unnecessary.  CF believes that there's no intent inherent to the position, so obviously the constructor needs to be mentioned specifically.
MM believes that (non-tail) pass is outside the model, so shouldn't exist, and such code is best written without the sugar to emphasize its unusualness.  CF believes that the construct must support both equally, so pass&fail must both exist, and there's no reason to use one if not also using the other.
MM believes that the model is most appropriately selected at the function level, so try fn is essential as the most common case.  CF considers pass/fail as control flow essentially like return, so no extra function-level meaning is needed or wanted.

(Please correct me if I'm mischaracterizing the CF position, as I unsurprisingly prefer the other.)
I'd rather not continue the philosophical debate between the two positions at this time.  That said, I would encourage anyone in favour of pass to write a concrete RFC about it, perhaps just as a pre-RFC in IRLO for now, to explicitly elaborate the motivation and invite the same level of scrutiny that throw received.

@scottmcm I'm not sure where the names "mental model position" and "control flow position" come from, here. For me, this is about 1) type-based reasoning (a thing of type Result should return a Result) and 2) visibility of the underlying mechanism (a function returning Result should have both Result and Err/Ok visible, or an equivalent). Invisibly wrapping a final value with Ok fails on both counts.

Invisibly wrapping a final value with Ok fails on both counts.

Can you please find a phrasing other than "visible/invisible" for this?
It seems trivially obvious to me that
let x: Option<u16> = try {
    4
};

Is no less visible (nor type-based) than, say,
let x: Option<u16> = From::from(
    4
);

Which of course works fine today.

@scottmcm
Thank you for elaborating. I don't have a strong background in the theory of programming. What I do have, especially when it comes to functional programming, I've absorbed only when it has a practical application in my work. (The State and IO monads, for example, confound me.) I asked those questions because I don't know the answers. I offer my apologies for continuing to go off-topic. :)
I'm interested in blending both positions, because I see practical applications in each. What I need to find is a compelling example that uses fail and pass to avoid mistakes. I believe the pattern could be particularly useful in crypto and validation scenarios--cases where implicit or return modes are dangerous.
@joshtriplett

I'm not sure where the names "mental model position" and "control flow position" come from, here.

I'm not sure about "mental model position", but I've been calling the "result is just a value" position the "control flow position". My reasoning is that if result is just a value, then the most salient feature of the try block is what code it executes.
I admit I find "mental model position" to be a bit odd, since they're both mental models. IMO, "error propagation position" is more descriptive. My reasoning is that the block propagates errors so the programmer can concentrate on the happy path.

@Centril thanks for the in-depth response!
One thing that's worth pointing out: we can reserve some keywords now, and still introduce #[keywords(...)] later on if we find we need different ones. So if there's an emerging consensus on a set of keywords that are reasonable to reserve now, I'm all for it! I just want to avoid sinking too much more time into this, and especially avoid further needlessly-heated discussions.

@aturon

I just want to avoid sinking too much more time into this, and especially avoid further needlessly-heated discussions.

Going full RFC on pass will continue the needlessly-heated discussions. I'd prefer a solution that avoids it, whether that be extending this RFC to cover pass and/or succeed or keyword gates.
I believe, however, that the approach shouldn't be split. If throw and fail are reserved by RFC, then pass (and/or success) should also be reserved. If you (the lang team) want to use keyword gates, then this RFC should be rejected in favor of the gated solution. My argument for this approach is the same as for pass: the try feature set should be approached holistically.

Is it that bad if we don’t have those try … catch block for three years?

We can turn it like: Is it good to have it? :p

@aturon

One thing that's worth pointing out: we can reserve some keywords now, and still introduce #[keywords(...)] later on if we find we need different ones.

Exactly; let's do that :)

Is it that bad if we don’t have those try … catch block for three years?

try has already gone through the RFC process and will be reserved. See #2388.

No no I meant: is that bad if the feature doesn’t land until up to three years, knowing that the RFC has been already been merged?

With one day left in the FCP, I assume it won't be postponed on #[keywords(...)]. The last guidance came from @scottmcm, who stated a 2nd RFC should be filed for pass.
Before I go about opening that can of worms, could someone confirm my assumption?

So far this RFC has had no positive response. It seems like it's being merged just to make the point that negative reactions don't count. I wish people would instead try to understand why people are negative towards this RFC. The only motivation for this RFC seems to be that because the feature may not be implemented, it's okay to reserve the keyword for it. We could as well reserve the eval keyword for the reason that an eval feature may not be implemented.
Personally I initially just reacted with :-1: without posting a comment, because I thought this is just some newcomer who has learnt Java at university who noticed that Rust is a younger language than Java and made a well-intended but ill-informed attempt to help Rust “catch up” with Java. Now I found out it isn't. It looks more like a politician who makes a plan to construct a road through a national park, and after massive public protests the plan is shut down, and then the politician instead makes another plan to reserve funds to construct a road through a national park. Those who downvoted this RFC are probably the same people as already commented on the previous RFC and successfully shut it down, and they shouldn't have to repeat their position in comments to this RFC, or hear that their reaction doesn't count because they haven't repeated themselves.
Enough about the process. Here's my position…
throw – Originally it was called “raise an exception”, just like you can “raise an objection”. In some language however, the keyword raise was already taken, so another keyword had to be chosen. Someone though let's go with throw, because it sounds better than foobar, and then it caught on because people copy things without the history behind them.
fail – This is intended to sound less like Java, but only superficially changes the wording, while still being all about thinking in Java. Java comes with the idea that a function call can only have one ordinary outcome, and all other outcomes are exceptional. Exceptional enough to mysteriously justify handling them with different language constructs than the ordinary outcome. Rust rejects this idea and instead has enum values that can express different outcomes, all of them handled in the same way. These outcomes are given no special treatment by the language. The outcomes Err and Ok from the standard library work the same way as variants I declare myself. fail gives the Err variant special treatment, making it impossible to raise other variants. Introducing pass would give the Ok variant special treatment as well, making it more symmetric, but still making it impossible to raise values of other types than Result, and it would be mad to have to do match x { Err(x) => fail x, Ok(x) => pass x } when we could simply have raise x.
The correct approach would of course be not to have a keyword that wraps the value in a variant. This would look like raise Err(x) and raise Ok(x), but it also allows raise x, where the variant of x has been determined elsewhere, or x is not a Result at all, just like break and return that allow raising any type, not just a Result. Macros err! and ok! can be provided for convenience, wrapping ok!($x) as raise Ok($x.into()). These macros would also not require the language to give any variant special treatment, and anyone can declare their own macros to do the same thing with other types.
Let's also get rid of the Java keyword try and use the already reserved keyword do. let x = do { raise 5; }; would be the same as let x = loop { break 5; };. The motivation of having two different keywords break and raise is the same as the motivation to have break and throw.
My recommendation is not to reserve any keyword at this time.

Rust rejects this idea and instead has enum values that can express different outcomes, all of them handled in the same way. These outcomes are given no special treatment by the language.

This is already not true-- we have the ? operator which explicitly propagates the error case of a Result or other Try value. fail and throw are designed to make it easier to construct and return these error values.

So far this RFC has had no positive response.

This statement is factually untrue. Denying the existence of opposing viewpoints increases the emotional tension in the conversation & makes it easier for people who are inclined to disagree with you to dismiss your comment outright instead of engaging with it seriously.
Anyway, the RFC hasn't been merged despite FCP ending because we talked about it in the lang team meeting last week and didn't have a consensus to merge it based on what has come out in the final comment period. Someone is supposed to leave a summary comment but I'm not sure who (and I don't remember the exact conclusion we reached).

Someone is supposed to leave a summary comment but I'm not sure who

That would be me, and apologies for not getting to it sooner!
The overwhelming sentiment during the meeting was that we are all tired of having heated arguments about keywords for not-yet-existent features, and are eager to put this issue to bed. That said, feelings about how to do that varied...

Drop all reservations except for accepted features (so: try, async, await)
Reserve liberally (so: merge this RFC, the delegate RFC, possibly toss in a few more)
Various options in between

A key point is how confident we feel that we can add some reasonable mechanism for within-edition reservations (like I proposed earlier). I'm not aware of strong opposition to an idea along these lines, but as always it's hard to predict how things will play out.
@nikomatsakis and I felt particularly strongly that up-front reservations are wrong and a mistake in the initial Edition proposal, basically for the reasons I've already outlined in the thread: they force up-front decisions about surface issues of features that are not yet fully proposed, let alone accepted or implemented. That just seems totally backwards and is going to keep leading to unworkable discussions. We both feel that the role of Editions here is that they can absorb any keyword-flags that have accumulated in the meantime.
In all, there is certainly no consensus to merge this RFC as-is, and I think there are no objections to instead closing it, under the assumption that we'll add a keyword-flag mechanism (or something like it) as needed later.
Given all that:
@rfcbot fcp cancel

@rfcbot fcp close

I'm not aware of strong opposition to an idea along these lines,

I feel that up-front keyword reservations are the correct call, but I can appreciate that I may be in the minority here. I'd much prefer a liberal reservation of keywords.
We'll see how it goes :)

I don't feel strongly enough to block, but

I'd like to see a concrete new plan, not just "not this one".
Does this imply we should also immediately un-reserve existing keywords for unapproved features?
I rather like Steve's suggestion to just reserve a whole bunch of common keywords

@rfcbot reviewed

I'd like to see a concrete new plan, not just "not this one".

That's likely to occur after the edition. And it'll likely be "plans", plural, since there's a great deal of discussion still to be had before we get anywhere close to a consensus.

And it'll likely be "plans", plural, since there's a great deal of discussion still to be had before we get anywhere close to a consensus.

I meant a plan for an alternative to keyword reservations, not about any particular feature.  Is there some lexical space we have available to use until a new edition shows up?  Or maybe a plan to schedule regular editions, to help get some of the "it's ok, I'll just catch the next train" we have for normal stable?

@scottmcm:

I meant a plan for an alternative to keyword reservations, not about any particular feature.

A good place to start may be "Idea"/"Pre-Pre-RRC" discussions for @aturon's keyword flags on internals. I question whether it will distract too much from 2018, though. Closing this RFC isn't beneficial if it would merely move the conflict around.


atlasmap-maven-plugin: URLClassLoader is only used for loading root class

Not yet sure how this is working within syndesis-build-helper-maven-plugin today from ClassLoader perspective. It seems like the URLClassLoader created here should be set as a TCCL before invoking class inspection. Otherwise it fails if method signature contains unknown class from current TCCL.
https://github.com/atlasmap/atlasmap/blob/47ddb07e1b3541f5aea5c4007ff93368151f40bf/runtime/atlasmap-maven-plugin/src/main/java/io/atlasmap/maven/GenerateInspectionsMojo.java#L177-L187

@lburgazzoli - FYI

Setting a compound class loader (maven original TCCL + this URLClassLoader) as a TCCL while invoking class inspection should be safe anyway. Let me try that.

Succeeded to invoke atlasmap-maven-plugin with the compound URL ClassLoader. This allows me to reporoduce #176


⚠ Bofrost.at has degraded performance

In a4e9878, Bofrost.at (https://www.bofrost.at) experienced degraded performance:

HTTP code: 200
Response time: 1273 ms

Resolved: Bofrost.at performance has improved in d5eaafd.


Remove nested runner payloads from linux

This adjusts linux to follow the same model we use for windows with a discrete archive (zip/tgz) to cary the primary executable, subprocess runners, and dependent libraries.
Darwin retain the payload model where the go binary is fully self contained.
Marking draft as it still needs some more testing and CI will need adjusting, but initial happy path looks good.
For comparison, the current (v0.2.1) artifacts are:

ollama-linux-amd64 - 467 MB
ollama-linux-amd64-rocm.tgz - 1.14 GB

With this PR:
% ls -lh ./dist/ollama-linux-amd64.tgz
-rw-r--r--  1 daniel  staff   1.1G Jul  9 13:19 ./dist/ollama-linux-amd64.tgz

After extracting on a system:
% ls -F
cuda/  ollama*  ollama_runners/  rocm/
% du -sh .
4.6G	.

Note: I opted to include rocm into the single artifact, since we do the same on Windows, and that simplifies the overall logic.  That said, it's the brunt of the extracted size so this may be an area worth optimizing.  One option might be to simply exclude the rocm directory during the extract in the install script if no AMD GPUs are detected.
% du -sh rocm
3.6G	rocm

Correction to the comment above - I accidentally omitted the rocblas tensile library.  The PR isn't updated, but with that fixed, the sizes are now:
% ls -lh ./dist/ollama-linux-amd64.tgz
-rw-r--r--  1 daniel  staff   1.6G Jul  9 17:49 ./dist/ollama-linux-amd64.tgz

% ls -F
cuda/  ollama*  ollama-linux-amd64.tgz  rocm/
% du -sh .
9.4G	.
% du -sh *
369M	cuda
229M	ollama
1.6G	ollama-linux-amd64.tgz
7.2G	rocm

Closing in favor of #5631


Update to keycloak 12.0.4

Thanks.
I'll merge this, as this is not a game changer.
But WDYT about keeping align with all the patch versions?
I don't think we need a new testcontainers-keycloak version with every new KC version. Major versions yes, minor possibly also (although there wasn't a minor version in the past since changing the versioning schema beginning with v5), but not necessarily patch version, until they will fix a certain issue.

Thanks for the quick response :)
I'd opt to maintain a version compatibility table in the readme.me and keep the library versioning independent of the supported Keycloak version to keep the versioning scheme straight forward.
As you suggest, I'd do a major version bump of the library whenever the underlying Keycloak version does a major version bump. The rest can be handled with minor or patch version bumps of the library.

This table already exists: https://github.com/dasniko/testcontainers-keycloak#testcontainers--keycloak-version-compatiblity

I know, that's why I edited the table in this PR :) just wanted to point out that I think this is the way to go.

I didn't mean to change the major version of this library when the major version of KC changes. I want to avoid this. A major version change of KC should only result in a minor version change of tc-kc.
What I wanted to discuss is, if we really need a new version of the lib on every KC patch version. IMHO this is only needed if the patch really fixes an issue which will make the library fail. But most of the patch versions of KC didn't solve anything we need in a testcontainer.

Oh, apparently I miss-understood this part: Major versions yes, minor possibly also, but not necessarily patch version, until they will fix a certain issue.
Your suggestion makes sense to me.


Better configuration option

Having to create and edit a TS file feels kinda weird, even if you have a little experience with TS itself.
Instead of having such a file should the config options be defined in a different format, like JSON or YAML, to be a bit more userfriendly.
Additionally should it be configurable, where the file is located (if that isn't a thing already), to allow maintainers the freedom of organizing their repository the way they like to have (i.e. by putting the config in the .github folder).

Honestly json or typescript is pretty similar 🤔 As you can not write hooks easily in json / yaml those aren't really an option TBF:
https://github.com/woodpecker-ci/plugin-ready-release-go/blob/111667f97fce6942fbf1c6a671ee5f723cf198d3/src/utils/types.ts#L42?
Quite a few options can be set using env variables / plugin settings: https://github.com/woodpecker-ci/plugin-ready-release-go/blob/main/docs.md#settings

I personally dislike that the docs.md isn't explaining all the settings. Only a few (in regards to the config ts file) and then expects the user to know how to read the TS file and how it should be formatted...
Granted, one can assume that someone using Woodpecker may be familiar with such stuff, but it's also not a guarantee either.
What I want to say is, that a bit more verbose explanation would be of great use for the more average user. Maybe a sort of cookbook page could be useful here, listing some examples?

Also, at the very least should it be made possible to allow setting your own location for the config file, no?
Or alternatively have some options be added to the plugin settings, like the commentOnReleasedPullRequests option (Maybe as a PLUGIN_COMMENT_ON_RELEASE_PRS env variable?).


Make a state management switcher element for power devs / demos

It would be great to have like a 'console' mode you can pop open the hood on and run a single command to mess with state values. Bad for a real site, but great for demos and teaching purposes. The first of which is easy is site theme
Related, it would be good to have a "developer mode" for the site settings much like site outline has.

#317 should be a feature of this as well

demo now exposes state object through window.HAXCmsStore


When using "models" feature only, bytes dependency not included

The encoding related code in models module should be behind the encode feature flag.

Resovled in https://github.com/bgpkit/bgpkit-parser/commit/ce66eaba607679341201b4cf93b8a917748ad24a


dialogflow webhook integrated with hangouts chat is not working properly

I have connected dialogflow with the hangouts chat. By enabling the webhook in dialogflow for a intent, from firebase i am getting the response as per that intent in dialogflow test app,but that response is not showing in hangouts chat.Is there any specific format for sending response to hangouts chat from dialogflow?
This is the code i have tried:
const functions = require('firebase-functions');
const app = dialogflow({debug: true});
const {dialogflow, BasicCard, Permission, Suggestions,}
=require('actions-on-google');
app.intent('id', (conv, {name}) =>
{
conv.close(People here are always available.So,you can call ${name} anytime)
});

The Actions on Google is not expected to work with Hangouts Chat. They're different platforms. In this case, you'd want to go to the more generic Dialogflow fulfillment library.

Please reopen this issue if you have new information to add!


Google feedback on TS 4.2-beta

This GitHub issue contains feedback on the TS 4.2-beta release from the team
that is responsible for keeping Google's internal software working with the
latest version of TypeScript.
Executive summary

We do not expect to have significant difficulty in upgrading Google to TS
4.2.
We found one change to the emitted JS that broke our tsickle and Clutz
tool's output in some cases. We will fix the tools to match the new
behavior.
Some changes to our TypeScript code are required to make it compile with TS
4.2.

About a third of the new errors reported by TS 4.1-beta are clearly
related to announced changes.
The other 60% of new TS error messages to report legitimate source code
errors that were previously missed by TS 4.1.
Detail sections below explain the changes to our code we expect to make
to unblock the upgrade.

Impact summary

Change description
Announced
Libraries affected

.d.ts Extension Breaks Module Resolution
no
N/A

Changes to lib.d.ts Definitions
no
0.06%

Template Literal Types
yes
0.05%

Function not Called in Condition
no
0.02%

Misc Other Changes
no
0.01%

noImplicitAny in yield
yes
~0

Type Arguments in JavaScript
yes
~0

Primitives as in RHS
yes
~0

abstract Construct Signatures
yes
~0

Typechecking Call Stack Depth Increased
no
~0

The Announced column indicates whether we were able to connect the observed
change with a section in the
TS4.2-beta announcement.
The following sections give more detailed explanations of the changes listed
above.
Template Literal Types
This change was announced.
We find the typing of template literals questionable, since it leads to
unexpected inference and spammy error messages. It's also unclear what the
application of these types is.
Example:
TS2322: Type '`${string}_null.csv` | `${string}_${string}.csv`' is not assignable to type '`${string}_null` | `${string}_${string}`'.
  Type '`${string}_null.csv`' is not assignable to type '`${string}_null` | `${string}_${string}`'.
    Type 'string' is not assignable to type '`${string}_null` | `${string}_${string}`'.
      Type '`${string}_null.csv`' is not assignable to type '`${string}_${string}`'.

458     filename = `${filename}.csv`;

In this case, a template literal type was inferred for a local variable. The
diagnostic is emitted at a reassignment to that variable. The user clearly
intended type string. Several more verbose examples were found.
Our fix for the new type errors will likely be casting to string.
.d.ts Extension Breaks Module Resolution
This change was not announced.
Starting with TS 4.2 the filename extension must not be included in the import
statement. The module resolution algorithm expects to add '.d.ts' itself.
import {Foo} from './foo.d.ts'; // must be changed to './foo'

The issue on our side was that other tools in our toolchain (tsickle and Clutz)
were generating import statements that included .d.ts extensions. These imports
began failing across our codebase such that many types were unavailable and
those libraries had type errors. There was no obvious connection of module
resolution issues.
We have since updated our tools to omit file extensions. These imports also work
against 4.1, so we don't anticipate further issues, regardless of whether this
makes it into 4.2.
Changes to lib.d.ts Definitions
This change was not announced but also expected.
We support the typing improvements. Generally it's clear what's changing.
Our fix will likely be casting away the errors in existing code.
We observed the following breakdown within this category:

Intl related: 50%
ResizeObserver: 33%
Other: 17%

Typechecking Stack Depth Increased
This change was not announced but isn't an API change.
Our fix will likely be to replace some complex types with simpler ones and
accept some losses in type accuracy.
A handful of libraries in our codebase use types that are arguably too complex.
The power of the TS typesystem allows this, but can lead to runaway typing.
A sample stack trace is below:
RangeError: Maximum call stack size exceeded
at createInferenceContext (.../typescript.js:62045:40)
at instantiateSignatureInContextOf (.../typescript.js:68496:27)
at compareSignaturesRelated (.../typescript.js:58654:26)
at signatureRelatedTo (.../typescript.js:60861:24)
at signaturesRelatedTo (.../typescript.js:60811:30)
at structuredTypeRelatedToWorker (.../typescript.js:60214:39)
at structuredTypeRelatedTo (.../typescript.js:59829:30)
at recursiveTypeRelatedTo (.../typescript.js:59801:64)
at isRelatedTo (.../typescript.js:59341:34)
at isPropertySymbolTypeRelated (.../typescript.js:60485:28)

I have not read this in full, but thank you all tremendously for the summary on 4.2 which we find invaluable.
We have second guessed the template literal inference changes in 4.2 quite a bit for the last few weeks, and we have a revert out for review here: https://github.com/microsoft/TypeScript/pull/42588

Just a small side-note: Your seemingly arbitrary use of linebreaks in the middle of sentences makes reading this issue very difficult.

Your seemingly arbitrary use of linebreaks

I think this is an unfortunate part of GitHub's commenting system, which uses a different markdown parsing strategy from its doc system. When writing markdown, I use one line per sentence. In the write-up @nreid260 had, there seems to be an auto-wrapping strategy. So where most markdown document parsers interpret these as part of the same paragraph, GitHub's comment parser kicks separate lines onto...separate lines, and makes our text look sub-optimal.

RE: linebreaks, this summary was written first as an internal PR and so got formatted using our Markdown formatter

For what it's worth, I also really enjoy these because it shows me holes in the breaking change section of our release notes. For example, I will be adding in the .d.ts resolution break in the blog post. Thank you for this again!

For 4.2-rc we observed the following:

Change description
Announced
Libraries affected

Changes to lib.d.ts Definitions
no
0.06%

Template Literal Types
yes
~0

Function not Called in Condition
no
0.03%

Misc Other Changes
no
0.02%

noImplicitAny in yield
yes
~0

Type Arguments in JavaScript
yes
~0

Primitives as in RHS
yes
~0

abstract Construct Signatures
yes
~0

Typechecking Call Stack Depth Increased
no
~0

Since you'd mentioned 50% of breaks being related to Intl - I should mention some of those have been reverted as well. You may need to deal with the removal of certain type aliases that'd been introduced for 4.2, but backed out post-RC.

Thanks for the warning.  I think we won't adapt our code to the TS releases until they are final (and maybe sometimes even after a few point releases in some cases), in part because it takes us a while to catch up, but also so we can avoid some of the churn that inevitably happens.

Are you saying that this time it was so bad that you are stopping, or that you only determined the root cause of the breaks for Beta and RC and didn't try fixing them until stable? We really appreciate you all trying these early!

The latter!  It takes us a while to adopt a version due to the work involved, so we are still slow.  For example, we just rolled out 4.1 recently.
In other words, we are trying to provide feedback on the betas so the feedback comes in early enough to be able to fix any big problems before they're released, but in terms of actually deploying those eventual releases we are likely ~months behind.


"Using template engines": Remove outdated info and broken links

Closes #1290
Currently, this is en-only, but at some point the same changes should be done in other langs.

I have an off-topic question, why isn't Developing template engines for Express in the advanced topics menu?

LGTM

Just wondering if we should list which templates are currently supported by express? I guess we'd need a core person to let us know that.
When I read "but it also supports...among others" I was like, which others.
I found this old link https://www.expressjs.com.cn/resources/template-engines.html, but not sure if all of these are still valid. Also, I think this page should be removed (I'll make an issue for it).
I'm being nit picky here, so this is obviously not urgent :)

@chrisdel101 Maybe you want to put it in an issue, your comment could get lost over time, and I think this could be a good idea.

That link above must be some site clone, so the link is not valid. But this issue persists. Thanks for heads up.


Everywhere: Implement from block expressions

This implements var from { ... } expressions that allow blocks to to be used as expressions. Where the expression evaluates to the variable var from the following block.
This maps directly on the the GCC block expression extension ({ ...; var; }). This can be useful for match cases and for initialising stuff that you may want to bail out from.
This was one of the syntaxes mentioned yesterday in the #jakt channel on Discord, that I was rather fond of, so I wanted to try implementing a little proof of concept. I'm not sure this will survive the court of public option though :sweat_smile:

An alternate syntax for this could also be { ... } as var (though I think the from may be more explicit)

We were chatting about this on discord the other day as another approach:
{
   out 3 + 4
}

so the out tells us what value to treat the block as. We could restrict it to the last line of the block.


Fix live queries

I added multilog/test/multilog_live.go and it showed some problems in both the badger and roaring bitmap multilog implementations.
This PR

[x] fixes values returned by livequeries
[x] correctly waits for values to be added
[x] adds a simplified sequence observable that is easier to use then luigis abstract one

Already merged into v0.1.2


https://stylesniffer.cookiecode.dev doc search is not working

Algolia is not yet properly setup, need to provide a key

For open sources projects, there is an easier way to get the doc indexed, by joining the docsearch contributors program https://docsearch.algolia.com/apply/

Waiting for the email containing all the interesting data