October 25, 2022
On 10/25/22 10:54, Salih Dincer wrote:

> So I don't understand why it causes problems with
> dynamic arrays!  So why is there nothing wrong with the static array in
> the example below?

The same rules as other uses of dynamic arrays...

>      //A[] a = [A.init];/*

In that case, there is a single instance of [A.init]. All A.a members point to it through their .ptr .length members.

>      A[1] a = [A.init];//*/

In that case, there is still a single instance of [A.init], which gets copied to each A.a member because static arrays don't have .ptr to point to any member. Static arrays are "just elements side by side."

In other words, there is no option but to copy to static arrays; they can't point to elements and they don't have any problem in this case.

Ali

October 25, 2022
On 10/25/22 11:01, Ali Çehreli wrote:

> static arrays don't have .ptr to point
> to any member.

Why do I say incorrect things like that? :) Of course static arrays have .ptr as well but that always point to their own body of N elements. They own their elements... I move away from the keyboard now... :)

> Static arrays are "just elements side by side."

I still like that description though.

Ali

October 25, 2022

On 10/25/22 2:03 PM, Ali Çehreli wrote:

>

On 10/25/22 11:01, Ali Çehreli wrote:

>

static arrays don't have .ptr to point
to any member.

Why do I say incorrect things like that? :) Of course static arrays have .ptr as well but that always point to their own body of N elements. They own their elements... I move away from the keyboard now... :)

You were right actually. The arr.ptr is a shortcut for the address of the first element.

A dynamic array is equivalent to a struct with a ptr and length fields. A static array does not have fields, it's just the data itself. The properties are not real fields, but lowerings so they can be used like dynamic arrays.

-Steve

October 25, 2022
On 10/25/22 11:23, Steven Schveighoffer wrote:

>> Why do I say incorrect things like that? :)

> You were right actually.

As always! Now I'm confused. :o)

Ali

October 25, 2022

On Tuesday, 25 October 2022 at 17:54:16 UTC, Salih Dincer wrote:

>

On Tuesday, 25 October 2022 at 17:18:35 UTC, Paul Backus wrote:

>

It's not a bug. They're pointing to the exact same instance of A in memory:

I don't understand? So I don't understand why it causes problems with dynamic arrays! So why is there nothing wrong with the static array in the example below?

Static arrays are value types. When you copy a static array, the copy's data is stored in a separate block of memory from the original:

int[1] a = [1];
int[1] b = a;

assert(&a[0] !is &b[0]); // different memory

Dynamic arrays are reference types. When you copy a dynamic array, both copies point to the same block of memory:

int[] a = [1];
int[] b = a;

assert(&a[0] is &b[0]); // same memory

In order to create a copy of a static array with its own block of memory, separate from the original, you have to use the built-in .dup method:

int[] a = [1];
int[] b = a.dup;

assert(&a[0] !is &b[0]); // different memory
October 25, 2022
On 10/25/22 13:12, Paul Backus wrote:

> In order to create a copy of a static array

Although .dup works for static arrays as well, you meant "dynamic array" and everyones knows it. :)

