#Enum of custom type

1 messages · Page 1 of 1 (latest)

granite wharf
#

Enums are a tool to express a limited amout of option for a value. Right now the baking type is not important, however there is an interesting exception to define a integer and assign manually a value.

I propose to extend this concept to generic types like this:

const MyVals = enum(f64) {
    small = 0.01,
    med = 11,
    high = 1e32
};

This behaviour can be replicated currenty with a get function, however I find it error prone.

const MyVals = enum {
    small,
    med,
    high,
    
    fn get(self: @This()) f64 {
        return switch(self) {
            .small => 0.01,
            .med => 11,
            .high => 1e32,
        };
    }
};

Also It could be useful to allow assignement:

const x: MyVals = .small;
var y:f64 = x;
 

I tried to search for previous issues, but I couldn't find a similar proposal.
Is this something that could be added to the language?

marble vale
#

chances of a proposal like this being accepted are few to none. Enums are integers, through and through

#

I would argue the example you've given isn't actually that error prone - I'd say it's a fairly clear API

#

also, even in the hypothetical world where this was accepted, your use case wouldn't be as you've demonstrated, it would probably look more like

const x: MyVals = .small;
var y: f64 = @enumToInt(f64, x);

because enums don't coerce to their backing integer in the first place.

If it's any consolation, you could consider doing something like:

const MyVal = enum(u64) {
    small = @bitCast(u64, @as(f64, 0.01)),
    med = @bitCast(u64, @as(f64, 11)),
    high = @bitCast(u64, @as(f64, 1e32)),

    pub fn get(val: MyVal) f64 {
        return @bitCast(f64, @enumToInt(val));
    }
};
granite wharf
#

What are the properties that integers have to enable enums. It's simply an arbitrary choice or they enable more optimized code?

#

Also I think use case is over types: enum(type) {f1 = f16, f2 = f64} , and use this enum for constrain function definition to specific types

#

Allowing direct assignment makes sense, it would treat the enum like an type expression.

#

Without needing to check "manually" with an if / else case

marble vale
#

this just isn't the intended usage of enums, nor is it how zig has been designed

#

though to answer, yes, enums being integers does indeed enable optimised code generation

marble vale
#

given existing generics, you could even slim this down, in this specific example:

const Float = enum {
    f16 = 16,
    f64 = 64,

    fn Type(comptime ret: Float) type {
        return std.meta.Float(@enumToInt(ret));
    }
};
fn add(comptime rt: Float, a: anytype, b: anytype) rt.Type() {
    // ...
}
#

Whilst I admire and share your desire to improve the language, I'd advise that you take some time to try and understand the design decisions in Zig: simplicity is one of its greatest and most fiercely guarded qualities, so a new feature requires a great deal of rationale behind it before it would even be considered

#

and please, don't be discouraged.

#

it's a common sentiment that zig will never be the perfect language for anyone, specifically because it has rejected and will reject so many features; the intention is that there will be few enough features in zig that you can keep most of the language in your head without debugging your knowledge.

granite wharf
#

Thank you for the comprehensive answer and very kind words! I respect the zen of zig, that is what it got me into it.

#

However I really like this proposal, and I would like see it discussed. How would you go to make a stronger case for it? Taking part of std and implementing this feature? Comparing it to other languages ecc.?

marble vale
#

Well, the basis for adding features to zig comes down to use cases. You have to ask: "what does this solve?", and "does it solve it better than status quo?", as well as "do the benefits outweigh the added complexity?"

#

for my part, I don't really see any strong answers to those questions in favour of this feature

#

I agree it would be "nice to have", but it doesn't strike me as powerful as many other rejected features

#

In terms of complexity, it adds a lot, as it upends many assumptions about enums and enum coercion, and leaves many questions, such as "how does this interact with non-exhaustive enums?"

granite wharf
#

Thank you again. I can see how edge cases and implementation complexity would stop immediately this proposal.

#

I think I'm going to use the bitCast solution. Do you forsee any problematics, other than for compiletime types?

marble vale
#

Well, depends on what you mean by problematics. bitCast is a fine solution for sized types, but doesn't work for zero-sized types like type or comptime_int

#

If you encounter any specific issues, you are always free to look for a thread, or open one to get your question answered