November 19, 2022

On Saturday, 19 November 2022 at 01:04:39 UTC, Ki Rill wrote:

>

On Friday, 18 November 2022 at 15:37:31 UTC, Mike Parker wrote:

>

Discussion Thread

[...]

I think it's not worth adding this to D as well. I have no problem typing out the full name of an enum, and if I or anyone else does face such a difficulty, why not use a short alias?

with(a, b, c, d):

That's a good idea.

MySuperLongType flag = MySuperLongType.ValueA | MySuperLongType.ValueB | MySuperLongType.ValueC | MySuperLongType.ValueD | MySuperLongType.ValueE | MySuperLongType.ValueF | MySuperLongType.ValueG;

// vs

MySuperLongType flag = .ValueA | .ValueB | .ValueC | .ValueD | .ValueE | .ValueF | .ValueG;


No need to import any helper function, no need to introduce any extra noisy variable, no need to bloat the scope with with or alias, it's simple, readable, and effective

Have you ever tried Vulkan? (graphics library)

The amount of ugly code one has to write due to verbose enum/struct name is disgusting

Also D already supports designated initialization for structs, it's kinda similar in principle, and it is super useful

November 18, 2022
On 11/18/2022 6:06 PM, ryuukk_ wrote:
> MySuperLongType flag = MySuperLongType.ValueA | MySuperLongType.ValueB | MySuperLongType.ValueC | MySuperLongType.ValueD | MySuperLongType.ValueE | MySuperLongType.ValueF | MySuperLongType.ValueG;
> 
> // vs
> 
> MySuperLongType flag = .ValueA | .ValueB | .ValueC | .ValueD | .ValueE | .ValueF | .ValueG;

with (MySuperLongType)
MySuperLongType flag = ValueA | ValueB | ValueC | ValueD | ValueE | ValueF | ValueG;
November 19, 2022
On 19.11.22 03:54, Walter Bright wrote:
> With the syntax $e to look up an enum member, the compiler will need to search *every* enum that is in scope. Since one of D's strengths is whole program compilation, this can be slow. To speed that up, it will likely require that the compiler maintain a hash table of all the enum fields.
> 
> I.e. a parallel symbol table will have to be maintained alongside the regular symbol table. 

Not true. E.g. see my example with delegates.
November 19, 2022
On Saturday, 19 November 2022 at 02:57:27 UTC, Walter Bright wrote:
> with (MySuperLongType)
> MySuperLongType flag = ValueA | ValueB | ValueC | ValueD | ValueE | ValueF | ValueG;

`flag` is now inaccessible since `with` creates a new scope.

Of course, you may be able to just extend the scope to cover the usage point as well.
November 19, 2022

On Saturday, 19 November 2022 at 02:06:57 UTC, ryuukk_ wrote:

>
MySuperLongType flag = MySuperLongType.ValueA | MySuperLongType.ValueB | MySuperLongType.ValueC | MySuperLongType.ValueD | MySuperLongType.ValueE | MySuperLongType.ValueF | MySuperLongType.ValueG;

// vs

MySuperLongType flag = .ValueA | .ValueB | .ValueC | .ValueD | .ValueE | .ValueF | .ValueG;

Very, very simple solution:

MySuperLongType flag = M.ValueA | M.ValueB | M.ValueC | M.ValueD |  M.ValueE | M.ValueF | M.ValueG;

I mean, if you don't want to type that much, use shorter names.

November 19, 2022

On Saturday, 19 November 2022 at 02:57:27 UTC, Walter Bright wrote:

>

On 11/18/2022 6:06 PM, ryuukk_ wrote:

>

MySuperLongType flag = MySuperLongType.ValueA | MySuperLongType.ValueB | MySuperLongType.ValueC | MySuperLongType.ValueD | MySuperLongType.ValueE | MySuperLongType.ValueF | MySuperLongType.ValueG;

// vs

MySuperLongType flag = .ValueA | .ValueB | .ValueC | .ValueD | .ValueE | .ValueF | .ValueG;

with (MySuperLongType)
MySuperLongType flag = ValueA | ValueB | ValueC | ValueD | ValueE | ValueF | ValueG;

Why should i have to type the name of the type twice? it doesn't help with readability

Imagine on this small example, that would be overkill

Little experiment, read it out loud, the repetition and noise is clearly not wanted

