No we should not support enum types derived from strings

Jon Degenhardt jond at noreply.com
Tue May 11 19:43:34 UTC 2021


On Friday, 7 May 2021 at 11:55:53 UTC, Andrei Alexandrescu wrote:
> On 5/7/21 2:03 AM, evilrat wrote:
>> On Friday, 7 May 2021 at 03:48:47 UTC, Andrei Alexandrescu 
>> wrote:
>>> We should remove all that rot from phobos pronto.
>>>
>>> https://github.com/dlang/phobos/pull/8029
>> 
>> Just a commoner here, can you explain for stupid what makes 
>> enum string a no go and why it should begone?
>
> Heavy toll on the infra for a very niche use case with trivial 
> workarounds on the user side.

To try to put some focus on the user perspective, here's a sample 
program:

```
import std.stdio;
import std.array;
import std.range;

void main()
{
     writefln!"%d"(0);

     immutable string f1 = "%d";
     writefln!f1(1);

     enum f2 = "%d";
     writefln!f2(2);

     enum string f3 = "%d";
     writefln!f3(3);

     enum { f4 = "%d" }
     writefln!f4(4);

     enum : string { f5 = "%d" }
     writefln!f5(5);

     enum X { f6 = "%d" }
     writefln!(X.f6)(6);   // Compilation error

     enum Y : string { f7 = "%d" }
     writefln!(Y.f7)(7);   // Compilation error
}
```

All but the named enums (last two) are fine. These fail with 
similar compilation errors:

```
Error: template std.stdio.writefln cannot deduce function from 
argument types !("%d")(int), candidates are:
dmd-2.095.1/osx/bin/../../src/phobos/std/stdio.d(4258):        
writefln(alias fmt, A...)(A args)
   with fmt = f6,
        A = (int)
   must satisfy the following constraint:
        isSomeString!(typeof(fmt))
dmd-2.095.1/osx/bin/../../src/phobos/std/stdio.d(4269):        
writefln(Char, A...)(in Char[] fmt, A args
```

This is at least a potentially confusing situation for users. The 
error message indicates that `f6` should be a "string" of some 
kind, and it looks like one. One needs to be very familiar with 
the details to understand why it does not satisfy `isSomeString`. 
Similarly with understanding why anonymous enums are fine but 
named enums are not.

The error message is also not particularly helpful in determining 
what the available workarounds are. They may be trivial once 
understood, but there's non-trivial learning to get there. Note 
that slicing (`[]`) and `.representation()` do not work for the 
template argument. Casting does. e.g. The following is fine:

```
     writefln!(cast(string)X.f6)(6);
```

It can be argued that this case is rare enough in user code that 
the ROI from either making the case work or improving the 
compiler error message is too low to devote time to this now. But 
maybe there are other cheap options that could help users. A 
documentation note perhaps. A FAQ somewhere on the D site that 
would surface in searches.


More information about the Digitalmars-d mailing list