-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Use different keywords for declaring tagged unions and C-style enums. #27
Conversation
For example: ~~~rust enum AB { A = 1, B } enum CD { C, D(int) } ~~~ would become: ~~~rust enum AB { A = 1, B } union CD { C, D(int) } ~~~
I am in favor. |
Thanks @SimonSapin :)
I am opposed, but I won't fight if a tide forms. |
Should C-Style enums be |
I feel very bad for bringing up this bikeshed, but it's been irritating me for a while now. I have tried my best to be as comprehensive as possible in order to encourage a focused debate. Let me know if I have missed anything, or whether you have any there are any gaps in the |
FWIW, I’m in favor of moving away from the name "enum" for things that are not what everyone else calls "enum" (sums of unit types.) I’m less convinced about the separation. |
@esummers If you have a more comprehensive explanation, I can add it to the
Were you arguing to change that? |
@bjz Not necessarily in favor of changing, I just think that interoperability with other languages should not be part of the core language syntax. It was my impression that assigning values to the tags was not recommended for pure rust code. Maybe I am off. I suppose assigning tags may be useful for persistent storage of serialized data. Another thing: Splitting these may help with unifying with structs. For instance, I think it would be nice to nest a union inside a struct without having to declare separately. C-style enums muddles that possibility. I often want some shared fields mixed with the varients. |
I'm in favor of the separation, and like the current names ( |
@esummers I agree with the sentiment that it is slightly unsavory that we are beholden to C in providing this functionality in the core language. A macro could very well be the solution, with the loss of being able to statically check that all cases are covered. |
@esummers it's useful for FFI. On Tue, Apr 1, 2014 at 11:09 AM, Brendan Zabarauskas <
|
I had another idea. Maybe assigning integer tags to variants should be an attribute since it is mainly for C interoperability.
EDIT: @bjz Good point about |
But then you can't cast using |
I could be in favor of this. I myself have experience with introducing C++ friends to Rust, and mild grievance with using the word I'm not entirely sold on the In ancient Rust, the |
Following up on my last comment, here's the original mailing list thread where http://article.gmane.org/gmane.comp.lang.rust.devel/823/match=renaming+tag |
I haven't thought this through, but is there any reason we couldn't just use a variation of structs for enums/unions? Just specify variant constructors instead of fields when that is what you want.
EDIT: @bjz Clarified. I guess like #24 except not necessarily tied to virtual inheritance. |
@esummers Why did you leave off the type identifier in that example? Your comment about there being 'no constructor' makes no sense either - |
@bjz thanks for the careful explanation. I am trending negative on this proposal, let me explain why:
As to the special treatment of C-like enums, I don't see it as anything special. Different types are good for different things. Just like not all enums can implement
The main objections were always (1) people like custom discriminants and (2) using a trait with deriving interferes with the ability to cast variants in constant expressions. Oh, P.S. For historical note, enums were once defined with the keyword |
Being mindful of where we sit in the canon of programming languages, and trying not to muddy terminology too much is very important. If we hope that Rust makes as big of an impact as we want, then we don't want to be cursed for years to come for confusing terminology. Also being accessible to systems programmers, who find the use of
That workflow would not change. I didn't want to muddy the RFC with a further potential change, but I could see enum People: (&static str, &static str) {
Ann = ("Ann", "Bennett"),
Robert = ("Robert", "Brown"),
} Apologies for the pretty horrible example. I have seen it used in the D community quite often, but I don't have any examples on hand. If enums were generalised in that way then I would be more comfortable with them being a language construct. That would also allow you to use type aliases for your reprs (something that is annoyingly not possible today). |
Also, in regards to C folks being confused by |
That's not the impression that I get from this proposal. If you leave Thinking about it as well, it feels really gross that both these would be possible: enum Foo {
Bar = 1,
Qux = 2,
}
union Foo {
Bar,
Qux
} I can already imagine the endless questions of when to use one or the other. The My anecdotal evidence that my friends don't like the |
For posterity, Graydon's original rationale for
(Note that newtype enums were dropped aeons ago in favor of newtype structs.) |
That is a concern. Thanks for putting it that way.
Hmm yeah, it does. :(
You have a far better gauge on how Rust is perceived in the outside of the core community, so I would trust your judgement far more than my own. Perhaps I'm making much ado about nothing. |
Using a macro/syntax extension like |
Other considerations aside, I don't think it would be a bad thing exactly to rename union Foo {
Bar = 1,
Baz = 2
} Maybe it could look less weird with a different syntax: union Foo {
Bar(1),
Qux(2)
} ...although I have no idea if this would cause problems if we later extended the type system to include numerics. |
I've used c/c++ since about 1994 and it took me about 20 seconds to get used to the use of the name; "enum variants" are still values, just with more internal structure (ok, so the tag is seperate). There are things that take time to get used to , thats' no where near one of them. I think the current naming is fine, because it emphasises that it is NOT a C union - which has the ability to unsafely acess the wrong data; and you could keep union available if you decided you wanted to embed more direct overlap with C/C++*.. like C/C++ unions available in unsafe code, for library data.. Still, it wouldn't be a disaster if it was changed. |
-1 from me. Union seems like a bad choice since it also has an existing meaning that is different from the Rust use. Importantly, I don't think we should add more (or split existing) data structures in Rust - it already has a lot. As a matter of opinion I didn't find the use of |
(Like LLVM’s intermediate representation (IR)? clang and rustc are front ends for it.) |
I mean middle - a single AST that is a superset of what rust and C++ can represent.. add borrow check warnings to your C++ compiler.. emit bindings between rust&c++ libraries translating everything .. unify concepts/traits where possible. I'm not volunteering to write this though :) |
Just a thought: It makes sense to iterate over the variants of a c-style "enum", but it doesn't necessarily make sense to iterate over the variants of a "union". (Inspired by rust-lang/rust#5417 ) enum Directons {North, East, South, West};
for dir in Directions::iter() { ... do stuff ....} |
The equivalent to Rust enums in popular languages are class hierarchies, not C unions. The problem is however that the syntax to define class hierarchy is repetitive, since each variant needs to specify its superclass, so we can't just adopt it as our only syntax for enums. So, I think there is really no perfect solution to this problem. On the other hand, mathematically, the obvious name is "disjoint union", while in computer science, it's either called a tagged/discriminated union or sum type Maybe we could invent a keyword related to either class hierarchies ("hier"?), disjoint unions ("disj"?) or some of the terms used in CS ("tag", "tagged", "disc", "sum", ...), but not sure if that's better. Also, if we make enum variants first class like #11 and #24 propose, even enums of singletons are not really like C enums, so we may want to use a single keyword different than "enum" for all cases. |
who is the target audience, if its about clarity ? i gather scala has 'case class', or perhaps you could clarify with "enum union {..}" - but it would be a shame to lose the 'one keyword introduces a definiton' property that rust currently has .. so easy to grep all the definitions out of a file & so on. is there any way to poll this scientifically? |
In all honesty, my personal scientific poll was going to be "go ask dobkeratops, he knows a thing about C++". But then you somehow found your way here on your own. :P |
@bill-myers Re. #24, if that was the case I would reiterate what I said before: it seems like it would unify ADTs into one construct, so maybe Anyway, I think there have been lots of good arguments in favor of the status quo. I am pretty much convinced that it is probably not worth the change. At least we now have a good, documented discussion on the matter that we can point folks to in the future. Let me know if you would like me to close this. |
I don't think there's any reason to leave this open for now, we're pretty much just bikeshedding now. You're right in that it's good to have this discussion documented to avert future bikesheds. |
I don't really like either It's a tagged |
It appears as though most people are not in favor of this change. I too am not in favor of this change (I think @bstrie described very well the reasons why). But on the off chance that the tide turns again, renaming |
I suppose one argument for changing it is for (the more stubborn half of)* C++ people who might just assume, at a glance, its nothing special. "match is just switch++" (no it isn't,its key to how the langauge avoids nullpointers). psychological/political effect. (* i, personally, am 100% happy with enum) |
@dobkeratops If C++ folks are ok saying "match is just switch", then they'd probably be ok saying "data is just enum" as well. I think the more important thing to do is just to change the tutorial/reference to de-emphasize C-like enums and emphasize non-C-like enums instead. And don't even talk about explicit discriminants or casting to |
I'm a nobody that just happened on this discussion. For what its worth I agree 100% with kballard. This seems like an education issue. In the tutorial, don't teach enum like it is a C/C++ enum. Slap them in the face with the difference. |
@xgalaxy indeed. I think the tutorial makes a mistake in introducing discriminated enums first. They should be pushed further down, perhaps even out into the FFI tutorial. |
Perhaps we are wrong even in using |
Another post on /r/rust: Enum type confusion [Beginner] |
Why should |
struct Foo { x: T } Is almost the same as: enum Bar {
Bar { x: T }
} The differences being that
It would be nice to have a unified |
I wonder if we could think of: struct Foo { x: T } As something like: #[deriving(Deref, DerefMut)]
data Foo({ x: T }) :/ |
I'm not a contributor or anything, but as a C/C++ developer, I'm very surprised at the general support towards keeping I find the concern about the difference between tagged/untagged especially confusing given that the majority of union use I see are sum types. The remainder are generally type conversions to avoid issues with strict aliasing; irrelevant to Rust. It follows that Rust being a safe language would have a safe In contrast, enums are generally used as associated sets of constant integers, quite often not default ordered, either as flags or as specified by an external protocol, and occasionally containing duplicate values. Given that Rust's tagged unions only satisfy a subset of those cases, |
Me too.
Yeah, I think @nikomatsakis is talking about removing c-style Ultimately, I am one voice amongst many. And I am growing a little tired of the fight. However this RFC has shown up on the weekly meeting agenda a few times (I think from @alexcrichton?), so it seems that there is interest in discussing it further. |
We discussed this at a meeting today, and we're going to close this for now. We may be able to revisit this in the near future if the need becomes pressing again, but at this time we think that closing is the best way to go. |
Cool, thanks for the info Alex! |
Fix period in the middle of a sentence in TUTORIAL.md
For example:
would become: