Skip to content
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

Add fallible closure to idioms #250

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- [Privacy For Extensibility](./idioms/priv-extend.md)
- [Easy doc initialization](./idioms/rustdoc-init.md)
- [Temporary mutability](./idioms/temporary-mutability.md)
- [Fallible closure](./idioms/fallible-closure.md)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might find a better headline for the summary to let this idiom be found more easily.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, this often comes up when people want to avoid "arrow code" with let guards or "match hell", maybe something around that ?


- [Design Patterns](./patterns/index.md)
- [Behavioural](./patterns/behavioural/intro.md)
Expand Down
35 changes: 35 additions & 0 deletions idioms/fallible-closure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Fallible closure inside infallible function

## Description

Build a fallible closure inside of an apparently infallible function.

## Example

```rust
use std::path::Path;

// this function hides its failure states
fn file_stem(path: &Path) -> &str {
// this closure is fallible, so it can make use of `?`
// fn() -> Option<&str>
let inner = || Some(path.file_stem()?.to_str()?);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this example is not making full use of ?, it could even have TryInto IIRC.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be written :

let inner =  || path.file_stem()?.to_str();

but that wouldn't show much

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think that is better. I don't know why we need to have another layer for that.

inner().unwrap_or("untitled")
}
```

## Motivation

You may sometimes want to use the [`?`] operator inside an infallible function,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sometimes, here it would be good to give examples when that might be the case and when you would find this idiom in the wild.

in those cases a closure inside your function could be the simple solution.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this a good and simple solution in these cases, an explanation for it would be good

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this even an idiom? I thought it is just a syntax?


## Advantages

This allows using the terser syntax permitted by the [`?`] operator inside an
infallible context.
Comment on lines +28 to +29
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bit repetitive, it's good for this, because it's good like. maybe a bit more elaboration. maybe the text from my last comments would fit better in here then


## Disadvantages

This is hiding failure states from the consumer of the API.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is that bad and when do you really want to avoid it? mentioning some cases would be good and probably also state, that if this is overused it could be considered an anti-pattern


[`?`]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator