-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Introduce var
/let
-else
-statement
#1871
Conversation
@josh11b - this needs the labels |
Looking at the files changed, looks like this is still a work in progress, so I've made it a draft proposal. |
Yep. Still putting some thought into this right now. Especially, into @geoffromer's comment "whether we should have this feature at all. There may be other combinations of pattern matching/error handling features which would make this one superfluous". |
OK, so far so good. I added another suggestion for this pattern: let (x: i32, true) = F(1) else {
// Can't use `x` here.
return false;
} => let (x: i32, true) = F(1) ?: { return false; } A "compressed" ternary operator omitting the happy path. It'll be very familiar to all curly-brace language programmers, I think. |
Considering @geoffromer comment, I think, it can be, that depending upon how var/let (x: i32, true) = F(1) or { return; }; |
If the label recommendation of Edit: Here it is: #1874 |
More food for thought: https://www.hillelwayne.com/post/python-abc/ - HN view on this: https://news.ycombinator.com/item?id=32314368 |
This PR is marked "ready for review", but it's still in the "Draft" column of the "Proposals" project (see "Projects" on the right side of the GitHub window). If you intend this to be ready for review, I think it needs to be moved to the "RFC" column. Otherwise, the PR should be marked as a draft (use the "convert to draft" link in the "Reviewers" section). It's unfortunate that we track this information in two places, but I'm not sure if there's a better option :-( |
I'm assuming that this is intended to be in rfc given the "ready for review", and marking it such. See #1898 for some context. |
This statement is syntactic sugar for a set of other patterns, specifically it | ||
guards a code block if a requirement of this code block is violated. That is, | ||
there is actually no problem. |
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.
There is a problem, otherwise we should not pursue this proposal. I believe var
/let
-else
solves a real problem, and it is important that this proposal articulate what that problem is. The problem has to do with making common programming tasks both readable and writable. The specific benefit of var
/let
-else
is when the task has two cases:
- One case which can be identified using a pattern, and the main body of the function following will be handling.
- All other cases can be handled uniformly and briefly.
If code follows that pattern, then this construct has two advantages: it is concise and not going to introduce as much indenting as other constructs. Both of these help readability and writability. Consider:
match (my_container.LookUp(...)) {
case .None => { return NotFound; }
case .Some(result: String) => {
very;
long;
block;
of;
code;
return Found(processed_result);
}
}
compared to:
let .Some(result: String) = my_container.LookUp(...)
else { return NotFound; }
very;
long;
block;
of;
code;
return Found(processed_result);
The big question is whether this use case is important / common. And I think that comes down to looking at examples when you would use this construct. I think the "function returns an optional" situation is one common example where this comes up. Another example is when calling a function that returns an error that this function wants to transform into a different error. Other examples would be valuable to identify.
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.
You might want to search around for the "return early pattern" to find examples where this would be useful.
This pattern is said to improve the readability of code, compared to an | ||
equivalent `match` or `if` statement. It allows to keep code which handles | ||
violated requirements next to the requirements. |
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.
Rationales in Carbon are to be written in terms of Carbon's stated goals and principles. The proposal template has some links, the one that I think is relevant to this proposal is: [Code that is easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write)
- `var`/`let` ... `or {...}` | ||
- `var`/`let` ... `?: {...}` a short-circuited ternary operator | ||
- `var`/`let` ... `otherwise {...}` | ||
- introducer syntax: `guard var`/`let` ... `else {...}` |
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.
These alternatives should include the advantages and disadvantages of these options and a rationale for why we chose the proposal over the alternative. If you don't know, that is a good time to reach out to the community.
This proposal adds this pattern as it seems to be rather popular and simplifies | ||
common error-handling patterns. |
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.
It would be great to go deeper into this here.
Marking this as draft again. Thanks @josh11b for the thorough review. |
From #2165 |
@PramodhTVK - feel free to continue on this one. I am redirecting my energy to other FLOSS work. Edit: Waiting 1mo until deleting https://github.com/rscircus/carbon-lang containing the branch from this PR. |
What is missing??? This is the best request for carbon error handling that I see. Very similar to v lang. |
|
transfer statement as `break`, `continue`, `return`, or a function that does not | ||
return. | ||
|
||
[Rust](https://github.com/rust-lang/rfcs/blob/master/text/3137-let-else.md) |
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.
Can you instead add the actual pull so that our reviewers can feel the impression at that time?
|
||
## Details | ||
|
||
TBD after enough C in this RFC. |
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.
?
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.
RFC - Request For Comment
Hence C is Comment(s). Like yours. ;)
Should this still be a draft? |
FYI, Rust has recently stabilized |
Hey @josh11b - thanks for having a look. I pulled out of working here and encouraged @PramodhTVK to continue after that time-consuming Discord mess and refocused, as it took too much time and I didn't receive any help from whatever side I tried. However, @zygoloid helped meanwhile, as far as I see. Thank you. Then, you can find the summary of my last thoughts on this here. I'll be having a look at Rust. Thanks again. |
Read the HN thread right now. To my eye the reaction is rather mixed. As
@josh11b pointed out the fans, I'll focus a bit on the critics:
Many disadvantages are pointed out. Like `match` binding the error, while
it's dropped in `let-else`, many alternative solutions with similar amount
of code/'reviewability', pointing out the already existing solution/match
for the unhappy path using `if`, not being handy for Result types and
mostly for Option types only, and the biggest point being this comment by
pavon:
```
Yeah, I feel like the vast majority of the time this would be better
handled by splitting out that block into a function. There are situations
where there the number of parameters needed to pass in would get unwieldy,
but that is where I start thinking about if all that loose state is
intrinsic to the problem, or a sign that I need to refactor my
datastructures.
```
…On Thu, Nov 3, 2022, 20:15 josh11b ***@***.***> wrote:
FYI, Rust has recently stabilized let...else, see Announcing Rust 1.65.0
<https://blog.rust-lang.org/2022/11/03/Rust-1.65.0.html#let-else-statements>.
On Hacker News <https://news.ycombinator.com/item?id=33451359>, there are
some comments saying why they are excited by this features 1
<https://news.ycombinator.com/item?id=33452517>, 2
<https://news.ycombinator.com/item?id=33452556>,
—
Reply to this email directly, view it on GitHub
<#1871 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAI46CVQXMDC2YY2DZX2ZGDWGQFLNANCNFSM55I47I3Q>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
We triage inactive PRs and issues in order to make it easier to find active work. If this PR should remain active, please comment or remove the |
We triage inactive PRs and issues in order to make it easier to find active work. If this PR should remain active or becomes active again, please reopen it. \n\n\n This PR was closed and archived because there has been no new activity in the 14 days since the |
As implied in PR #1388 and requested in #1758 this proposal introduces the rationale behind the simplification of a common error-handling pattern, informally known as let-else statement (or var-else statement). It can be interpreted as syntactic sugar for a
match
-statement where the non-matched case diverges. Hence, the usage as error-handling pattern.