Jump to page: 1 2
Thread overview
Allow Conditional Compilation Inside Enum Declaration
Mar 30
IchorDev
Mar 30
monkyyy
Mar 31
IchorDev
Mar 31
monkyyy
Apr 02
Hipreme
Apr 02
Basile B.
Apr 02
Basile B.
Apr 04
Daniel N
Apr 08
IchorDev
Apr 03
Dukc
March 30

To declare an enum type that may or may not have one or more members depending on conditional compilation statements requires duplicating the entire enum:

static if(cond){
	enum A{
		x,y,z,w,
	}
}else{
	enum A{
		x,y,z,
	}
}

For an enum type with many members—or many conditionals—this quickly becomes an insane amount of repetition.

The logical solution is to just allow conditional compilation statements inside enums:

enum A{
	x,y,z,
    static if(cond){
		w,
	}
}
March 30

On Saturday, 30 March 2024 at 14:57:00 UTC, IchorDev wrote:

>

To declare an enum type that may or may not have one or more members depending on conditional compilation statements requires duplicating the entire enum:

static if(cond){
	enum A{
		x,y,z,w,
	}
}else{
	enum A{
		x,y,z,
	}
}

For an enum type with many members—or many conditionals—this quickly becomes an insane amount of repetition.

The logical solution is to just allow conditional compilation statements inside enums:

enum A{
	x,y,z,
    static if(cond){
		w,
	}
}

As a specif case or for all lists?

Could you do this for functions foo(static if(bar){1},2)?

is changing the meaning of {} nessery or should it be for single elements?
enum A{x,y,z, static if(cond) w}

March 31

On Saturday, 30 March 2024 at 22:34:46 UTC, monkyyy wrote:

>

As a [specific] case or for all lists?

Could you do this for functions foo(static if(bar){1},2)?

I’m not sure if that’s really in the scope of this idea. Maybe that could be another proposal?

>

is changing the meaning of {} nessery or should it be for single elements?
enum A{x,y,z, static if(cond) w}

I don’t see why that would be necessary? Ideally it should work just like any existing conditional compilation. (e.g. also allowing version(Something):, etc.)

March 31

On Sunday, 31 March 2024 at 02:36:40 UTC, IchorDev wrote:

>

On Saturday, 30 March 2024 at 22:34:46 UTC, monkyyy wrote:

>

As a [specific] case or for all lists?

Could you do this for functions foo(static if(bar){1},2)?

I’m not sure if that’s really in the scope of this idea. Maybe that could be another proposal?

>

is changing the meaning of {} nessery or should it be for single elements?
enum A{x,y,z, static if(cond) w}

I don’t see why that would be necessary? Ideally it should work just like any existing conditional compilation. (e.g. also allowing version(Something):, etc.)

While I can't mimik what the mathy compiler devs will say I'm pretty sure existing static if must be in a very different level of the compiler then enum parsing.

One of the bugs I reported was about meta programming enums using user types op overloads (where +1, would be treated as x2 for flags) I think x,y,z,w are fragile order of operation values and any attempt to meta program them would be "you have to go full string mixin and do everything all at once"

So in my head this compile time version of if as a code block and ternary if and a version of this feature with the logic "if static condation is met, parse this element to parent node, otherwise skip" that works like the auto flattening of sequences seems more likely

April 01

On Saturday, 30 March 2024 at 14:57:00 UTC, IchorDev wrote:

>

The logical solution is to just allow conditional compilation statements inside enums:

enum A{
	x,y,z,
    static if(cond){
		w,
	}
}

It's not very elegant, but you can do it with a string mixin:

enum string enumMembers = "x, y, z, " ~ (cond ? "w, " : "");

mixin("enum A { " ~ enumMembers ~ " }");
April 02

On Saturday, 30 March 2024 at 14:57:00 UTC, IchorDev wrote:

>

To declare an enum type that may or may not have one or more members depending on conditional compilation statements requires duplicating the entire enum:

static if(cond){
	enum A{
		x,y,z,w,
	}
}else{
	enum A{
		x,y,z,
	}
}

For an enum type with many members—or many conditionals—this quickly becomes an insane amount of repetition.

The logical solution is to just allow conditional compilation statements inside enums:

enum A{
	x,y,z,
    static if(cond){
		w,
	}
}

I agree and the idea is not novel, for example that, from memory it's been seen several times in the NG too. Risk for a DIP on this is that it could get rejected with a rationale such as "you can do that with metaprog, which is the D way". That is more or less what what Paul has replied, if you read under the lines.

April 02

On Sunday, 31 March 2024 at 02:36:40 UTC, IchorDev wrote:

>

On Saturday, 30 March 2024 at 22:34:46 UTC, monkyyy wrote:

>

As a [specific] case or for all lists?

Could you do this for functions foo(static if(bar){1},2)?

I’m not sure if that’s really in the scope of this idea. Maybe that could be another proposal?

>

is changing the meaning of {} nessery or should it be for single elements?
enum A{x,y,z, static if(cond) w}

I don’t see why that would be necessary? Ideally it should work just like any existing conditional compilation. (e.g. also allowing version(Something):, etc.)

My main take against that, is that it would be harder to make it compatible when using libraries. One value could change:

enum A
{
static if(cond) w,
x,
y,
z
}

