DIP 1031--Deprecate Brace-Style Struct Initializers--Community Review Round 1 Discussion

12345swordy alexanderheistermann at gmail.com
Fri Feb 14 16:19:10 UTC 2020


On Friday, 14 February 2020 at 14:46:43 UTC, Steven Schveighoffer 
wrote:
> On 2/14/20 12:53 AM, Mathias Lang wrote:
>> On Thursday, 13 February 2020 at 07:29:00 UTC, Mike Parker 
>> wrote:
>>> This is the feedback thread for the first round of Community 
>>> Review for DIP 1031, "Deprecate Brace-Style Struct 
>>> Initializers":
>>>
>>> https://github.com/dlang/DIPs/blob/c0c1c9f9665e0bc1db611f4e93e793d64451f763/DIPs/DIP1031.md
>>>
>> 
>> 
>> I think this is heading in the right direction, however I see 
>> three issues:
>> 
>> 1) The type name has to be repeated.
>>      So as mentioned, `Foo f = (42, 84);` would be more 
>> readable than `Foo f = Foo(42, 84);`.
>>      This gets worse when a struct contains nested struct 
>> definitions, as Andre pointed out (here: 
>> https://github.com/dlang/DIPs/pull/169#issuecomment-532830320).
>> 
>> 2) It's actually part of 1, but I wanted to make it a separate 
>> issue because it's important. Not *all* usages of struct 
>> initializer can be replaced by the constructor syntax. For 
>> example:
>> ```
>> --- definition.d
>> module definition;
>> 
>> struct Foo
>> {
>>      private struct Bar
>>      {
>>          int a;
>>          int b;
>>      }
>> 
>>      Bar ber;
>> }
>> 
>> --- main.d
>> module main;
>> import definition;
>> 
>> void main ()
>> {
>>      Foo f = { ber: { a: 42, b: 84 } };
>> }
>> ```
>> 
>> To replace this usage, one has to use `typeof(Foo.ber)`. Even 
>> more verbose.
>> 
>
> This is probably less of a problem. If you need to initialize 
> items via static construction with a private type, chances are 
> the library gives you a mechanism to do that.
>
> However even when you have public access to the name, but the 
> name is unwieldy (e.g. the templates in your followup message), 
> makes this look like a bigger problem than the simple examples. 
> Imagine a struct with a static array of structs. Currently you 
> can do this:
>
> struct Vector2D
> {
>   float x;
>   float y;
> }
> struct Moves
> {
>    Vector2D[4] items;
> }
>
> Moves awsd = {items: [{x: 1, y: 0}, {x: 0, y: 1}, {x: -1, y: 
> 0}, {x:0, y:-1}]};
>
> But with this DIP, the call now becomes:
>
> Moves awsd = Moves(items: [Vector2D(x: 1, y: 0), Vector2D(x: 0, 
> y: 1), Vector2D(x: -1, y: 0), Vector2D(x:0, y:-1)]);
>
> Now, imagine Vector2D and Moves are templated on type! Would be 
> horrendous.
>
> I can think of a solution though, just have a substitute for 
> the real name of the type for struct initializers. In other 
> words, this is not a function call, and does not have possible 
> overloads. Something like:
>
> Foo f = Foo(ber: auto(a: 42, b: 84));
>
> It's not as terse, but circumvents for the most part the issue 
> of long names.
>
> You could even just keep the initializer syntax but with 
> parentheses instead of braces:
>
> Foo f = Foo(ber: (a: 42, b: 84)); // only valid for struct 
> initialization without a ctor.
>
> I think this would be unambiguous. But at that point, why are 
> we even deprecating the current syntax?
>
> Indeed, I think instead of deprecation, we should first just 
> provide the alternative, and see how it goes.
>
> I'm also not sure we even need to deprecate this feature. We 
> aren't gaining anything syntax-wise, and it's not harmful for 
> the compiler to support it as far as I can tell.
>
> -Steve

I was thinking of this when you brought up that issue.
https://github.com/dotnet/csharplang/issues/100

I.E.
Moves awsd = Moves(items: [(x: 1, y: 0), (x: 0, y: 1), (x: -1, y: 
0), (x:0, y:-1)]);


More information about the Digitalmars-d mailing list