Jump to page: 1 2
Thread overview
UDAs on enum members
Jul 13, 2016
Tomer Filiba
Jul 13, 2016
Chris Wright
Jul 13, 2016
ketmar
Jul 13, 2016
Tomer Filiba
Jul 13, 2016
user1234
Jul 14, 2016
Jacob Carlborg
Jul 16, 2016
ZombineDev
Jul 16, 2016
Sönke Ludwig
Jul 17, 2016
Ali Çehreli
Jul 17, 2016
ketmar
Jul 17, 2016
Jonathan M Davis
Jul 17, 2016
Jacob Carlborg
Jul 17, 2016
Walter Bright
Jul 18, 2016
Basile B.
Aug 31, 2017
EntangledQuanta
Sep 01, 2017
apz28
July 13, 2016
It would be really nice if I could put UDAs on enum members as well, e.g.,

enum MyEnum {
    @("SOM") SomeMember,
    @("ANO") AnotherMemberWithAVeryLongName,
}

I can think of many reasons why that would be desired, but the concrete one is the following: I have an interchangeable data format, and my enum might gain members over time. I don't care about the value of the member, so I don't want to number them myself, but I can't control where users would choose to place the new member, so they might cause renumbering of existing members, breaking the interchangeable format.

So what I wanted is to assign each member a "short stable name" that would be used to serialize the value (using my own dump/load functions)... But I had to resort to a long, ugly switch statement, mapping members to their names and vice versa. The dumping function uses final-switch, so you won't forget to update it, but the loading one can't (it takes a string) so it would be easy to people to forget.

Given that UDAs can be used practically everywhere (including struct/union members), is there an objection to make them legal on enum members as well?