> with its own block of
> memory, separate from the original, you have to use the built-in `.dup`
> method:
>
> ```d
> int[] a = [1];
> int[] b = a.dup;

Ali

October 25, 2022
On Tuesday, 25 October 2022 at 20:12:25 UTC, Paul Backus wrote:
> On Tuesday, 25 October 2022 at 17:54:16 UTC, Salih Dincer wrote:
>> On Tuesday, 25 October 2022 at 17:18:35 UTC, Paul Backus wrote:
>>> It's not a bug. They're pointing to the exact same instance of `A` in memory:
>>
>> I don't understand?  So I don't understand why it causes problems with dynamic arrays!  So why is there nothing wrong with the static array in the example below?
>
> Static arrays are value types. When you copy a static array, the copy's data is stored in a separate block of memory from the original:
>
> ```d
> int[1] a = [1];
> int[1] b = a;
>
> assert(&a[0] !is &b[0]); // different memory
> ```
>
> Dynamic arrays are reference types. When you copy a dynamic array, both copies point to the same block of memory:
>
> ```d
> int[] a = [1];
> int[] b = a;
>
> assert(&a[0] is &b[0]); // same memory
> ```
>
> In order to create a copy of a static array with its own block of memory, separate from the original, you have to use the built-in `.dup` method:
>
> ```d
> int[] a = [1];
> int[] b = a.dup;
>
> assert(&a[0] !is &b[0]); // different memory
> ```

This is interesting, I understand the point of "reference vs copy", and I'm OK with this design choice of, but I wonder in the case of newcomers if this is a case the generate more problem understanding this rules, like we are having here.

Matheus.
October 25, 2022
On Tuesday, 25 October 2022 at 20:27:18 UTC, Ali Çehreli wrote:
> On 10/25/22 13:12, Paul Backus wrote:
>
> > In order to create a copy of a static array
>
> Although .dup works for static arrays as well, you meant "dynamic array" and everyones knows it. :)

Yes; thank you for the correction. :)
October 25, 2022
On 10/25/22 13:36, matheus wrote:
> On Tuesday, 25 October 2022 at 20:12:25 UTC, Paul Backus wrote:

>> Static arrays are value types.

What that means is, when we say float[3], there are just 3 floats without any overhead.

>> Dynamic arrays are reference types.

That phrase can be confusing because we often use the terms "dynamic array" and "slice" interchangably.

I find the following simpler to understand (can still be confusing):

- Dynamic arrays are expandable arrays that are owned by the D runtime (the GC). Dynamic arrays don't have names.

- The names (symbols) that we see in source code are slices that are references to elements of arrays. Such arrays can be static or dynamic.

When we add an element to a slice that has no room (.capacity <= .length) then a fresh dynamic array is created from the copies of the elements of the slice.

> if this is a case the generate more problem understanding this rules,

I think all these array complexities are inherent. Other examples from two other languages that I know:

- In C, arrays that are members of user-defined types are value types. Arrays that are parameters are reference types (pointer to the first element). Confusing.

- In C++, std::vector is a value type, which would be copied if passed by value. So there came std::array, std::string_view, std::span, etc. to address value versus reference complexities.

I don't think D could do anything better with arrays. They seem to work pretty well and are among the favorite features of many D programmers.

Ali

October 26, 2022

On Tuesday, 25 October 2022 at 20:36:28 UTC, matheus wrote:

>

On

>

int[] a = [1];
int[] b = a.dup;

assert(&a[0] !is &b[0]); // different memory

This is interesting, I understand the point of "reference vs copy", and I'm OK with this design choice of, but I wonder in the case of newcomers if this is a case the generate more problem understanding this rules, like we are having here.

Matheus.

Huh, I do NOT understand and I DO agree with you!

Excuse me, but they still write in purple prose about dynamic&static array literature here!

I've known D for more than 10 years, but the topic we're talking about still seems strange to me. The explanations given are not enough for me, I'm sorry.

Can anyone tell me what happens when I change the location of the structure? So the X structure must be in the stack when it is in main(), and the following must be in the heap, right?

import std;

//void main() {

  struct X
  {
    struct Y {
      int i = 10;
      alias i this;
    }
    Y[] y = [Y.init];

    string toString() {
      return y.format!"%s";
    }
  }

void main() {

  X[2] x;
  x.writeln;       // [[10], [10]]

  x[0].y[0] = 0;   // [[0], [0]]
  x.writeln;

  x[0].y.length++;
  x[0].y[1] = 1;

  x[1].y[0] = 2;
  x.writeln;       // [[0, 1], [2]]

} /* Output of other state:
[[10], [10]]
[[0], [0]]
[[2, 1], [2]]
*/

SDB@79