NetworkState network_state = NetworkSate.DISCONNECTED;

Another example:

if (client.network_state == NetworkState.CONNECTED)
    client.network_state = NetworkState.DISCONNECTED;

// vs

with (NetworkState)
if (client.network_state == CONNECTED)
    client.network_state = DISCONNECTED;

// same issue as above, reading it feels repetitive, and it adds extra cognitive load


// there, straith to the point
// you can name your variable more verbosely, you no longer have to duplicate enum type everywhere
// type system is smart enough
if (client.network_state == .CONNECTED)
    client.network_state = .DISCONNECTED;

Taken from my project, c'mon, if i use proper naming in my code, i should be allowed to ommit the typename of the enum

Just like i can omit the type of the integer

int myInt = 42;

// and not
int myInt = int.42;
    if (ctx.engine.input.is_key_just_pressed(.PAGE_UP))
    {
        cam_pos_d *= 1.2;
        cam_pos_h *= 1.2;
    }
November 19, 2022

On Saturday, 19 November 2022 at 03:15:26 UTC, bachmeier wrote:

>

On Saturday, 19 November 2022 at 02:06:57 UTC, ryuukk_ wrote:

>
MySuperLongType flag = MySuperLongType.ValueA | MySuperLongType.ValueB | MySuperLongType.ValueC | MySuperLongType.ValueD | MySuperLongType.ValueE | MySuperLongType.ValueF | MySuperLongType.ValueG;

// vs

MySuperLongType flag = .ValueA | .ValueB | .ValueC | .ValueD | .ValueE | .ValueF | .ValueG;

Very, very simple solution:

MySuperLongType flag = M.ValueA | M.ValueB | M.ValueC | M.ValueD |  M.ValueE | M.ValueF | M.ValueG;

I mean, if you don't want to type that much, use shorter names.

Using shorter type/variable name is what hurts readability of your code

Using proper naming is the key, if i can omit the type name of the enum and leverage the type system, i am encouraged to use meaningful and longer type/variable name, wich improve readability

// the function name is verbose, i know it passes the enumeration type of keys
is_key_pressed(.A);
is_key_pressed(Key.A);

// vs

// the function name is short, what should i pass?
// of you passed and enumeration type of keys
// therefore you ask if it's a key that was pressed
is_pressed(.A);
is_pressed(Key.A);

I should have the choice

November 18, 2022
On 11/18/2022 7:09 PM, Adam D. Ruppe wrote:
> On Saturday, 19 November 2022 at 02:57:27 UTC, Walter Bright wrote:
>> with (MySuperLongType)
>> MySuperLongType flag = ValueA | ValueB | ValueC | ValueD | ValueE | ValueF | ValueG;
> 
> `flag` is now inaccessible since `with` creates a new scope.


True, but you could also do:

with (MySuperLongType):  // <= note colon
MySuperLongType flag = ValueA | ValueB | ValueC | ValueD | ValueE | ValueF |
 ValueG;


> Of course, you may be able to just extend the scope to cover the usage point as well.

Yup.
November 18, 2022
On 11/18/2022 7:05 PM, Timon Gehr wrote:
> On 19.11.22 03:54, Walter Bright wrote:
>> With the syntax $e to look up an enum member, the compiler will need to search *every* enum that is in scope. Since one of D's strengths is whole program compilation, this can be slow. To speed that up, it will likely require that the compiler maintain a hash table of all the enum fields.
>>
>> I.e. a parallel symbol table will have to be maintained alongside the regular symbol table. 
> 
> Not true. E.g. see my example with delegates.

I was thinking of the general case of $a being able to find member `a` among all the enums in scope.

You're referring, of course, to the "contextual" part of the DIP, where the lookup works only in a subset of cases. The contextual lookup can result in some odd cases like:

---- module A ----
    private enum E { e; };
    public void dra(E);
------------------
    import A;

    dra($e);
------------------

Is that a good thing? I'm not sure. This is also not addressed in the DIP.


November 18, 2022
Consider this:

    enum A { a; }
    enum B { a; }

    void f(A);
    void f(B);

    ...
    f($a + $a); // mentioned in the DIP as allowed
    ...

Since the DIP allows expressions containing such enum inferences, it looks like we are faced with the possibility of having to re-run the semantic pass for enum arguments for every enum overload.