And while we're on the subject, why can't enums have methods? At the risk of sounding as if I like Java (I don't :) ), it's a really nice language feature. Back to our example:

enum MyEnum {
    @("SOM") SomeMember,
    @("ANO") AnotherMemberWithAVeryLongName;

    string dump() {
        ...  // `this` is a value, not a ref here
    }
    static MyEnum load(string name) {
        ...
    }
}

Basically just allow a semicolon at the end of the members, after which methods could appear. Adding members or whatever else Java has is an overkill -- just use a struct for that. But instead of lots of dumpMyEnum(MyEnum e)/loadMyEnum(string s) pairs, you could write myMember.dump()/MyEnum.load(s)


-tomer
July 13, 2016
On Wed, 13 Jul 2016 11:57:21 +0000, Tomer Filiba wrote:
> And while we're on the subject, why can't enums have methods?

Why not use a free function?

import std.stdio;
enum Foo { bar, baz }

void print(Foo f) {
  final switch(f) {
    case Foo.bar:
      writeln("bar");
      break;
    case Foo.baz:
      writeln("baz");
      break;
  }
}

void main() {
  Foo.bar.print();
}

> At the
> risk of sounding as if I like Java (I don't :) ), it's a really nice
> language feature.

Nothing wrong with liking things from Java.
July 13, 2016
On Wednesday, 13 July 2016 at 11:57:21 UTC, Tomer Filiba wrote:
> It would be really nice if I could put UDAs on enum members as well, e.g.,
>
> enum MyEnum {
>     @("SOM") SomeMember,
>     @("ANO") AnotherMemberWithAVeryLongName,
> }
>
> I can think of many reasons why that would be desired, but the concrete one is the following: I have an interchangeable data format, and my enum might gain members over time. I don't care about the value of the member, so I don't want to number them myself, but I can't control where users would choose to place the new member, so they might cause renumbering of existing members, breaking the interchangeable format.
>
> So what I wanted is to assign each member a "short stable name" that would be used to serialize the value (using my own dump/load functions)... But I had to resort to a long, ugly switch statement, mapping members to their names and vice versa. The dumping function uses final-switch, so you won't forget to update it, but the loading one can't (it takes a string) so it would be easy to people to forget.
>
> Given that UDAs can be used practically everywhere (including struct/union members), is there an objection to make them legal on enum members as well?
>
> And while we're on the subject, why can't enums have methods? At the risk of sounding as if I like Java (I don't :) ), it's a really nice language feature. Back to our example:
>
> enum MyEnum {
>     @("SOM") SomeMember,
>     @("ANO") AnotherMemberWithAVeryLongName;
>
>     string dump() {
>         ...  // `this` is a value, not a ref here
>     }
>     static MyEnum load(string name) {
>         ...
>     }
> }
>
> Basically just allow a semicolon at the end of the members, after which methods could appear. Adding members or whatever else Java has is an overkill -- just use a struct for that. But instead of lots of dumpMyEnum(MyEnum e)/loadMyEnum(string s) pairs, you could write myMember.dump()/MyEnum.load(s)
>
>
> -tomer

To the risk of not being usefull I wonder if what you want wouldn't be easier to obtain with a union and a bit of discipline. If you put only manifest constants inside a union you can have methods and UDAs. The union can be verified by a template.

union Enum
{
     int value;
     @("SOM") enum SomeMember = int(0);
     @("ANO") enum AnotherMemberWithAVeryLongName = int(1);
}

template validateEnum(T)
{
    // check for unique-ness of each value
    // check other things.
    enum validateEnum = check();
}

To the question of mapping, since each member has an unique value, the member value itself can be used as hash in an AA without producing clustering. This works well if values are integers or floats.
July 13, 2016
On Wednesday, 13 July 2016 at 12:40:50 UTC, Chris Wright wrote:
> Why not use a free function?

'cause OP wants enum ctor to be called like this:

MyEnum.create(somedata);


2OP: to create enum from string, you can use `std.conv.to`:
  enum E { A, B, C }
  E v = to!E("A");

still not a ctor, but i think that it looks clear enough.
July 13, 2016
On Wednesday, 13 July 2016 at 12:54:19 UTC, ketmar wrote:
> 2OP: to create enum from string, you can use `std.conv.to`:
>   enum E { A, B, C }
>   E v = to!E("A");

I obviously failed to convey the purpose. I don't need a string representation of the enum member, I want to be able to attach UDAs to members. The second part, about Java-like enums, was just an thought. Scratch that.

Right now, I have this real code:

enum Severity: ubyte {
    INFO, WARNING, MINOR, MAJOR, CRITICAL
}
@notrace string severityToString(Severity sev) {
    final switch (sev) with (Severity) {
        case INFO:      return "INF";
        case WARNING:   return "WRN";
        case MINOR:     return "MNR";
        case MAJOR:     return "MJR";
        case CRITICAL:  return "CRT";
    }
}
@notrace Severity stringToSeverity(string sev) {
    switch (sev) with (Severity) {
        case "INF":  return INFO;
        case "WRN":  return WARNING;
        case "MNR":  return MINOR;
        case "MJR":  return MAJOR;
        case "CRT":  return CRITICAL;
        default:     return WARNING;
    }
}

If I could attach UDAs to the enum members', I could just auto-generate that stuff. That's all I'm asking for. The purpose of having a short name is for compression -- this text is going to be stored a lot, and I don't want to store the value, because (a) I don't care what value is assigned to each and (b) users might add new members, anywhere in the enum, causing the values to be remapped.

In other words, I don't want

enum Severity: ubyte {
    INFO, MINOR, MAJOR, WARNING, CRITICAL
}

to break the data I already have

-tomer
July 14, 2016
On 2016-07-13 13:57, Tomer Filiba wrote:
> It would be really nice if I could put UDAs on enum members as well, e.g.,

I think it should be supported, if nothing else for "turtles all the way"/completeness.

-- 
/Jacob Carlborg
July 16, 2016
On Thursday, 14 July 2016 at 07:05:08 UTC, Jacob Carlborg wrote:
> On 2016-07-13 13:57, Tomer Filiba wrote:
>> It would be really nice if I could put UDAs on enum members as well, e.g.,
>
> I think it should be supported, if nothing else for "turtles all the way"/completeness.

I agree. Another thing missing is parameter UDAs. There is [1] a pull request for that, but unfortunately it got stuck about a year ago.

[1]: https://github.com/dlang/dmd/pull/4783
July 16, 2016
Am 16.07.2016 um 20:57 schrieb ZombineDev:
> On Thursday, 14 July 2016 at 07:05:08 UTC, Jacob Carlborg wrote:
>> On 2016-07-13 13:57, Tomer Filiba wrote:
>>> It would be really nice if I could put UDAs on enum members as well,
>>> e.g.,
>>
>> I think it should be supported, if nothing else for "turtles all the
>> way"/completeness.
>
> I agree. Another thing missing is parameter UDAs. There is [1] a pull
> request for that, but unfortunately it got stuck about a year ago.
>
> [1]: https://github.com/dlang/dmd/pull/4783

+1 for both, they would be very useful. For example vibe.d currently requires passing the parameter name as an argument to the UDA to work around the lack of support for UDAs on parameters.

Kind of related, the "deprecated" attribute would also be important to have for enum members [1]. I still have a bunch of enum members that were supposed to be removed/replaced years ago, but there is no way to implement a deprecation process.

[1]: https://issues.dlang.org/show_bug.cgi?id=9395
July 17, 2016
On 07/14/2016 12:05 AM, Jacob Carlborg wrote:
> On 2016-07-13 13:57, Tomer Filiba wrote:
>> It would be really nice if I could put UDAs on enum members as well,
>> e.g.,
>
> I think it should be supported, if nothing else for "turtles all the
> way"/completeness.
>

One more +1...

To those who know the compiler internals, is there a reason why UDA are not applied to all turtles? (I guess the answer is not that simple. :) )

Ali

July 17, 2016
On Sunday, 17 July 2016 at 16:07:13 UTC, Ali Çehreli wrote:
> To those who know the compiler internals, is there a reason why UDA are not applied to all turtles?

mostly 'cause parser doesn't support that.
« First   ‹ Prev
1 2