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

#[deriving(PartialEq, Eq, Show, Clone, Hash, PartialOrd, Ord, Default, Encodable, Decodable)] is too verbose #441

Open
comex opened this issue Nov 5, 2014 · 9 comments
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.

Comments

@comex
Copy link

comex commented Nov 5, 2014

If I have a small struct wrapping some basic types, or a basic enum, it's quite likely that the entire list of traits above is appropriate to derive (with the possible exception of Default). However, this is so noisy that, in practice, nobody seems to do so, including in the main Rust repository: for example, grep libsyntax for pub enum and look at how many of them cannot be used as keys in maps or even Shown. Instead, some random subset of traits is derived depending on what people actually need to do with the struct. But this is annoying:

  • If I need to add a new trait, it's usually a completely meaningless busywork change.
  • If the type is a public item from someone else's library, then I can't add a deriving, but would have to make a copy of the type and manually convert values back and forth in order to do whatever the trait is for. I haven't actually encountered this yet, but then again I haven't written that much code..

The most obvious solution would be a shortcut to derive as many traits as possible, though I'm not sure how that would interact with new derivable traits potentially being added in the future.

@canndrew
Copy link
Contributor

canndrew commented Nov 5, 2014

It would be nice if it were possible to have traits which are opt-out instead of opt-in. So, for example, if I explicitly wanted to forbid Showing a particular type (for whatever reason) I could write:

#[noderive(Show)]
pub enum MyEnum {
    ...
}

You could also allow users to define their own traits like this by providing default implementations of all methods and marking the trait with an #[implicit] attribute.

@glaebhoerl
Copy link
Contributor

Imagine how much code you would have to write in C++!

More constructively, one small but potentially significant improvement would be to automatically derive supertraits; so that e.g. #[deriving(Ord)] would automatically imply #[deriving(PartialEq,Eq,PartialOrd)] as well.

@mdinger
Copy link
Contributor

mdinger commented Feb 15, 2015

A less comprehensive change would be to add minor globbing:

// These two are equivalent because `*Eq` includes `PartialEq` and `Eq`.
// Same for `*Ord`
#[deriving(*Eq, *Ord)]`
#[deriving(PartialEq, Eq, PartialOrd, Ord)]

Deriving supertraits is probably a better idea though.

@mdinger
Copy link
Contributor

mdinger commented Apr 14, 2015

#1028 was proposing something similar to this. One or both of them were postponed and thus should be labeled as postponed.

@barosl
Copy link
Contributor

barosl commented Aug 19, 2015

@mdinger

#[deriving(*Eq, *Ord)]`

If that is made possible, could we also do #[derive(*)]? That sounds... crazy! But I like it!

Additionally, I guess this kind of feature also requires #1210 (specialization), because auto-derived code might interfere with user implementation without that.

@mdinger
Copy link
Contributor

mdinger commented Aug 19, 2015

@barosl That is definitely amusing and I would not be opposed. Kinda magical.

@ticki
Copy link
Contributor

ticki commented Sep 5, 2015

More constructively, one small but potentially significant improvement would be to automatically derive supertraits; so that e.g. #[deriving(Ord)] would automatically imply #[deriving(PartialEq,Eq,PartialOrd)] as well.

👍

It would be nice if there was a way to distinguish between traits and supertraits (such as a some sign or a naming convention)

@lambda-fairy
Copy link
Contributor

This seems like another use case for macros-in-attributes:

macro_rules! ord_traits {
    () => (PartialEq, Eq, PartialOrd, Ord)
}

#[deriving(ord_traits!())]
pub enum MyEnum { ... }

@louy2
Copy link

louy2 commented Apr 24, 2017

Unsurprisingly Haskell people is also exploring options regarding this. If curious one can check out their points on it: https://ghc.haskell.org/trac/ghc/wiki/IntrinsicSuperclasses

@Centril Centril added the T-lang Relevant to the language team, which will review and decide on the RFC. label Feb 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests

9 participants