Frist Draft (in this forum): Enum Parameters

Paul Backus snarwin at gmail.com
Tue May 7 17:44:25 UTC 2024


On Tuesday, 7 May 2024 at 16:34:52 UTC, Steven Schveighoffer 
wrote:
> I don't think this is going to be the case. Consider that 
> without explicitly forwarding, the difficulty is not in 
> preserving refness, but non-refness. If care is not taken (e.g. 
> via using forward), then a non-ref parameter suddenly turns 
> into a ref parameter (implicitly). This is not the case for 
> enum parameters -- enumness is preserved whether it's not an 
> enum or is an enum.

If a single function in a call stack forgets to pass a given 
parameter by `ref`, it will be copied. If your code relies on the 
parameter not being copied (e.g., if it has a disabled copy 
constructor), this failure to preserve `ref` results in a bug.

If a single function in a call stack forgets to pass a given 
parameter by `enum`, it will be evaluated at runtime. If your 
code relies on the parameter being evaluable at compile time 
(e.g., if it uses it as a template argument or in a `static if` 
condition), this failure to preserve `enum` results in a bug.

The two are exactly analogous.

> Yes, generic code that wishes to forward enum-ness to another 
> thing must use auto enum to accomplish this. However, comparing 
> to the the current mechanism, things are pretty inferior. 
> Switching from an enum parameter to a runtime parameter 
> involves *changing the place where parameters are put*. You 
> currently have to remember to create a nested template with an 
> outer template that takes a tuple for this to work correctly 
> (something which I doubt many generic functions do).
>
> Put another way, if the cost of having the convenience of enum 
> parameters is that we must also allow auto enum, I don't think 
> this is a large enough drawback.

The argument here is essentially that it is worth it to make the 
library *author's* job more difficult in order to give the 
library *users* a better experience.

In general, I agree. But there's a point at which this argument 
falls apart. If you make the library author's job so difficult 
that they can no longer write correct code, it is library users 
who will ultimately suffer.

Personally, I think the `ref` storage class *already* crosses 
this line. The vast majority of generic D code does not handle 
non-copyable types correctly, and the design of `ref` is 100% to 
blame for this. Since `enum` uses the exact same design as `ref`, 
I think it's pretty reasonable to assume that it will cause the 
same kinds of problems.

So, when I evaluate this DIP, here's the tradeoff I'm looking at:

* **Pro:** more convenient library APIs (e.g., `format`).
* **Con:** more bugs in generic library code.

I don't think this is a good tradeoff.


More information about the dip.development mailing list