Re: Struct initialization has no effect or error?

2019-10-03 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, October 2, 2019 11:48:46 PM MDT Mike Parker via Digitalmars-d-
learn wrote:
> On Thursday, 3 October 2019 at 04:57:44 UTC, mipri wrote:
> > On Thursday, 3 October 2019 at 04:33:26 UTC, Brett wrote:
> >> I was trying to avoid such things since X is quite long in
> >> name. Not a huge deal... and I do not like the syntax because
> >> it looks like a constructor call.
> >
> > It is a constructor call, though. You can define your own as
>
> > well:
> Technically it's a struct literal. It's only a constructor if you
> define one, in which case struct literals no longer work. E.g.,
>
> struct Foo {
>  int x;
>
>  this(int a, int b) { x = a + b; }
> }
>
> Without the constructor, the literal Foo(10) would be valid, but
> with the constructor you'll get a compiler error.

Yeah. Syntactically, there's no real distinction, but the compiler doesn't
do something like generate a constructor for you, and unlike with a
constructor, you won't necessarily get errors if you do something like use
too few arguments. So, if you had

struct S
{
int x;
}

auto s = S(42);

and then changed it to

struct S
{
int x;
int y;
}

auto s = S(42);

the code would continue to compile without complaint. And if you had
something like

struct S
{
string s;
int i;
}

auto s = S("hello", 42);

struct S
{
string s;
int foo;
int i;
}

auto s = S("hello", 42);

you end up initializing the wrong members. The same if had

struct S
{
int x;
int y;
}

auto s = S(12, 99);

and changed it to

struct S
{
int y;
int x;
}

auto s = S(12, 99);

The fact that struct literals exist basically forces you to declare
constructors if you don't want to have to worry about breaking code by
rearranging member variables.

Personally, I think that using struct literals is just begging for bugs in
your code, so I never use them, and I always declare constructors. I wish
that struct literals weren't a thing at all, but some folks clearly like
them.

If using a struct literal with braces without providing the member names
gets deprecated like apparently Walter wants to do, then maybe using the
construction syntax for struct literals would be deprecated as well, which
would at least improve the situation. struct literals with member names are
still error-prone, but at least you then eliminate the bugs where you
initialize the wrong members and instead just get the ones where new members
end up with the default value whether it's appropriate or not.

- Jonathan M Davis





Re: Struct initialization has no effect or error?

2019-10-02 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 3 October 2019 at 04:57:44 UTC, mipri wrote:

On Thursday, 3 October 2019 at 04:33:26 UTC, Brett wrote:
I was trying to avoid such things since X is quite long in 
name. Not a huge deal... and I do not like the syntax because 
it looks like a constructor call.


It is a constructor call, though. You can define your own as 
well:



Technically it's a struct literal. It's only a constructor if you 
define one, in which case struct literals no longer work. E.g.,


struct Foo {
int x;

this(int a, int b) { x = a + b; }
}

Without the constructor, the literal Foo(10) would be valid, but 
with the constructor you'll get a compiler error.




Re: Struct initialization has no effect or error?

2019-10-02 Thread mipri via Digitalmars-d-learn

On Thursday, 3 October 2019 at 04:33:26 UTC, Brett wrote:
I was trying to avoid such things since X is quite long in 
name. Not a huge deal... and I do not like the syntax because 
it looks like a constructor call.


It is a constructor call, though. You can define your own as well:

  #! /usr/bin/env rdmd
  import std.stdio;

  struct X {
  int a;

  this(int x) {
  a = x * 2;
  }
  }

  void main() {
  auto test = X(22);
  writeln(test.a);
  }

output: 44



Re: Struct initialization has no effect or error?

2019-10-02 Thread Brett via Digitalmars-d-learn

On Wednesday, 2 October 2019 at 17:54:20 UTC, H. S. Teoh wrote:
On Wed, Oct 02, 2019 at 05:37:57PM +, Brett via 
Digitalmars-d-learn wrote:

struct X { int a; }

X[1] x;

x[0] = {3};

or

x[0] = {a:3};

fails;


This works:

x[0] = X(123);



Should the syntax not extend to the case of array assignment?


Arguably it should. But it's mainly cosmetic, since the X(123) 
syntax works just fine. (It *is* an incongruity in D's syntax, 
though. It's not a big deal once you learn it, but it's a bit 
counterintuitive the first time you need to use it.)




