Thread overview
[Issue 8432] New: write needs to print full enum type
Jul 25, 2012
Andrej Mitrovic
Jul 25, 2012
Andrej Mitrovic
[Issue 8432] format should qualify enum type with its value
Jan 27, 2013
Andrej Mitrovic
Feb 03, 2013
Andrej Mitrovic
July 25, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8432

           Summary: write needs to print full enum type
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: Phobos
        AssignedTo: nobody@puremagic.com
        ReportedBy: andrej.mitrovich@gmail.com


--- Comment #0 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2012-07-25 06:20:45 PDT ---
enum X { Val }

void main()
{
    string[X] hash;
    hash[X.Val] = "1";
    writeln(hash);

    X[string] hash2;
    hash2["foo"] = X.Val;
    writeln(hash2);
}

Output:
[Val:"1"]
["foo":Val]

This should really be:
[X.Val:"1"]
["foo":X.Val]

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 25, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8432


bearophile_hugs@eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs@eml.cc


--- Comment #1 from bearophile_hugs@eml.cc 2012-07-25 07:06:16 PDT ---
There is a tradeoff here, in some situations what you ask for is good because it makes the output more qualified and explicit:

import std.stdio;
enum FirstEnum { foo, bae }
enum SecondEnum { foo, spam }
void main() {
    auto a = FirstEnum.foo;
    auto b = SecondEnum.foo;
    writeln(a, " ", b);
}

It prints:

foo foo

While with your proposal it prints an output that allows you to see the types:

FirstEnum.foo SecondEnum.foo


But in some other cases it's not so good. In most real cases enums have a name longer than your "X". With DMD 2.2060beta this program:


import std.stdio;
enum SomeLongEnumName { foo, bar, baz, spam }
void main() {
    SomeLongEnumName[] a;
    with (SomeLongEnumName)
         a = [foo, bar, baz, spam, foo, bar, baz, spam, foo, bar, baz, spam];
    writeln(a);
}


Prints:

[foo, bar, baz, spam, foo, bar, baz, spam, foo, bar, baz, spam]

With your proposal it prints:

[SomeLongEnumName.foo, SomeLongEnumName.bar, SomeLongEnumName.baz, SomeLongEnumName.spam, SomeLongEnumName.foo, SomeLongEnumName.bar, SomeLongEnumName.baz, SomeLongEnumName.spam, SomeLongEnumName.foo, SomeLongEnumName.bar, SomeLongEnumName.baz, SomeLongEnumName.spam]

That in my opinion is unacceptably noisy.


And when you really need the enum names it's not too much hard to add them to the textual output (despite it requires a little longer code):

import std.stdio;
enum FirstEnum { foo, bae }
enum SecondEnum { foo, spam }
void main() {
    auto a = FirstEnum.foo;
    auto b = SecondEnum.foo;
    writeln(typeof(a).stringof, ".", a, " ",
            typeof(b).stringof, ".", b);
}


It prints:

FirstEnum.foo SecondEnum.foo


An alternative idea is to print single enums qualified with their enum name and print enums in collections without their enum name. This means this program:


import std.stdio;
enum SomeLongEnumName { foo, bar, baz, spam }
void main() {
    SomeLongEnumName a;
    SomeLongEnumName[] b;
    with (SomeLongEnumName) {
        a = bar;
        b = [foo, bar, baz, spam, foo, bar, baz, spam, foo, bar, baz, spam];
     }
    writeln(a);
    writeln(b);
}


will print:

SomeLongEnumName.bar
[foo, bar, baz, spam, foo, bar, baz, spam, foo, bar, baz, spam]

But if you want to print many single enum variables without their enum name, how do you remove it? Adding "typeof(a).stringof, "."," before them in the writeln is simpler than removing the lading enum name. Python2 print statement adds a space between items, this is usually handy, but when you don't want that damned space, you have to use other functions from the std.library. This was so bad that in Python3 they have fixed it. Generally adding is simpler than removing.

So in the end I am against your proposal, and I think the current situation is the best of all the alternatives I can think of (but maybe someone is able to find a better new idea).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 25, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8432



--- Comment #2 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2012-07-25 09:02:56 PDT ---
If you use enum arrays with writeln() you would typically use shorter names. My issue is that this can make reading output ambiguous:

enum X { foo }
enum Y { foo }

void main()
{
    X x;
    Y y;
    writeln(x);
    writeln(y);
}

outputs:
foo
foo

In C++ you don't have to use the enum tag, but in D you do, and it would make sense to output the correct type definition.

Consider another case which is why I filed this:

enum Type { Class, Struct, Enum }

struct Class { }
struct Struct { }
struct Enum { }

void main()
{
    Type[string] type = ["foo" : Type.Class];
    writeln(type);
}

outputs:
["foo":Class]

This output confused me since Class is both a struct definition and a named enumerated value. I use writeln() almost strictly for debugging and I would really want to see *valid* type info, which means a string representation that could be re-inserted into code which you could practically mix in (not that I would do that but it makes sense to keep a 1:1 mapping like this).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 25, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8432



--- Comment #3 from bearophile_hugs@eml.cc 2012-07-25 11:54:03 PDT ---
(In reply to comment #2)

> enum Type { Class, Struct, Enum }
> 
> struct Class { }
> struct Struct { }
> struct Enum { }
> 
> void main()
> {
>     Type[string] type = ["foo" : Type.Class];
>     writeln(type);
> }
> 
> outputs:
> ["foo":Class]
> 
> This output confused me since Class is both a struct definition and a named enumerated value.

A partial solution is to add the type:

writeln(typeof(type).stringof, ": ", type);

It prints:

Type[string]: ["foo":Class]

Now you see that the keys can't be the struct name.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 27, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=8432


Andrej Mitrovic <andrej.mitrovich@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         AssignedTo|nobody@puremagic.com        |andrej.mitrovich@gmail.com
            Summary|write needs to print full   |format should qualify enum
                   |enum type                   |type with its value


--- Comment #4 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2013-01-26 16:41:39 PST ---
Other than introducing a new format specifier, I'm not sure how to proceed.

Perhaps a '%q' for "qualified" would do it.

Andrei if you're reading this I'd like to get an opinion so I can work on it or close the report. Thanks.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 03, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=8432


Andrej Mitrovic <andrej.mitrovich@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |WONTFIX


--- Comment #5 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2013-02-03 13:01:48 PST ---
Not too important for me, I'm closing it.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------