October 15, 2022
On 15.10.22 14:10, Tejas wrote:
> On Saturday, 15 October 2022 at 11:29:00 UTC, rassoc wrote:
>> On 10/14/22 21:46, jfondren via Digitalmars-d wrote:
>>> and it crashes with an oversized array as the lengths don't match
>>
>> Try compiling with -release for extra fun, or not.
> 
> It printed the arrays
>   ```
> [0, 0, 0]
> [0, 0, 0]
> ```
> ... lol did it cache the results of the previous call? Somebody please explain this, is this what Timon meant by undefined behaviour getting introduced in programs whose `assert`s get removed from the code?

The code has UB with -release, but it is a different case. There are no asserts in it. Currently, failing asserts introduce UB in -release even if they are not guarding against anything that would ordinarily cause UB. I think that's not justifiable.
October 15, 2022

On Friday, 14 October 2022 at 19:46:06 UTC, jfondren wrote:

>

On Friday, 14 October 2022 at 18:57:44 UTC, mw wrote:

>

Why this code can be compiled and causing runtime error? it should be caught at compile time!

import std.stdio;

void main() {
    int[3] arr;
    writeln(arr.ptr);
    arr = new int[3];
    writeln(arr.ptr);
    writeln(typeid(arr));
}

output (e.g.):

7FFD5EBF1530
7FFD5EBF1530
int[3]

It's not a reassignment of arr, but a copying of the contents of the dynamic array, and it crashes with an oversized array as the lengths don't match,

This is so confusing, we should have two different syntax for this two different semantics:

arr = other;  // assign array variable to `other`

arr[] = other[];  // assign array contents

I think D has the second form already, then the first form should not be a shorthand for the second form.

These two have two different semantics.

If you view the above two statements as in Python (numpy), it's very clear their meaning are different:

arr = other;  // assign array variable to `other`

arr[:] = other[:];  // assign array contents
October 15, 2022

On Saturday, 15 October 2022 at 16:20:51 UTC, mw wrote:

>

On Friday, 14 October 2022 at 19:46:06 UTC, jfondren wrote:

>

[...]

This is so confusing, we should have two different syntax for this two different semantics:

arr = other;  // assign array variable to `other`

arr[] = other[];  // assign array contents

I think D has the second form already, then the first form should not be a shorthand for the second form.

These two have two different semantics.

If you view the above two statements as in Python (numpy), it's very clear their meaning are different:

arr = other;  // assign array variable to `other`

arr[:] = other[:];  // assign array contents

+1

October 15, 2022
On 10/15/22 18:20, mw via Digitalmars-d wrote:
> If you view the above two statements as in Python (numpy), it's very clear their meaning are different:
> ``` Python
> arr = other;  // assign array variable to `other`
> 
> arr[:] = other[:];  // assign array contents
> ```
These python arrays aren't static though.

Also, good old python will give you a view/slice of the whole array in the later case, not element-wise assignment. Numpy works differently and will fail if your shapes aren't the same:

 >>> a = np.array([1,2,3])
 >>> b = np.array([1,2,3,4,5])
 >>> a[:] = b[:]
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
 ValueError: could not broadcast input array from shape (5,) into shape (3,)

Not all that different from your initial static array example.
October 15, 2022
On Saturday, 15 October 2022 at 17:09:53 UTC, rassoc wrote:
> On 10/15/22 18:20, mw via Digitalmars-d wrote:
>> If you view the above two statements as in Python (numpy), it's very clear their meaning are different:
>> ``` Python
>> arr = other;  // assign array variable to `other`
>> 
>> arr[:] = other[:];  // assign array contents
>> ```
> These python arrays aren't static though.
>
> Also, good old python will give you a view/slice of the whole array in the later case, not element-wise assignment. Numpy works differently and will fail if your shapes aren't the same:
>
>  >>> a = np.array([1,2,3])
>  >>> b = np.array([1,2,3,4,5])
>  >>> a[:] = b[:]
>  Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
>  ValueError: could not broadcast input array from shape (5,) into shape (3,)
>
> Not all that different from your initial static array example.

you can always specify the start, end index:

```
a[start_a: end_a] = b[start_b: end_b]
```

It will fail if the length does not match; or even you can argue that it's also runtime error (right, Python is not static compiled language).

But the main point I want to make is: these two different semantics should have different syntax, do not overload as it only confuse the programmer.

October 15, 2022
On 10/15/22 19:18, mw via Digitalmars-d wrote:
> But the main point I want to make is: these two different semantics should have different syntax, do not overload as it only confuse the programmer.
> 

They are not the same thing and behave differently for dynamic and static arrays. Furthermore, there's a distinction between dynamic arrays and slices: ownership of data. [1]