This avoids a double copy.

[...]

Which any modern optimizer would optimize away.


T


I was trying to avoid such things since X is quite long in name. 
Not a huge deal... and I do not like the syntax because it looks 
like a constructor call.


Re: Struct initialization has no effect or error?

2019-10-02 Thread Andre Pany via Digitalmars-d-learn

On Wednesday, 2 October 2019 at 18:35:39 UTC, mipri wrote:

On Wednesday, 2 October 2019 at 17:37:57 UTC, Brett wrote:

X y = {3};

works fine.

So one has to do

x[0] = y;


You could initialize x all at once. Complete example:

  import std.stdio;

  struct Point {
  int x, y;

  string toString() {
  import std.format : format;

  return format("(%d, %d)", x, y);
  }
  }

  void main() {
  Point[2] ps = [{0,0}, {4,4}];
  foreach (p; ps) writeln(p);
  }


The brace style struct initializer will likely be deprecated. 
Please see here https://github.com/dlang/DIPs/pull/169


Kind regards
Andre


Re: Struct initialization has no effect or error?

2019-10-02 Thread mipri via Digitalmars-d-learn

On Wednesday, 2 October 2019 at 17:37:57 UTC, Brett wrote:

X y = {3};

works fine.

So one has to do

x[0] = y;


You could initialize x all at once. Complete example:

  import std.stdio;

  struct Point {
  int x, y;

  string toString() {
  import std.format : format;

  return format("(%d, %d)", x, y);
  }
  }

  void main() {
  Point[2] ps = [{0,0}, {4,4}];
  foreach (p; ps) writeln(p);
  }



Re: Struct initialization has no effect or error?

2019-10-02 Thread mipri via Digitalmars-d-learn

On Wednesday, 2 October 2019 at 17:54:20 UTC, H. S. Teoh wrote:
On Wed, Oct 02, 2019 at 05:37:57PM +, Brett via 
Digitalmars-d-learn wrote:

struct X { int a; }

X[1] x;

x[0] = {3};

or

x[0] = {a:3};

fails;


This works:

x[0] = X(123);



I'd knew I'd gotten the impression from somewhere that this was 
the
recommended way to initialize structs, but it took me a while to 
find

it.

Learning D:

  auto ms1 = MyStruct(10, 11);// struct literal
  MyStruct ms2 = {10, 11};// C-style, not preferred
  MyStruct ms3 = {b:11, a:10};// Named initializers

  ..

  Struct literals are convenient for simple types ...
  but they only allow for direct initialization of member
  variables. If more complex initialization is required, struct
  constructors should be used.

And then the impression was probably just from every single 
example

using the first form.

https://dlang.org/spec/struct.html#static_struct_init doesn't say 
that
this is dispreferred in any way, nor does it emphasize that you 
can't
use initialization syntax to assign to an already initialized 
variable
(this is probably obvious to C types). But there are 'Best 
Practices'
notes elsewhere in the page. This section could have one of 
those, to

say to just use the constructors.



Re: Struct initialization has no effect or error?

2019-10-02 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Oct 02, 2019 at 05:37:57PM +, Brett via Digitalmars-d-learn wrote:
> struct X { int a; }
> 
> X[1] x;
> 
> x[0] = {3};
> 
> or
> 
> x[0] = {a:3};
> 
> fails;

This works:

x[0] = X(123);


> Should the syntax not extend to the case of array assignment?

Arguably it should. But it's mainly cosmetic, since the X(123) syntax
works just fine. (It *is* an incongruity in D's syntax, though. It's not
a big deal once you learn it, but it's a bit counterintuitive the first
time you need to use it.)


> This avoids a double copy.
[...]

Which any modern optimizer would optimize away.


T

-- 
It is of the new things that men tire --- of fashions and proposals and 
improvements and change. It is the old things that startle and intoxicate. It 
is the old things that are young. -- G.K. Chesterton


Struct initialization has no effect or error?

2019-10-02 Thread Brett via Digitalmars-d-learn

struct X { int a; }

X[1] x;

x[0] = {3};

or

x[0] = {a:3};

fails;

Should the syntax not extend to the case of array assignment? 
This avoids a double copy.


X y = {3};

works fine.

So one has to do

x[0] = y;