Jump to page: 1 2 3
Thread overview
Struct Initialization syntax
Jul 23, 2018
Seb
Jul 23, 2018
Luís Marques
Jul 23, 2018
H. S. Teoh
Jul 23, 2018
aliak
Jul 23, 2018
H. S. Teoh
Jul 23, 2018
aliak
Jul 23, 2018
Luís Marques
Jul 23, 2018
kinke
Jul 24, 2018
rikki cattermole
Jul 24, 2018
Daniel N
Jul 24, 2018
rikki cattermole
Jul 23, 2018
John Colvin
Jul 25, 2018
Guillaume Lathoud
Jul 23, 2018
Cym13
Jul 23, 2018
Cym13
Jul 23, 2018
Andre Pany
Jul 23, 2018
JohnB
Jul 23, 2018
Jacob Carlborg
Jul 24, 2018
rikki cattermole
Jul 24, 2018
Dukc
Jul 24, 2018
Cym13
Jul 24, 2018
Dukc
Jul 24, 2018
H. S. Teoh
Jul 26, 2018
Jim Balter
Jul 24, 2018
Neia Neutuladh
Jul 25, 2018
rikki cattermole
July 23, 2018
tl;dr: the currently proposed syntax options are:


---
struct S
{
    int a = 2, b = 4, c = 6;
}
void foo()
{
    bar(S({c: 10})); // Option 1
    bar(S(c: 10));   // Option 2
    bar(S{c: 10});   // Option 3
}
---

So the struct-initialization DIP has been stalled for too long and I think it's time we finally get this story done.
I personally prefer option 2, but this might be in conflict to named arguments which we hopefully see in the near future too. Hence, I'm leaning forward to proposing Option 1 as the recommended Option for the DIP (that's also what the PoC DMD PR implements). What's your take on this?

DIP: https://github.com/dlang/DIPs/pull/71
Rendered view: https://github.com/wilzbach/DIPs/blob/struct-initialization/DIPs/DIP1xxx-sw.md
July 23, 2018
On Monday, 23 July 2018 at 16:26:42 UTC, Seb wrote:
> Hence, I'm leaning forward to proposing Option 1 as the recommended Option for the DIP (that's also what the PoC DMD PR implements). What's your take on this?

Although a bit more verbose that seems like a good choice. If you could save the “initialization list” in an enum that choice also seems to generalize better. Not conflicting with named arguments is important for me, as named arguments would be very nice to have for hardware description kind of stuff.


July 23, 2018
On Mon, Jul 23, 2018 at 04:26:42PM +0000, Seb via Digitalmars-d wrote:
> tl;dr: the currently proposed syntax options are:
> ---
> struct S
> {
>     int a = 2, b = 4, c = 6;
> }
> void foo()
> {
>     bar(S({c: 10})); // Option 1
>     bar(S(c: 10));   // Option 2
>     bar(S{c: 10});   // Option 3
> }
> ---
> 
> So the struct-initialization DIP has been stalled for too long and I think it's time we finally get this story done.

+1.


> I personally prefer option 2, but this might be in conflict to named arguments which we hopefully see in the near future too.

Yeah.


> Hence, I'm leaning forward to proposing Option 1 as the recommended Option for the DIP (that's also what the PoC DMD PR implements). What's your take on this?
[...]

I don't like option 1 because it resembles anonymous function syntax and AA initialization syntax, but is actually neither.

I'm on the fence about option 2 and option 3.

I actually prefer option 3 as being overtly special initialization syntax that doesn't try to masquerade as something else.

But OTOH, option 2 has a lot going for it, given that today, S(x, y, z)
is the syntax for initializing struct fields in order, so one would
expect that S(p: x, q: y, r: z) ought to be a natural extension of the
syntax for specifying fields out-of-order (or with some fields omitted).

It's true that there's potential conflict with named arguments, but IMO it's a mighty bad idea to name ctor parameters in a way that conflicts with the struct fields.  Either your struct has a member named x, your ctor uses parameter names that are different from x (thus avoiding the confusion), or if your ctor also takes a parameter named x, in which case one would expect that it would initialize the member x, as opposed to a different member y.  To have a ctor take a parameter named x but using it to initialize member y instead of member x, seems to be such a horrible idea that it should not be a big deal for struct initialization syntax to "conflict" with it.


T

-- 
If you want to solve a problem, you need to address its root cause, not just its symptoms. Otherwise it's like treating cancer with Tylenol...
July 23, 2018
On Monday, 23 July 2018 at 16:26:42 UTC, Seb wrote:
> tl;dr: the currently proposed syntax options are:
>
>
> ---
> struct S
> {
>     int a = 2, b = 4, c = 6;
> }
> void foo()
> {
>     bar(S({c: 10})); // Option 1
>     bar(S(c: 10));   // Option 2
>     bar(S{c: 10});   // Option 3
> }
> ---
>
> So the struct-initialization DIP has been stalled for too long and I think it's time we finally get this story done.
> I personally prefer option 2, but this might be in conflict to named arguments which we hopefully see in the near future too. Hence, I'm leaning forward to proposing Option 1 as the recommended Option for the DIP (that's also what the PoC DMD PR implements). What's your take on this?
>
> DIP: https://github.com/dlang/DIPs/pull/71
> Rendered view: https://github.com/wilzbach/DIPs/blob/struct-initialization/DIPs/DIP1xxx-sw.md

I'm in favour of 3.

Option 2 looks nice but I'm against it because of possible named arguments. Even though they're not part of the language yet and may never be we already have too many clunky things not to avoid a conflict when we can.

