-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extended Try RFC #211
Closed
Closed
Extended Try RFC #211
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
- Start Date: 2014-06-25 | ||
- RFC PR: | ||
- Rust Issue: | ||
|
||
# Summary | ||
|
||
Extend the `try!` macro to include an optional second parameter that is a constructor to wrap | ||
around the original error in case of failure. | ||
|
||
# Motivation | ||
|
||
`try!` is a useful macro when dealing with many functions that return `Result`s, but they become | ||
useless when the `Result` type that the programmer wants to return has a different failure type. | ||
For example, in a function that uses Io and Regex, two different error types could be generated | ||
(IoError, and Regex::Error). The author could not choose either of these errors to return because | ||
neither is extendable with the other. Instead it is common for library and application authors | ||
to create their own error types that wrap the errors that could possibly be produced. Unfortunately, | ||
this means that the `try!` macro is no longer useful. | ||
|
||
# Detailed design | ||
|
||
This RFC proposes adding another argument to the `try!` macro that would be used as a constructor | ||
to wrap around existing error types. For example: | ||
|
||
```rust | ||
enum MyError { | ||
IoFailed(IoError), | ||
RegexFailed(regex::Error) | ||
} | ||
|
||
fn read_then_regex(filename: &str, regex: &str) -> MyError { | ||
let file = try!(File::open(filename), IoFailed); | ||
let regex = try!(Regex::new(regex), RegexFailed); | ||
// do things | ||
} | ||
|
||
``` | ||
|
||
The desugared version of this example (which is required to implement this pattern today) | ||
would look like: | ||
|
||
```rust | ||
fn read_then_regex(filename: &str, regex: &str) -> MyError { | ||
let file = match File::open(filename) { | ||
Ok(a) => a, | ||
Err(x) => IoFailed(x) | ||
}; | ||
let regex = match Regex::new(regex) { | ||
Ok(a) => a, | ||
Err(x) => RegexFailed(x) | ||
}; | ||
// do things | ||
} | ||
``` | ||
|
||
The motivation for this improvement is the exact same as the motivation for the original `try!` | ||
macro. | ||
|
||
The original form of the `try!` macro would still be valid and would continue to work without | ||
any changes. | ||
|
||
# Drawbacks | ||
|
||
Adds confusion. It is not immediately obvious as to what the 2nd argument is for if | ||
the reader is not already familiar with it. | ||
|
||
# Alternatives | ||
|
||
* Create another macro that is very similar | ||
* (named `try_or!` ?). | ||
* Create another macro that is very similar and place it in an external library |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that the
try!
macros is widely used and mostly liked, creating a new macro seems like it would be a much better idea. In that case, I would recommend implementing it as an external library and getting some use and experience, then submitting a PR to add it to std (I don't think that would require an RFC), and perhaps finally an RFC to add it to the prelude if it is very popular.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nick29581 The existing
try!()
can easily be extended to take two arguments without breaking any backwards compatibility. The suggestion for a new macro is only as a potential readability aid. Personally, I think using a new macro is unnecessary, providing a second arg totry!()
should be visible enough.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its also a good way to get some experience using this without affecting a really crucial macro. I mean that if we added this, decided it was a mistake, then took it out again, it could be painful. So there is a high bar for acceptance. If we had some use of this beforehand to convince us it was a good idea, then it would be easier to accept.
So, change the last sentence in my previous comment to "submit an RFC to merge the new macro in with Try!"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted this macro bad enough that I made my own cargo project that implements this RFC.
https://github.com/TyOverby/try_or
I'm pretty bad at writing macros, so I wouldn't suggest that this be made the official implementation, but I've found that it is incredibly handy.