And boom! Depending on how you're using, one may:

  1. Break
  2. Worse: create surprising behavior because, if you use X, it will become Y which is still valid.

Although the idea does make sense in some aspects, I fear for the worst

April 02

On Tuesday, 2 April 2024 at 17:10:07 UTC, Basile B. wrote:

>

On Saturday, 30 March 2024 at 14:57:00 UTC, IchorDev wrote:

>

To declare an enum type that may or may not have one or more members depending on conditional compilation statements requires duplicating the entire enum:

static if(cond){
	enum A{
		x,y,z,w,
	}
}else{
	enum A{
		x,y,z,
	}
}

For an enum type with many members—or many conditionals—this quickly becomes an insane amount of repetition.

The logical solution is to just allow conditional compilation statements inside enums:

enum A{
	x,y,z,
    static if(cond){
		w,
	}
}

I agree and the idea is not novel, for example that, from memory it's been seen several times in the NG too. Risk for a DIP on this is that it could get rejected with a rationale such as "you can do that with metaprog, which is the D way". That is more or less what what Paul has replied, if you read under the lines.

forgot to say you can use a struct filled with anonymous enum members too.

struct A
{
    enum T x = 0;
    enum T y = 1;
    enum T z = 2;
static if (cond)
    enum T w = 3;
}

However RN I cant confirm that the usage is 100% equivalent. Use of the members is likely but use of the container may not, e.g in std.traits (esp. the EnumMembers template ...).

April 02
On Tuesday, April 2, 2024 11:19:54 AM MDT Hipreme via dip.ideas wrote:
> On Sunday, 31 March 2024 at 02:36:40 UTC, IchorDev wrote:
> > On Saturday, 30 March 2024 at 22:34:46 UTC, monkyyy wrote:
> >> As a [specific] case or for all lists?
> >>
> >> Could you do this for functions `foo(static if(bar){1},2)`?
> >
> > I’m not sure if that’s really in the scope of this idea. Maybe that could be another proposal?
> >
> >> is changing the meaning of {} nessery or should it be for
> >> single elements?
> >> `enum A{x,y,z, static if(cond) w}`
> >
> > I don’t see why that would be necessary? Ideally it should work
> > just like any existing conditional compilation. (e.g. also
> > allowing `version(Something):`, etc.)
>
> My main take against that, is that it would be harder to make it compatible when using libraries. One value could change:
>
> ```d
> enum A
> {
> static if(cond) w,
> x,
> y,
> z
> }
> ```
>
> And boom! Depending on how you're using, one may:
>
> 1. Break
> 2. Worse: create surprising behavior because, if you use X, it
> will become Y which is still valid.
>
> Although the idea does make sense in some aspects, I fear for the worst

Well, you can already do that. It's just that you have to wrap the entire enum declaration to do it. Really, this is exactly the same as using static ifs to compile members into a struct or not, which we do all the time. So, there's nothing special here, and the fact that we can't do it with enums regularly causes issues any time that you're dealing with enum declarations that need to vary based on stuff like the OS (both for when the list of enum members needs to change and when the values of those members needs to change depending on the system). Fortunately, most enums aren't in that boat, but it surprises me every time that I run into it.

I suspect that enum declarations are the only place in the language where you can put ddoc comments on individual symbols, but you can't actually version those symbols with version statements or static ifs. And it definitely feels inconsistent that we're not allowed to use conditional compilation with their declarations.

And yes, it could be abused, but that's no different from any other place that conditional compilation is used to control whether symbols get compiled in or not.

- Jonathan M Davis




April 02
On Saturday, March 30, 2024 8:57:00 AM MDT IchorDev via dip.ideas wrote:
> To declare an enum type that may or may not have one or more
> members depending on conditional compilation statements requires
> duplicating the entire enum:
> ```d
> static if(cond){
>   enum A{
>       x,y,z,w,
>   }
> }else{
>   enum A{
>       x,y,z,
>   }
> }
> ```
>
> For an enum type with many members—or many conditionals—this quickly becomes an insane amount of repetition.
>
> The logical solution is to just allow conditional compilation
> statements inside enums:
> ```d
> enum A{
>   x,y,z,
>      static if(cond){
>       w,
>   }
> }
> ```

Yeah, I'm surprised by this every time that I run into it. I don't think that I've ever tried it with static ifs, since usually, I run into it with an enum where I need to change either the list of enum members and/or their values based on the OS, so I'm trying to use version statements, but it definitely comes up when writing code that has to worry about differences between OSes. For instance, for a socket library, if you have an enum for address families (e.g. inet, inet6, unix, etc.), that list is going to differ depending on the OS.

Now, if the entire enum actually needs to only exist on a particular system, then it makes sense that the whole thing would be versioned, but in the cases where you need to change the list of members or their values based on conditional compilation, it's definitely annoying that you're forced to version the entire enum declaration.

I'm also pretty sure that this is the only place in the language where you can put ddoc comments on individual symbols, but you can't use conditional compilation for those symbols. It acts like a struct with regards to putting ddoc on its members but then acts like an array literal with regards to conditional compilation and its individual members / elements. So, it definitely has inconsistent behavior with regards to other parts of the language.

- Jonathan M Davis




« First   ‹ Prev
1 2