Option 1 is clean but a bit strange, I don't like the idea of doubling the enclosing symbols, in that situation you'd expect S() and {} to have separate effects, not to combine into a special effect. It also looks like a constructor while it's not, which isn't a nice conflation to make. I wouldn't be very dismayed by it though.

Still, that's why I prefer option 3 which is very similar to classical struct initialization and has clearly only one effect.

PS: Now that I think about it, would something like S{c:3}("a") be allowed to say “Call the constructor with the string "a" as argument on the struct of type S initialized with c=3”? I may have missed it but I don't think that's addressed by the DIP.
July 23, 2018
On Monday, 23 July 2018 at 17:10:08 UTC, Cym13 wrote:
> PS: Now that I think about it, would something like S{c:3}("a") be allowed to say “Call the constructor with the string "a" as argument on the struct of type S initialized with c=3”? I may have missed it but I don't think that's addressed by the DIP.

I took that last point to GH, no need to discuss it here.
July 23, 2018
On Monday, 23 July 2018 at 16:57:20 UTC, H. S. Teoh wrote:

> It's true that there's potential conflict with named arguments, but IMO it's a mighty bad idea to name ctor parameters in a way that conflicts with the struct fields.

After using Swift for a while, I've found this to be the exact opposite. It is on the contrary very common to name parameters as you would your members because they are very commonly the most intuitive names.

struct Point {
  int x, int y;
  this(x: int, y: int) {}
}

auto p = Point(x: 3, y: 4); // what else would you name them?

Can we just consider that named struct init syntax *is* a generated named constructor?

If named arguments choose a different syntax then you have no conflict. If they go with the same (i.e. option 2) then you have seamless consistency.

Cheers,
- Ali
July 23, 2018
On Mon, Jul 23, 2018 at 05:32:23PM +0000, aliak via Digitalmars-d wrote:
> On Monday, 23 July 2018 at 16:57:20 UTC, H. S. Teoh wrote:
> 
> > It's true that there's potential conflict with named arguments, but IMO it's a mighty bad idea to name ctor parameters in a way that conflicts with the struct fields.
> 
> After using Swift for a while, I've found this to be the exact opposite. It is on the contrary very common to name parameters as you would your members because they are very commonly the most intuitive names.
[...]

I worded myself poorly.  What I meant was that if a ctor parameter has the same name as a field, then it's obviously meant to initialize that field, so there isn't really a conflict, you're just passing the argument to the ctor instead of setting it directly to the struct.  It would be a horrendously bad idea to have a ctor parameter that has the same name as a field, but is used to initialize a different field.

OTOH, if you have a ctor, then one would assume that you're intentionally overriding direct initialization of fields, so you wouldn't want people to be using named initialization of fields anyway, they should be using the ctor instead.  So any conflicts in this area wouldn't really be relevant.


> struct Point {
>   int x, int y;
>   this(x: int, y: int) {}
> }
> 
> auto p = Point(x: 3, y: 4); // what else would you name them?
> 
> Can we just consider that named struct init syntax *is* a generated named constructor?
> 
> If named arguments choose a different syntax then you have no conflict. If they go with the same (i.e. option 2) then you have seamless consistency.
[...]

Yes, this is what I was trying to get at.  Thanks!


T

-- 
Don't modify spaghetti code unless you can eat the consequences.
July 23, 2018
On Monday, 23 July 2018 at 17:46:12 UTC, H. S. Teoh wrote:
> I worded myself poorly.  What I meant was that if a ctor parameter has the same name as a field, then it's obviously meant to initialize that field, so there isn't really a conflict, you're just passing the argument to the ctor instead of setting it directly to the struct.  It would be a horrendously bad idea to have a ctor parameter that has the same name as a field, but is used to initialize a different field.
> [...]
>> 
>> If named arguments choose a different syntax then you have no conflict. If they go with the same (i.e. option 2) then you have seamless consistency.
> [...]
>
> Yes, this is what I was trying to get at.  Thanks!
>
>
> T

Hehe oops, indeed you were :p Seems I did not parse properly. Apologies!

Cheers,
- Ali

July 23, 2018
On Monday, 23 July 2018 at 17:46:12 UTC, H. S. Teoh wrote:
> Yes, this is what I was trying to get at.  Thanks!

If such integration was possible then that sounds like it would be a good solution.


July 23, 2018
On Monday, 23 July 2018 at 16:26:42 UTC, Seb wrote:
> tl;dr: the currently proposed syntax options are:
>
>
> ---
> struct S
> {
>     int a = 2, b = 4, c = 6;
> }
> void foo()
> {
>     bar(S({c: 10})); // Option 1
>     bar(S(c: 10));   // Option 2
>     bar(S{c: 10});   // Option 3
> }
> ---
>
> So the struct-initialization DIP has been stalled for too long and I think it's time we finally get this story done.
> I personally prefer option 2, but this might be in conflict to named arguments which we hopefully see in the near future too. Hence, I'm leaning forward to proposing Option 1 as the recommended Option for the DIP (that's also what the PoC DMD PR implements). What's your take on this?
>
> DIP: https://github.com/dlang/DIPs/pull/71
> Rendered view: https://github.com/wilzbach/DIPs/blob/struct-initialization/DIPs/DIP1xxx-sw.md

I also prefer option 3. From a readability point of view it is the most pleasant one (my personal opinion). I also like it due to the already existing struct initialization syntax I am using a lot.

Kind regards
Andre
« First   ‹ Prev
1 2 3