rust-unofficial / patterns

A catalogue of Rust design patterns, anti-patterns and idioms
https://rust-unofficial.github.io/patterns/
Mozilla Public License 2.0
7.95k stars 362 forks source link

Should #[non_exhaustive] be advised over private members for extensibility? #132

Closed haibane-tenshi closed 2 years ago

haibane-tenshi commented 3 years ago

#[non_exhaustive] attribute on Rust reference.

I believe #[non_exhaustive] emerged as a better solution to the same problem and private members are an artifact from the rime before it. Still it seems there are a few differences.

From what I can understand, the attribute has three primary differences compared to private members:

Overall I consider the new approach as much superior (less boilerplate, better consistency), the old one should be deprecated and used only when very specific semantics is required (e. g. module-level non-exhaustiveness vs crate-level).

AnthonyYoManz commented 3 years ago

#[non_exhaustive] was made with the very purpose of replacing the old-school, unintuitive private member pattern so I think it makes sense to update our advice.

simonsan commented 3 years ago

the old one should be deprecated and used only when very specific semantics is required (e. g. module-level non-exhaustiveness vs crate-level)

That said, how do you imagine it. Do you want to keep both variants in the repo and state their use cases explicitly (link between them, improve doc to state both)? #135 replaces it now, which I'm not sure of if there is still at least one scenario where it will be used?

MarcoIeni commented 3 years ago

An obvious scenario where it will be used is for compatibility with MSRV (Minimum supported Rust version).

Do you want to keep both variants in the repo and state their use cases explicitly (link between them, improve doc to state both)?

I would keep both variants in the same file, if it is necessary to keep the old approach.

Maybe the file could be called "Fields extensibility" and then we discuss both the approaches, first the new one and then we also write the old one (again, if we decide it is necessary), by explicitly saying it is less idiomatic than using non_exhaustive.

haibane-tenshi commented 3 years ago

I'm a third person here, but I would probably create a "Legacy" category with patterns which are outdated/replaced with better alternatives, and then create cross-links on both approaches (maybe with MSRV mentioned etc.)

MarcoIeni commented 3 years ago

Mmm..I don't dislike the idea of a "legacy" category :)

simonsan commented 3 years ago

I think something like:

Introduction
Contributing
Idioms
Patterns
Anti-patterns
Functional Programming
Refactoring
Legacy
|--- Idioms
|--- Patterns
|--- Anti-Patterns
Additional Resources

Could be then a nice build up rather than mentioning legacy in each category.

MarcoIeni commented 3 years ago

I agree! Of course for now there will be only the idioms directory there because this will be the only entry. So in #135 we could move the old file in legacy/idioms/ and idioms/priv-extend.md will be updated with the new approach. If you agree with this plan we could remove the needed-discussion label.

simonsan commented 2 years ago

A different approach is required to achieve similar effect without the attribute - a variant with never type (empty enum or !). It is not mentioned in the book.

This would be the question if it's worth to mention then and should be added.

For now I think the legacy category didn't make sense. Also it's the question if we would need such a category overall and won't only keep the preferable approach and maybe an alternative inside the same file to have a discussion about both.