But what you are probably looking for is the follow which is behaving the same as in python:

import std.stdio : writeln;
void main() {
    auto a = [1,2,3];
    auto b = [1,2,3,4,5];
    a = b.dup;
    writeln(a is b, " ", a == b); // false true
}

[1] https://dlang.org/articles/d-array-article.html
October 15, 2022
On Saturday, 15 October 2022 at 18:22:10 UTC, rassoc wrote:
> On 10/15/22 19:18, mw via Digitalmars-d wrote:
>> But the main point I want to make is: these two different semantics should have different syntax, do not overload as it only confuse the programmer.
>> 
>
> They are not the same thing and behave differently for dynamic and static arrays. Furthermore, there's a distinction between dynamic arrays and slices: ownership of data. [1]
>
> But what you are probably looking for is the follow which is behaving the same as in python:
>
> import std.stdio : writeln;
> void main() {
>     auto a = [1,2,3];
>     auto b = [1,2,3,4,5];
>     a = b.dup;
>     writeln(a is b, " ", a == b); // false true
> }
>
> [1] https://dlang.org/articles/d-array-article.html


Regarding the syntax problem I want to make my point clear again: different semantics (variable assignment a = b v.s content assignment a[] = b[]) should have different syntax, *regardless* they are static or dynamic array.

As more fun with your example:

     a = b.dup;  // so this is content assignment?
     writeln(a is b, " ", a == b); // false true

     a = b;      // this is var assignment?
     writeln(a is b, " ", a == b); // true true

This current syntax in D is as clear as mud.

October 15, 2022
On Saturday, 15 October 2022 at 18:44:04 UTC, mw wrote:
> Regarding the syntax problem I want to make my point clear again: different semantics (variable assignment a = b v.s content assignment a[] = b[]) should have different syntax, *regardless* they are static or dynamic array.

Of course, with these different syntax, the compiler can do more for static checking:

```
  int[3] a;            // compiler know it's a static array
  a = b;               // compiler issue error: static array cannot be re-assigned
  a = new int[5];      // compiler issue error: static array cannot be re-assigned
  a = what_ever_here;  // compiler issue error: static array cannot be re-assigned

  a[] = b[];    // content assignment ok; but if b's size can be known statically at compile time and is different from 3, issue error at compile time; otherwise run time error.

  a[start_a .. end_b] = b[start_b .. end_b];  // same as above, content assignment
```

October 15, 2022
On Saturday, 15 October 2022 at 18:44:04 UTC, mw wrote:
> Regarding the syntax problem I want to make my point clear again: different semantics (variable assignment a = b v.s content assignment a[] = b[]) should have different syntax, *regardless* they are static or dynamic array.
>
> As more fun with your example:
>
>      a = b.dup;  // so this is content assignment?
>      writeln(a is b, " ", a == b); // false true

Sorry, I just realized that `a = b.dup` is also var assignment: b.dup will create a new array and assigned to a, hence `a is b` is false.

>      a = b;      // this is var assignment?
>      writeln(a is b, " ", a == b); // true true
>
> This current syntax in D is as clear as mud.


October 15, 2022
On 10/15/22 20:56, mw via Digitalmars-d wrote:
> Of course, with these different syntax, the compiler can do more for static checking:
> 
> ```
>    int[3] a;            // compiler know it's a static array
>    a = b;               // compiler issue error: static array cannot be re-assigned
>    a = new int[5];      // compiler issue error: static array cannot be re-assigned
>    a = what_ever_here;  // compiler issue error: static array cannot be re-assigned
> 
>    a[] = b[];    // content assignment ok; but if b's size can be known statically at compile time and is different from 3, issue error at compile time; otherwise run time error.
> 
>    a[start_a .. end_b] = b[start_b .. end_b];  // same as above, content assignment
> ``` 

Static array doesn't mean they can't be mutable; they are simply stack allocated and value types.

Also, that checking will be done when it's only static arrays:

import std;
void main() {
    int[3] a;
    int[5] b;
    a = b;     // Error: mismatched array lengths, 3 and 5
    a[] = b[]; // Error: mismatched array lengths, 3 and 5
    a[10] = 0; // Error: array index 10 is out of bounds `a[0 .. 3]`
}

D, as of right now, doesn't do these compile-time checks when dynamic arrays are involved even if it could, which isn't optimal, I agree.

> This current syntax in D is as clear as mud.

Maybe these links help:

Cloning: https://forum.dlang.org/post/mailman.3.1473548067.2994.digitalmars-d-learn@puremagic.com
Array types and ops: https://dlang.org/spec/arrays.html