RFC: turn `true` and `false` into enums #5266

bstrie opened this Issue Mar 7, 2013 · 13 comments

7 participants

< bstrie> pcwalton: you wouldn't need to count true and false if they were done
          as enums, is there a reason they aren't?
<@pcwalton> bstrie: because enums do not have a defined memory layout but
            booleans do
<@pcwalton> anyway, I would probably be in favor of getting rid of "true" and
            "false" and doing what Go does
<@pcwalton> since it's somewhat inconsistent that "bool" is not a keyword in
            Rust but "true" and "false" are
<@nmatsakis> ...regarding bool, remember we have check exhaustiveness.
<@nmatsakis> an enum would work better
<@pcwalton> nmatsakis: ah, yes. well, enums don't work because bools have size
            in rust and we don't specify enum layout
<@pcwalton> at least, I'm proposing that we don't
<@pcwalton> in order to leave room for data layout optimizations (e.g.
            Option<~T> becoming a nullable pointer, Result<(),~T> becoming a
            nullable pointer, etc)
<@nmatsakis> pcwalton: I think we should permit the layout of enums to be
             specified with annotations.
<@nmatsakis> so bool could be labeled.
<@nmatsakis> we're defining it, anyhow.
<@pcwalton> hmm
< strcat> pcwalton: bool could just rely on the implementation details, since
          it's part of the implementation
<@pcwalton> that might work yeah
< strcat> just make the discriminant only as big as needed and it'll be 1 byte
< strcat> pcwalton: or you could say the layout is implementation defined if it
          contains pointers/arrays/strings
<@pcwalton> hmm, yes, that's possible

I agree with the point that having true and false keywords while not having bool is odd. Would they remain uncapitalized? If so they would be a very big exception to our naming conventions.


uint, u8, etc. are already a big exception to the naming conventions (and I don't think that's a bad thing in those cases).


Those are different though because they aren't defined in the core library. They are just magic always-in-scope identifiers.


@brson: I think using Bool, True and False would be better. They won't be any different than other types/variants that are exported in prelude (Option, Result, etc.).


What would you really gain by removing it? It seems like boolean values are such a fundamental thing, conceptually part of if statements etc., that it IS in the language, even if not present by named tokens.

It makes sense to keep complex, optional things, like bitstrings in the core/standard libraries, but come on... when are you going to write a program that WON'T have boolean values/logic in it? And if you have that, where is the sense in moving one line of that to a separate file?

If the point is to simply have fewer keywords, I don't think these are the keywords to drop. bools are EVERYWHERE in programming. I was very glad to see them given their proper (standardised) place, as keywords, in C++, as opposed to the (sometimes conflicting) macros like TRUE and FALSE and True and so on in C.


@lee-b: two reasons that I can think of. First off, there shouldn't be any impact to the end user. We'll still have true and false, they'll just be an enum variant, not a first-level object in a compiler.

Second: this will simplify the compiler and should help us to avoid bugs. With booleans as a first class object, it's easy for us to fix a bug for booleans and not for other types, or vice versa.

For everyone else: There's one more case to consider, which is that of the serializers. I like the idea of keeping serialize_bool, because it allows us to serialize to formats that support native boolean types. It's also a nice pattern that could solve the hack we have in the JSON serializer, where emit_enum_variant checks for variants named Some and None to handle JSON null values. It would be much more elegant if we just added an emit_option to handle that specific case, and let serialize_enum_variant handle the generic case.


@thestinger: If we do that, then should we bite the bullet and capitalize all our built in types?


@erickt: Well, in my opinion that would be the best thing to do. Using a different naming convention for the built-in types just seems inconsistent. I don't know if it's really worth the work to switch it all though :).


@thestinger but turning uint to Uint also means that you need to change 1234u to 1234U, which is doubly hideous! :) I'm fine with capitalizing bools (as much as I hate it in Python), but I'd prefer to leave the uints and friends decapitalized.


If you're not going to change the rest of the types to upper-case, please don't change bool/true/false. The very thought is making me cringe.


@bstrie: I think it would be Int and UInt, and I don't think there's any need to change the literals.


I don't think the asymmetry between literals and type names is unusual. It's the same for integers, chars, etc. I'm not really into making any changes in this area. Primitive types have built in meaning at several layers.


discussed at weekly meeting, decided against (no strong advocate and I'm pretty opposed on grounds of symmetry with other primitive types)

@graydon graydon closed this Mar 12, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment