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

RFC: Enum trait #5417

Closed
ghost opened this issue Mar 17, 2013 · 9 comments
Closed

RFC: Enum trait #5417

ghost opened this issue Mar 17, 2013 · 9 comments
Labels
A-traits Area: Trait system

Comments

@ghost
Copy link

ghost commented Mar 17, 2013

Since I've been doing some work with the deriving code in libsyntax, I thought I'd solicit opinions on adding a new trait to libcore:

trait Enum {
    static fn enumerate(blk: &fn(Self) -> bool);
}

Obviously, this would be most useful for enums with only nullary variants, but other enumerable types could take advantage of it as well (bool::all_values currently serves the same purpose).

This would make it possible to write

// enum Dir { North, East, South, West }
for Enum::enumerate |dir: Dir| { ... }

instead of

for [North, East, South, West].each |dir| { ... }

A standard implementation for enums with only nullary variants would be made available through #[deriving(Enum)], and a default method (or utility trait/impl until those are working) would be provided for obtaining all the values in a vector. It might be beneficial to have a static fn cardinality() -> Option<uint> method on the trait as well.

If the trait name is too easily confused with the keyword, another option is Enumerable.

@ghost
Copy link
Author

ghost commented Mar 17, 2013

Maybe it makes more sense to have a method on the trait that returns an iterator instead, to better support lazy operations and the usual extended iterator methods.

@kud1ing
Copy link

kud1ing commented Mar 18, 2013

Haskell's Enum is similar but not quite: http://zvon.org/other/haskell/Outputprelude/Enum_c.html

@catamorphism
Copy link
Contributor

I would prefer something more like Haskell's Enum type class, with fromEnum and toEnum methods. That seems more general to me -- I think you could implement what you're proposing in terms of it.

@ghost
Copy link
Author

ghost commented Mar 19, 2013

I think converting between enums and integers is a separate issue. This is just for those scenarios in which you need to access every variant of a C-like enum (or some other completely enumerable series, be it bitstrings, Fibonacci numbers, or the legal values of bool).

I'm proposing (in the static- and pure-less future) something like:

trait Enumerable<I: BaseIter<Self>> {
    fn enumerator() -> I;
}

which would be implemented like

enum Dir { North, East, South, West }

/* everything below this would be generated by `#[deriving(Enumerable)]` on the enum */

impl Enumerable<DirEnumerator> for Dir {
    fn enumerator() -> DirEnumerator { DirEnumerator }
}

struct DirEnumerator;

impl BaseIter<Dir> for DirEnumerator {
    fn each(&self, blk: &fn(&Dir) -> bool) {
        [North, East, South, West].each(blk);
    }

    fn size_hint(&self) -> Option<uint> { Some(4) }
 }

Then you might have some theoretical trait for C-like enums like

trait Enum<I: BaseIter<Self>> : Eq + Ord + TotalOrd
                              + Enumerable<I>
                              + FromInt + ToInt
                              + FromStr + ToStr { }

@z0w0
Copy link
Contributor

z0w0 commented Jun 6, 2013

@catamorphism thoughts on the clarification @apasel422 has provided? I certainly think what he has proposed would be incredibly useful (I've need that sort of thing before). Although, perhaps converting to/from integers could be provided on the same trait?

@catamorphism
Copy link
Contributor

@z0w0 I don't have a strong opinion. In any case, I don't think it should be on the backwards-compatible milestone. Nominating for feature-complete so we can discuss.

@emberian
Copy link
Member

@thestinger @huonw could this automatically be derived? I envision it just expanding to [A, B, C, D].iter() or somesuch..

@graydon
Copy link
Contributor

graydon commented Jul 31, 2013

I think this is just a deriving mode that produces an iterator, yeah. Not bad, but it should just be a feature (and I'm not even sure it's one that ought to block feature-complete). It's neat but I could live without it.

@graydon
Copy link
Contributor

graydon commented Aug 8, 2013

just a bug, removing milestone/nomination.

@huonw
Copy link
Member

huonw commented Jan 26, 2014

triage: no change. I think calling it Enum would be confusing.

@rust-highfive
Copy link
Collaborator

This issue has been moved to the RFCs repo: rust-lang/rfcs#284

oli-obk pushed a commit to oli-obk/rust that referenced this issue May 2, 2020
Update doc links and mentioned names in docs

changelog: none
oli-obk pushed a commit to oli-obk/rust that referenced this issue May 2, 2020
Rollup of 11 pull requests

Successful merges:

 - rust-lang#5406 (Fix update_lints)
 - rust-lang#5409 (Downgrade let_unit_value to pedantic)
 - rust-lang#5410 (Downgrade trivially_copy_pass_by_ref to pedantic)
 - rust-lang#5412 (Downgrade inefficient_to_string to pedantic)
 - rust-lang#5415 (Add new lint for `Result<T, E>.map_or(None, Some(T))`)
 - rust-lang#5417 (Update doc links and mentioned names in docs)
 - rust-lang#5419 (Downgrade unreadable_literal to pedantic)
 - rust-lang#5420 (Downgrade new_ret_no_self to pedantic)
 - rust-lang#5422 (CONTRIBUTING.md: fix broken triage link)
 - rust-lang#5424 (Incorrect suspicious_op_assign_impl)
 - rust-lang#5425 (Ehance opt_as_ref_deref lint.)

Failed merges:

 - rust-lang#5345 (Add lint for float in array comparison)
 - rust-lang#5411 (Downgrade implicit_hasher to pedantic)
 - rust-lang#5428 (Move cognitive_complexity to nursery)

r? @ghost

changelog: rollup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-traits Area: Trait system
Projects
None yet
Development

No branches or pull requests

7 participants