Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upRFC: `throw` expressions #2426
Conversation
Centril
added some commits
Apr 30, 2018
Centril
added
the
T-lang
label
Apr 30, 2018
scottmcm
reviewed
Apr 30, 2018
| [indeed suggests]: https://github.com/rust-lang/rfcs/blob/master/text/0243-trait-based-exception-handling.md#throw-and-throws | ||
|
|
||
| the unhappy path is not particularly differentiated from the happy path in | ||
| terms of syntax. By introducing `throw`, as RFC 2343 [indeed suggests], |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
I guess I'll be the one to make the highly subjective but critical point against this, since I think we need to start gathering opinions on it ASAP if it's going to get addressed properly: I'm still not convinced that In fact, the motivation section for this RFC made me more skeptical that I know Also, the prior art section feels highly misleading, since this feature has nothing to do with implicitly-propagated exceptions, and many of the languages listed are using |
nikomatsakis
approved these changes
May 1, 2018
This comment has been minimized.
This comment has been minimized.
|
I approve. In response to @Ixrec's concern:
I would say two things: First, I don't consider this feature to only make sense if we have Second, even if we are not sure we want something, if we think that there is a "pretty good chance" that we do, then it is worth reserving the keyword. In this case, I think the answer is definitely yes: both because there is prior art in favor and because there are a lot of folks who have spoken up in favor of |
This comment has been minimized.
This comment has been minimized.
While a bonus of
Just to clarify, this is the semantics of
As @nikomatsakis puts it, I would also say that the
Neither does
Many, but not all. Haskell and Idris use
I disagree with the notion that On the choice of keyword, I think we should pick something that is consistent with |
This comment has been minimized.
This comment has been minimized.
This is my strongest feeling in this area. Some sort of |
This comment has been minimized.
This comment has been minimized.
repax
commented
May 1, 2018
•
|
Thanks, @Centril for this fine RFC!
Here's my comment: I think we should find a better keyword than I'd like to stress this point. Our experimental We need a keyword that clearly expresses the occurrence of a failure, and is consistent with a failed attempt, a failed try. |
This comment has been minimized.
This comment has been minimized.
I do love the appreciation!
Ideas? Here are some synonyms of
How so? I understand that you might say: - "I threw the ball and my dog caught it", but the meaning of
I'm wary of making such predictions either way since it is difficult; We can give technical and non-technical arguments for why
This way of framing it seems to suggest
All in all, I think @nikomatsakis put it well on #2388:
This suggests to me that |
This comment has been minimized.
This comment has been minimized.
burdges
commented
May 1, 2018
|
We do need to tell people "Rust does not have exceptions", so using |
This comment has been minimized.
This comment has been minimized.
rpjohnst
commented
May 1, 2018
•
|
Back before 1.0, In this case, I don't think that confusion will come up. While there are still several ways to fail, they all tend to do the same thing as I'm not really opposed to I also have a general sense of uneasiness about introducing too many But at the same time I do think |
This comment has been minimized.
This comment has been minimized.
Surely no more so than than
Here's a fairly accurate check I think: https://sourcegraph.com/search?q=repogroup:crates+case:yes++\b((let|const|type|)\s%2Bfail\s%2B%3D|(fn|impl|mod|struct|enum|union|trait)\s%2Bfail)\b+max:400 The breakage doesn't seem too extensive. @rpjohnst I agree with your reasoning on
This one seems unlikely? I think at least any confusion here is quickly fixable in Rust's learning material.
True; I agree this is a problem, but let's not let the perfect be the enemy of the good? |
This comment has been minimized.
This comment has been minimized.
repax
commented
May 1, 2018
•
Why not Why not I'd prefer |
This comment has been minimized.
This comment has been minimized.
Sure; but
You don't need to reserve Regarding "what you may throw, you may catch", while I think that makes sense in English, would
This seems true to me, I can't argue with it. :) |
kennytm
reviewed
May 1, 2018
| is deemed quite low. | ||
| Searching for `raise` with sourcegraph indicates a very | ||
| small number of uses as an identifier, but searching for `throw` gives a timeout | ||
| indicating that there are no uses. |
This comment has been minimized.
This comment has been minimized.
kennytm
May 1, 2018
Member
I've got at least 4 results from https://sourcegraph.com/search?q=repogroup:crates+%5Cbfn%5Cs%2Bthrow%5Cb.
All of them are JS bindings (e.g. servo/servo and neon-bindings/neon), but I guess it is because of sourcegraph's selection of repositories.
This comment has been minimized.
This comment has been minimized.
Centril
May 1, 2018
Author
Contributor
Strange. I tried the following query before: https://sourcegraph.com/search?q=repogroup:crates+case:yes++\b((let|const|type|)\s%2Bthrow\s%2B%3D|(fn|impl|mod|struct|enum|union|trait)\s%2Bthrow)\b+max:400 and it timed out, but now it shows the results you reference.
Anyways, the breakage slightly is less extensive than for raise and fail; but all keywords in this space break minimally.
I'll update the RFC with this new info :)
Centril
added some commits
May 1, 2018
This comment has been minimized.
This comment has been minimized.
|
I've now added some of the recent discussion to the RFC's text. |
rpjohnst
reviewed
May 2, 2018
| the perfect be the enemy of the good. | ||
|
|
||
| A strategy for introducing early-return on success with Ok-wrapping **could** | ||
| be to introduce `try fn` and / or to let `return` perform an early return |
This comment has been minimized.
This comment has been minimized.
rpjohnst
May 2, 2018
Or, go the other way around- let people break out of try blocks. On its own, this is probably a bad idea, as try blocks are not loops, but it's possible 'label: try { .. break 'label value; .. } would be sufficient. For that matter, maybe any return or break that leaves the try block should be Ok-wrapped? For example:
fn f() -> Result<T, U> {
try {
let t: T = get_a_t()?;
return t;
}
}Maybe that's even worse.
This comment has been minimized.
This comment has been minimized.
Centril
May 2, 2018
Author
Contributor
My main concern wrt. re-purposing break is this:
try {
// ..
loop {
// Are we breaking the loop or the try?
// Perhaps it is obvious to say "the loop", but is it really?
break 3;
}
// ..
}Maybe that's even worse.
Probably, yeah.
This comment has been minimized.
This comment has been minimized.
Centril
May 2, 2018
Author
Contributor
Regarding break with label:
'label: try {
..
break 'label value;
..
}That seems workable, but it is not particularly ergonomic.
This comment has been minimized.
This comment has been minimized.
scottmcm
May 2, 2018
Member
While I'm a fan of having label-break-value, I see it mostly as a way for macros to provide customized flow control constructs. I'd rather it typically be internal to libraries more than something that shows up in syntax that would be used broadly.
This comment has been minimized.
This comment has been minimized.
Centril
May 2, 2018
Author
Contributor
Another, possibly bad, idea to facilitate for macros could be to introduce the special label 'try which always refers to the closest try { .. } block.
That way, you could just write:
try {
ok!(value);
}where ok!(value) expands to break 'try Try::from_ok(value).
This comment has been minimized.
This comment has been minimized.
rpjohnst
May 5, 2018
@Centril I think my rigorous reason is I don't like introducing new names "out of thin air." Every other label has its name chosen by the source code- I would be much less bothered by some kind of 'my_label: fn f() { ... } or 'my_label: try { ... } than I am by introducing 'fn or 'try as "special" names.
A similar-but-different situation came up in #2115, where people felt wary about allowing the source code to introduce names without some primary declaration point. But in that case, the source code is still the thing determining the name- you write the same name in two places and they mean the same thing. Labels inherently have a "declaration" point, but the same reasoning applies- you write the name down in both places, as a label.
(@squishy-clouds 'static is not a label at all- it's a lifetime, and further kind of a "monoidal identity element" like 0 or 1 or [], so it gets a bit of a pass here.)
This comment has been minimized.
This comment has been minimized.
Centril
May 6, 2018
Author
Contributor
@rpjohnst I don't think they would be so "out of thin air";
If the system of having special labels is applied out consistently per control flow block-form you could have:
'fn'loop'while'for- maybe just merge these as one
loop?
'if'match'try'async'const(maybe not?)
The goal of these are not to be used directly in people's code, but rather hidden away in macros so that you can invent new and interesting DSLs. The problem with having to explicitly declare the labels is that you have to pass them into the macros.
This comment has been minimized.
This comment has been minimized.
Ixrec
May 6, 2018
Contributor
Do we have any actual use cases for a generalized "magic labels" feature like this, even in DSLs? I've never heard anyone suggest any of these except as an implementation detail of a throw/fail macro.
This comment has been minimized.
This comment has been minimized.
phaylon
May 6, 2018
One use-case might be that if we had a 'try built-in label that can be targeted by ?, I think all of the other exception like syntax can be implemented by the eco-system (or even std if deemed worthy) as macros. That would allow for:
- People to use break-with-value and
?with these blocks without auto-wrapping or any other additional functionality, basically keeping it as close to current control flow as possible. - Experimentation with more exception like syntax on crates.io. Before things would settle that would also provide an explicit opt-in to specific semantics. Once things have settled, the functionality can simply be added to
std. Since they would still be macros, there's still an opt-in to additional semantics like auto-converting a final result. Adjusting pieces ofstdalso seems easier and more future proof than changing the language itself.
I'm wondering if it would make sense to put together a proposal for this path for the new exception like syntax extensions.
This comment has been minimized.
This comment has been minimized.
Centril
May 6, 2018
Author
Contributor
Do we have any actual use cases for a generalized "magic labels" feature like this, even in DSLs?
Not very concretely at least; Just hypothesizing ;)
This comment has been minimized.
This comment has been minimized.
|
Stemming from #2426 (review)... Would this be (eventually) allowed? let result = 'a: try {
try {
throw 'a e;
}
}; |
This comment has been minimized.
This comment has been minimized.
I suppose it could. It is consistent with
Another possibility is discussed here: https://github.com/Centril/rfcs/blob/rfc/throw-expr/text/0000-throw-expr.md#paper-exceptional-syntax |
This comment has been minimized.
This comment has been minimized.
|
I'm not objecting to the idea of having an expression that serves this function (though personally I think |
This comment has been minimized.
This comment has been minimized.
|
@joshtriplett How come? And are you saying that we should choose I do think that RFC #243 using exceptional terminology should be seen as precedent and therefore the case against exceptional terminology is less convincing. However; my view is that either @petrochenkov, @wesleywiser, @Flaise, @kjeremy, @gilescope @phaylon @alexander-irbis @0x7CFE: |
This comment has been minimized.
This comment has been minimized.
phaylon
commented
May 2, 2018
|
I agree with the concerns already stated, and my concerns from the I'd summarize it as: I'm generally against using exception syntax in a non-exception language, because, mainly:
These are largely philosophical/foundational, so I'm not sure there is much to address. I believe I will remain firmly in the -1 group. |
This comment has been minimized.
This comment has been minimized.
|
@phaylon Would you be more comfortable with
It is not included in the current proposal (and doesn't have to be).
Writing |
This comment has been minimized.
This comment has been minimized.
ibkevg
commented
May 8, 2018
•
|
@ssokolow Thanks for giving me the benefit of the doubt, but it was a typo. I need to issue an RFWIMNWIS, Request for What I Meant, Not What I Said! :D |
This comment has been minimized.
This comment has been minimized.
mikeyhew
commented
May 12, 2018
|
This is a very well-writren and thoroughly researched RFC. @Centril I like how neutral you remain when discussing the options, and although you argue for Just wanted to add a couple thoughts:
|
Centril
referenced this pull request
May 14, 2018
Closed
RFC: Reserve `throw` and `fail` as keywords in edition 2018 #2441
This comment has been minimized.
This comment has been minimized.
|
Since the only urgent question of this RFC is the keyword reservation of |
This comment has been minimized.
This comment has been minimized.
|
@rfcbot fcp postpone "The Rust team is laser focused on the 2018 Edition right now", so with #2441 covering the urgent-for-the-edition part, I propose we set aside any further discussion until after the current roadmap. |
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
May 20, 2018
•
|
Team member @scottmcm has proposed to postpone this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
May 23, 2018
|
|
rfcbot
added
final-comment-period
and removed
proposed-final-comment-period
labels
May 23, 2018
rust-lang
deleted a comment from
m-cat
May 23, 2018
rust-lang
deleted a comment from
mark-i-m
May 23, 2018
This comment has been minimized.
This comment has been minimized.
|
Moderation note: @m-cat such comments are very clearly against our code of conduct. Further such behavior will result in a ban from the project. Feel free to contact us at rust-mods@rust-lang.org if you have questions. |
This comment was marked as off-topic.
This comment was marked as off-topic.
ghost
commented
May 23, 2018
•
|
@Manishearth Why are you deleting people's comments? e: Btw, say hello to /r/programmingcirclejerk: |
This comment has been minimized.
This comment has been minimized.
|
[Comments/questions about moderation should go to the moderation team, please.] |
This comment was marked as off-topic.
This comment was marked as off-topic.
m-cat
commented
May 23, 2018
|
@Manishearth Can you tell me exactly how I violated the code of conduct? |
This comment has been minimized.
This comment has been minimized.
This is not the place to discuss this. |
rust-lang
deleted a comment
May 23, 2018
This comment was marked as off-topic.
This comment was marked as off-topic.
Pzixel
commented
May 23, 2018
|
Well, let's draw a line. I do believe that everybody agrees on that this issue produces a lot of arguing. However, I think that problem is much deeper than just this issue, it's about the whole desicion process. So, we can tilt at windmills and discuss implications instead of problem source, OR we can do the later. The main idea that some RFCs get accepted when they actually are not welcomed by the majority. It seems that the whole process is broken as we can't give a feedback if something goes wrong. E.g. I read this RFC. I disagree with it. How can I make it not happen? I should get 100+ upvotes on some very critical comment? I should write my own RFC "please, don't do RFC#42"? I should apply some Mozilla job and get into the core team? Or I can do just nothing and it will be accepted whenever I like it or not? (when I say "like" I mean something bigger than just my emotional state, but rather the overall feeling based on my professional experience). If you can answer this question then we can have some valuable talk. It's completely ok if you say that my opinion doesn't matter until I'm in core team, because there are ten persons who decide what's going to be included in the language, but please, be honest with me. @Centril says that it's a huge disappointment then you spend a lot of time, writing an RFC or a comment like this, when it was useless. Just say "we don't need your opinion" and we will save literally thousands of manyears that could have a better application as well as a better atmosphere in comments. |
This comment has been minimized.
This comment has been minimized.
|
Moderation note: There are multiple discussions happening in the forum about the RFC process. Please keep process discussion in the forums and out of individual RFC PRs. |
This comment has been minimized.
This comment has been minimized.
|
I'm going to go ahead and close out this RFC (which is in FCP for postponement), as I think it's quite clear we won't be pushing on this in the near future, and the thread is continuing to veer well off topic. |
Centril commentedApr 30, 2018
Introduce diverging
throw exprexpressions, typed at!, which eitherbreakto the closesttry { .. }if there is one, or if not,returnfrom thefnor closure. The expression formthrow expris supported on edition 2018 onwards. This also means thatthrowis reserved as a keyword.A minimal example:
if condition { throw Foo; }To @scottmcm for reviewing.