www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Array literals are weird.

reply Blatnik <blatblatnik gmail.com> writes:
I love how D redesigned the terrible C/C++ arrays. And it's 
awesome that array operations like element wise +, -, etc. are 
built into the language - it makes me want to use arrays and 
slices for everything. But there are still some rough edges in 
the design.

What do you expect to happen when you run this:

```D
import std;
void main() {
   writeln(typeid([1, 2, 3]));
}
```

Maybe I'm crazy, but I would expect `int[3]` to be printed. But 
`int[]` gets printed instead.

Why? What's the reason for this design?

This automatic downconversion loses potentially useful type 
information by default. It also means lazy code like this:

```D
auto array = [1, 2, 3]; // Type deduced as int[], not int[3]
```

performs an allocation, and thus it can't be used in  nogc or 
-betterC. (Not to mention that it's a completely unnecessary 
memory allocation).

It also means that functions that take a slice parameter:

```D
void foo(int[] bar);
```

Can't be called naturally in  nogc or -betterC.

```D
foo([1, 2, 3]) // Error: Array literal may cause GC allocation.
```

Instead you have to do this:

```D
int[3] bar = [1, 2, 3];
foo(bar); // Now it works with  nogc and -betterC
```

This obviously isn't a huge deal but it introduces a bit of 
friction into the  nogc workflow. It also makes slower, 
allocating code easier to write by default in non  nogc code.

This decision to make array literals slice types by default seems 
like a bad idea in all respects. It should be changed, array 
literals (are) should be fixed size.

But I'm still new to D, so maybe there is something that I'm 
missing. Any thoughts?
May 01 2021
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 1 May 2021 at 11:32:47 UTC, Blatnik wrote:
 It also means that functions that take a slice parameter:
 Can't be called naturally in  nogc or -betterC.
There's several other options you can consider, including making foo take a static array, in which case this syntax just works, or an array variadic: foo(int[] a...) when you can call it like this: foo(1, 2, 3) or you can use the library `.staticArray` thing to expressly indicate your intention on the original foo foo([1,2,3].staticArray);
 This obviously isn't a huge deal but it introduces a bit of 
 friction into the  nogc workflow. It also makes slower, 
 allocating code easier to write by default in non  nogc code.
It also makes you less likely to accidentally write use-after-free code that refers to an array on the stack after the function returns... There's some new features that are supposed to help catch this even with static arrays (the -dip1000 switch) but that's not terribly widespread.
 But I'm still new to D, so maybe there is something that I'm 
 missing. Any thoughts?
Well, a lot of this is just history: D didn't have static arrays like it does now for a while, but a good part of it too is to make the default thing be less likely to cause crash problems by accidentally escaping a reference to the stack.
May 01 2021
next sibling parent reply evilrat <evilrat666 gmail.com> writes:
On Saturday, 1 May 2021 at 11:50:27 UTC, Adam D. Ruppe wrote:
 or you can use the library `.staticArray` thing to expressly 
 indicate your intention on the original foo

 foo([1,2,3].staticArray);
Is there one in Phobos? Anyway this works, but maybe it can be made more type safe with constraints or just with improved symtax. ```d // compiles with -vgc and -betterC (weird, also without import stdc.core.stdio) import std.range : ElementType; template staticArray(alias T) { enum ElementType!(typeof(T))[T.length] staticArray = T; } extern(C) void main() { import core.stdc.stdio; auto arr = staticArray!([1,2,3]); pragma(msg, typeof(arr)); // int[3] foreach(i; arr) printf("%d\n", i); } ```
May 01 2021
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 1 May 2021 at 12:22:50 UTC, evilrat wrote:
 Is there one in Phobos?
http://dpldocs.info/staticArray i haven't tested with -betterC restrictions but i don't see any reason why it wouldn't work there
May 01 2021
next sibling parent Blatnik <blatblatnik gmail.com> writes:
On Saturday, 1 May 2021 at 12:27:07 UTC, Adam D. Ruppe wrote:
 i haven't tested with -betterC restrictions but i don't see any 
 reason why it wouldn't work there
Yep, `[1,2,3].staticArray` works just fine with -betterC.
May 01 2021
prev sibling parent evilrat <evilrat666 gmail.com> writes:
On Saturday, 1 May 2021 at 12:27:07 UTC, Adam D. Ruppe wrote:
 On Saturday, 1 May 2021 at 12:22:50 UTC, evilrat wrote:
 Is there one in Phobos?
http://dpldocs.info/staticArray i haven't tested with -betterC restrictions but i don't see any reason why it wouldn't work there
Wow, I see. It uses templates to deduce type and length as parameters.
May 01 2021
prev sibling parent reply russhy <russhy gmail.com> writes:
On Saturday, 1 May 2021 at 12:22:50 UTC, evilrat wrote:
 On Saturday, 1 May 2021 at 11:50:27 UTC, Adam D. Ruppe wrote:
 or you can use the library `.staticArray` thing to expressly 
 indicate your intention on the original foo

 foo([1,2,3].staticArray);
Is there one in Phobos? Anyway this works, but maybe it can be made more type safe with constraints or just with improved symtax. ```d // compiles with -vgc and -betterC (weird, also without import stdc.core.stdio) import std.range : ElementType; template staticArray(alias T) { enum ElementType!(typeof(T))[T.length] staticArray = T; } extern(C) void main() { import core.stdc.stdio; auto arr = staticArray!([1,2,3]); pragma(msg, typeof(arr)); // int[3] foreach(i; arr) printf("%d\n", i); } ```
don't you realize something is weird? someone is asking to be able to do auto a = [1, 2, 3] and you propose a template? this is asking people to look for alternative language auto a = new[1,2,3] <== this should be allocated array auto a = [1,2,3] <== this should be static array let's fix that, shall we? instead of telling people to bloat their files with templates
May 01 2021
next sibling parent reply evilrat <evilrat666 gmail.com> writes:
On Saturday, 1 May 2021 at 19:49:51 UTC, russhy wrote:
 On Saturday, 1 May 2021 at 12:22:50 UTC, evilrat wrote:
 On Saturday, 1 May 2021 at 11:50:27 UTC, Adam D. Ruppe wrote:
 or you can use the library `.staticArray` thing to expressly 
 indicate your intention on the original foo

 foo([1,2,3].staticArray);
Is there one in Phobos? Anyway this works, but maybe it can be made more type safe with constraints or just with improved symtax. ```d // compiles with -vgc and -betterC (weird, also without import stdc.core.stdio) import std.range : ElementType; template staticArray(alias T) { enum ElementType!(typeof(T))[T.length] staticArray = T; } extern(C) void main() { import core.stdc.stdio; auto arr = staticArray!([1,2,3]); pragma(msg, typeof(arr)); // int[3] foreach(i; arr) printf("%d\n", i); } ```
don't you realize something is weird? someone is asking to be able to do auto a = [1, 2, 3] and you propose a template? this is asking people to look for alternative language auto a = new[1,2,3] <== this should be allocated array auto a = [1,2,3] <== this should be static array let's fix that, shall we? instead of telling people to bloat their files with templates
You see only what you wanted to see. Let me clarify something. That code proves that unlike it was stated "array type information is gone" it actually isn't, which this code proves. It provides workaround just is case. I'm not forcing anyone to use it, and there is simpler solution (still a template one) in phobos. And finally, I haven't said anything like "D DONT NEED THIS, STFU AND USE HACKS". But after recent discussion you seem to trigger just by seeing my posts. No thanks I don't need any stalkers following me around.
May 01 2021
parent russhy <russhy gmail.com> writes:
On Sunday, 2 May 2021 at 05:57:02 UTC, evilrat wrote:
 On Saturday, 1 May 2021 at 19:49:51 UTC, russhy wrote:
 On Saturday, 1 May 2021 at 12:22:50 UTC, evilrat wrote:
 On Saturday, 1 May 2021 at 11:50:27 UTC, Adam D. Ruppe wrote:
 or you can use the library `.staticArray` thing to expressly 
 indicate your intention on the original foo

 foo([1,2,3].staticArray);
Is there one in Phobos? Anyway this works, but maybe it can be made more type safe with constraints or just with improved symtax. ```d // compiles with -vgc and -betterC (weird, also without import stdc.core.stdio) import std.range : ElementType; template staticArray(alias T) { enum ElementType!(typeof(T))[T.length] staticArray = T; } extern(C) void main() { import core.stdc.stdio; auto arr = staticArray!([1,2,3]); pragma(msg, typeof(arr)); // int[3] foreach(i; arr) printf("%d\n", i); } ```
don't you realize something is weird? someone is asking to be able to do auto a = [1, 2, 3] and you propose a template? this is asking people to look for alternative language auto a = new[1,2,3] <== this should be allocated array auto a = [1,2,3] <== this should be static array let's fix that, shall we? instead of telling people to bloat their files with templates
You see only what you wanted to see. Let me clarify something. That code proves that unlike it was stated "array type information is gone" it actually isn't, which this code proves. It provides workaround just is case. I'm not forcing anyone to use it, and there is simpler solution (still a template one) in phobos. And finally, I haven't said anything like "D DONT NEED THIS, STFU AND USE HACKS". But after recent discussion you seem to trigger just by seeing my posts. No thanks I don't need any stalkers following me around.
i'm not stalking you, i don't even read the user name when i reply to messages, i focus on their content today is you, yesterday it was another person, tomorow will probably be another person, that's the way it is, i find things that annoys me, i reply nobody else seems to be "triggered" by the need of such "workaround", i decided it would be me
May 02 2021
prev sibling next sibling parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Saturday, 1 May 2021 at 19:49:51 UTC, russhy wrote:
 On Saturday, 1 May 2021 at 12:22:50 UTC, evilrat wrote:
 On Saturday, 1 May 2021 at 11:50:27 UTC, Adam D. Ruppe wrote:
[...]
Is there one in Phobos? Anyway this works, but maybe it can be made more type safe with constraints or just with improved symtax. ```d // compiles with -vgc and -betterC (weird, also without import stdc.core.stdio) import std.range : ElementType; template staticArray(alias T) { enum ElementType!(typeof(T))[T.length] staticArray = T; } extern(C) void main() { import core.stdc.stdio; auto arr = staticArray!([1,2,3]); pragma(msg, typeof(arr)); // int[3] foreach(i; arr) printf("%d\n", i); } ```
don't you realize something is weird? someone is asking to be able to do auto a = [1, 2, 3] and you propose a template? this is asking people to look for alternative language auto a = new[1,2,3] <== this should be allocated array auto a = [1,2,3] <== this should be static array let's fix that, shall we? instead of telling people to bloat their files with templates
Is there any way to enable this in the language? ```d auto a = [1,2,3] + [4,5,6]; //[5,7,9] ``` I want to allow the operation. If I made a dmd fork, could I change this behavior "easily" or would it require a blood sacrifice
May 02 2021
parent reply Q. Schroll <qs.il.paperinik gmail.com> writes:
On Sunday, 2 May 2021 at 08:05:49 UTC, Imperatorn wrote:
 Is there any way to enable this in the language?

 ```d
 auto a = [1,2,3] + [4,5,6]; //[5,7,9]
 ```

 I want to allow the operation.

 If I made a dmd fork, could I change this behavior "easily" or 
 would it require a blood sacrifice
You could enable this easily using a wrapping struct template. Have a look at this: https://run.dlang.io/is/6CNgpy In short, the solution is very elegant, very general, and only requires you to make two keystrokes `.v` before the operation. Alternatively, you can use `v(1, 2, 3)` instead of a slice literal.
May 03 2021
parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Tuesday, 4 May 2021 at 00:34:49 UTC, Q. Schroll wrote:
 On Sunday, 2 May 2021 at 08:05:49 UTC, Imperatorn wrote:
 Is there any way to enable this in the language?

 ```d
 auto a = [1,2,3] + [4,5,6]; //[5,7,9]
 ```

 I want to allow the operation.

 If I made a dmd fork, could I change this behavior "easily" or 
 would it require a blood sacrifice
You could enable this easily using a wrapping struct template. Have a look at this: https://run.dlang.io/is/6CNgpy In short, the solution is very elegant, very general, and only requires you to make two keystrokes `.v` before the operation. Alternatively, you can use `v(1, 2, 3)` instead of a slice literal.
Interesting! Even more cool if not the .v was required tho 😁
May 03 2021
parent reply Q. Schroll <qs.il.paperinik gmail.com> writes:
On Tuesday, 4 May 2021 at 05:24:11 UTC, Imperatorn wrote:
 On Tuesday, 4 May 2021 at 00:34:49 UTC, Q. Schroll wrote:
 On Sunday, 2 May 2021 at 08:05:49 UTC, Imperatorn wrote:
 Is there any way to enable this in the language?

 ```d
 auto a = [1,2,3] + [4,5,6]; //[5,7,9]
 ```

 I want to allow the operation.

 If I made a dmd fork, could I change this behavior "easily" 
 or would it require a blood sacrifice
You could enable this easily using a wrapping struct template. Have a look at this: https://run.dlang.io/is/6CNgpy In short, the solution is very elegant, very general, and only requires you to make two keystrokes `.v` before the operation. Alternatively, you can use `v(1, 2, 3)` instead of a slice literal.
Interesting! Even more cool if not the .v was required tho 😁
The operation necessitates an allocation and people here don't like hidden allocations.
May 04 2021
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, May 04, 2021 at 06:16:15PM +0000, Q. Schroll via Digitalmars-d wrote:
 On Tuesday, 4 May 2021 at 05:24:11 UTC, Imperatorn wrote:
 On Tuesday, 4 May 2021 at 00:34:49 UTC, Q. Schroll wrote:
 On Sunday, 2 May 2021 at 08:05:49 UTC, Imperatorn wrote:
 Is there any way to enable this in the language?
 
 ```d
 auto a = [1,2,3] + [4,5,6]; //[5,7,9]
 ```
[...]
 Alternatively, you can use `v(1, 2, 3)` instead of a slice literal.
Interesting! Even more cool if not the .v was required tho 😁
The operation necessitates an allocation and people here don't like hidden allocations.
Why would an allocation be necessary? struct Vec(E, size_t n) { E[n] impl; alias impl this; E[n] opBinary(string op)(Vec v) { Vec result; mixin("result.impl[] = impl[] "~op~" v.impl[];"); return result; } } auto v(Args...)(Args args) { import std.traits : CommonType; alias E = CommonType!Args; Vec!(E, Args.length) result; result.impl = [ args ]; return result; } void main() nogc { // Look, ma! No allocations! int[3] arr = v(1,2,3) + v(4,5,6); assert(arr[0] == 5 && arr[1] == 7 && arr[2] == 9); } T -- Some ideas are so stupid that only intellectuals could believe them. -- George Orwell
May 04 2021
parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Tuesday, 4 May 2021 at 18:53:18 UTC, H. S. Teoh wrote:
 On Tue, May 04, 2021 at 06:16:15PM +0000, Q. Schroll via 
 Digitalmars-d wrote:
 On Tuesday, 4 May 2021 at 05:24:11 UTC, Imperatorn wrote:
 On Tuesday, 4 May 2021 at 00:34:49 UTC, Q. Schroll wrote:
 On Sunday, 2 May 2021 at 08:05:49 UTC, Imperatorn wrote:
 Is there any way to enable this in the language?
 
 ```d
 auto a = [1,2,3] + [4,5,6]; //[5,7,9]
 ```
[...]
 Alternatively, you can use `v(1, 2, 3)` instead of a slice 
 literal.
Interesting! Even more cool if not the .v was required tho 😁
The operation necessitates an allocation and people here don't like hidden allocations.
Why would an allocation be necessary? struct Vec(E, size_t n) { E[n] impl; alias impl this; E[n] opBinary(string op)(Vec v) { Vec result; mixin("result.impl[] = impl[] "~op~" v.impl[];"); return result; } } auto v(Args...)(Args args) { import std.traits : CommonType; alias E = CommonType!Args; Vec!(E, Args.length) result; result.impl = [ args ]; return result; } void main() nogc { // Look, ma! No allocations! int[3] arr = v(1,2,3) + v(4,5,6); assert(arr[0] == 5 && arr[1] == 7 && arr[2] == 9); } T -- Some ideas are so stupid that only intellectuals could believe them. -- George Orwell
To the high priests of D (I have only written *one* project in D so far): What would it take to allow array operations like I said before, without rewriting: ```d auto a = [1,2,3] + [3,2,1]; //[4,4,4] ``` Can this be accomplished using templates or a library solution, or do I have to modify the compiler? Thanks
May 04 2021
next sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 4 May 2021 at 19:44:24 UTC, Imperatorn wrote:
 What would it take to allow array operations like I said 
 before, without rewriting:

 ```d
 auto a = [1,2,3] + [3,2,1]; //[4,4,4]
 ```

 Can this be accomplished using templates or a library solution, 
 or do I have to modify the compiler?
C++ allows operator overloading for free-standing operator functions, D does not. Adding this to the compiler is easy enough. You just rewrite all "+" operators to some internal __add(x,y) template and then default that back to "+", then overload it for anything you want... Clunky, but it should work?
May 04 2021
parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Tuesday, 4 May 2021 at 20:16:29 UTC, Ola Fosheim GrΓΈstad wrote:
 On Tuesday, 4 May 2021 at 19:44:24 UTC, Imperatorn wrote:
 What would it take to allow array operations like I said 
 before, without rewriting:

 ```d
 auto a = [1,2,3] + [3,2,1]; //[4,4,4]
 ```

 Can this be accomplished using templates or a library 
 solution, or do I have to modify the compiler?
C++ allows operator overloading for free-standing operator functions, D does not. Adding this to the compiler is easy enough. You just rewrite all "+" operators to some internal __add(x,y) template and then default that back to "+", then overload it for anything you want... Clunky, but it should work?
Thanks everyone for all clarifications and examples! I'll experiment a bit and see what makes most sense.
May 04 2021
prev sibling next sibling parent Q. Schroll <qs.il.paperinik gmail.com> writes:
On Tuesday, 4 May 2021 at 19:44:24 UTC, Imperatorn wrote:
 On Tuesday, 4 May 2021 at 18:53:18 UTC, H. S. Teoh wrote:
 On Tue, May 04, 2021 at 06:16:15PM +0000, Q. Schroll via 
 Digitalmars-d wrote:
 On Tuesday, 4 May 2021 at 05:24:11 UTC, Imperatorn wrote:
 On Tuesday, 4 May 2021 at 00:34:49 UTC, Q. Schroll wrote:
 On Sunday, 2 May 2021 at 08:05:49 UTC, Imperatorn wrote:
 Is there any way to enable this in the language?
 
 ```d
 auto a = [1,2,3] + [4,5,6]; //[5,7,9]
 ```
[...]
 Alternatively, you can use `v(1, 2, 3)` instead of a 
 slice literal.
Interesting! Even more cool if not the .v was required tho 😁
The operation necessitates an allocation and people here don't like hidden allocations.
Why would an allocation be necessary? struct Vec(E, size_t n) { E[n] impl; alias impl this; E[n] opBinary(string op)(Vec v) { Vec result; mixin("result.impl[] = impl[] "~op~" v.impl[];"); return result; } } auto v(Args...)(Args args) { import std.traits : CommonType; alias E = CommonType!Args; Vec!(E, Args.length) result; result.impl = [ args ]; return result; } void main() nogc { // Look, ma! No allocations! int[3] arr = v(1,2,3) + v(4,5,6); assert(arr[0] == 5 && arr[1] == 7 && arr[2] == 9); }
To the high priests of D (I have only written *one* project in D so far): What would it take to allow array operations like I said before, without rewriting: ```d auto a = [1,2,3] + [3,2,1]; //[4,4,4] ``` Can this be accomplished using templates or a library solution, or do I have to modify the compiler?
Array literals are internal to the compiler. But you can just use something different like v(1,2,3). Heck, you can get even closer using a struct with static `opIndex` to resemble the look-and-feel of array literals: `v[1,2,3]`. You can adapt H. S. Teoh's or my approach. This is how it's done: ```D // for the array-literal-like syntax struct v { import std.traits : CommonType; static Vec!(CommonType!Args, Args.length) opIndex(Args...)(Args args) { return typeof(return)([args]); } } // the type of objects you create: struct Vector(...) { ... } // by H. S. Teoh void main() nogc { // Look, ma! No allocations! int[3] arr = v[1,2,3] + v[4,5,6]; assert(arr[0] == 5 && arr[1] == 7 && arr[2] == 9); } ```
May 04 2021
prev sibling parent reply Blatnik <blatblatnik gmail.com> writes:
On Tuesday, 4 May 2021 at 19:44:24 UTC, Imperatorn wrote:
 ```d
 auto a = [1,2,3] + [3,2,1]; //[4,4,4]
 ```

 Can this be accomplished using templates or a library solution, 
 or do I have to modify the compiler?
I'm by no means a high priest of D. However I'm fairly confident the answer to your question is no. ```D // Built-in: int[3] a = [1,2,3] + [3,2,1]; // You can do this. auto a = [1,2,3] + [3,2,1]; // But not this. // With H.S. Teoh's thing: auto a = v(1,2,3) + v(3,2,1); // You can do this - a is int[3]. auto a = v(1,2,3) + v(3,2,1) + v(42,42,42); // But not this - Error: Invalid array operation. ``` So if you actually want to make this universal, you would need to modify the compiler. From my own testing, the compiler actually turns these kinds of expressions into a function call. ```D int[3] a = [1,2,3] + [3,2,1]; // Gets turned into something like .. import core.internal.array.operations; int[3] a; int[3] __temp1 = [1,2,3]; int[3] __temp2 = [3,2,1]; arrayOp!(int[], int[], int[], "+", "=")(a[], __temp1[], __temp2[], "+", "="); ``` This also might explain why you can't use `auto a = ...` (it's not a great excuse).
May 04 2021
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, May 04, 2021 at 09:49:16PM +0000, Blatnik via Digitalmars-d wrote:
[...]
 ```
 // With H.S. Teoh's thing:
 auto a = v(1,2,3) + v(3,2,1); // You can do this - a is int[3].
 auto a = v(1,2,3) + v(3,2,1) + v(42,42,42); // But not this - Error: Invalid
 array operation.
 ```
[...] The only reason it's invalid is because I made opBinary return E[n] rather than Vec!(E,n). If it returned Vec instead, then arbitrary expressions can be made possible (e.g., with generic overloads for opBinary and opUnary). With alias this, the Vec struct will become a thin wrapper over static arrays; `auto` will give you Vec!(E,n) rather than E[n], but any use of it that needs E[n] will automatically decay to E[n]. It's not 100% the same as built-in static array expressions, but it's pretty darned close. T -- He who does not appreciate the beauty of language is not worthy to bemoan its flaws.
May 04 2021
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 04.05.21 20:16, Q. Schroll wrote:
 
 The operation necessitates an allocation and people here don't like 
 hidden allocations.
(Just some of them. Some of them obnoxiously loud. They shouldn't dictate language evolution.)
May 05 2021
prev sibling next sibling parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Saturday, 1 May 2021 at 19:49:51 UTC, russhy wrote:
 On Saturday, 1 May 2021 at 12:22:50 UTC, evilrat wrote:
 On Saturday, 1 May 2021 at 11:50:27 UTC, Adam D. Ruppe wrote:
[...]
Is there one in Phobos? Anyway this works, but maybe it can be made more type safe with constraints or just with improved symtax. ```d // compiles with -vgc and -betterC (weird, also without import stdc.core.stdio) import std.range : ElementType; template staticArray(alias T) { enum ElementType!(typeof(T))[T.length] staticArray = T; } extern(C) void main() { import core.stdc.stdio; auto arr = staticArray!([1,2,3]); pragma(msg, typeof(arr)); // int[3] foreach(i; arr) printf("%d\n", i); } ```
don't you realize something is weird? someone is asking to be able to do auto a = [1, 2, 3] and you propose a template? this is asking people to look for alternative language auto a = new[1,2,3] <== this should be allocated array auto a = [1,2,3] <== this should be static array let's fix that, shall we? instead of telling people to bloat their files with templates
Is there any way to enable this in the language? ```d auto a = [1,2,3] + [4,5,6]; //[5,7,9] ``` I want to allow the operation. If I made a dmd fork, could I change this behavior "easily" or would it require a blood sacrifice
May 02 2021
parent reply norm <norm.rowtree gmail.com> writes:
On Sunday, 2 May 2021 at 08:07:58 UTC, Imperatorn wrote:
 On Saturday, 1 May 2021 at 19:49:51 UTC, russhy wrote:
 On Saturday, 1 May 2021 at 12:22:50 UTC, evilrat wrote:
 On Saturday, 1 May 2021 at 11:50:27 UTC, Adam D. Ruppe wrote:
[...]
Is there one in Phobos? Anyway this works, but maybe it can be made more type safe with constraints or just with improved symtax. ```d // compiles with -vgc and -betterC (weird, also without import stdc.core.stdio) import std.range : ElementType; template staticArray(alias T) { enum ElementType!(typeof(T))[T.length] staticArray = T; } extern(C) void main() { import core.stdc.stdio; auto arr = staticArray!([1,2,3]); pragma(msg, typeof(arr)); // int[3] foreach(i; arr) printf("%d\n", i); } ```
don't you realize something is weird? someone is asking to be able to do auto a = [1, 2, 3] and you propose a template? this is asking people to look for alternative language auto a = new[1,2,3] <== this should be allocated array auto a = [1,2,3] <== this should be static array let's fix that, shall we? instead of telling people to bloat their files with templates
Is there any way to enable this in the language? ```d auto a = [1,2,3] + [4,5,6]; //[5,7,9] ``` I want to allow the operation. If I made a dmd fork, could I change this behavior "easily" or would it require a blood sacrifice
I think there was once a PR that made this nice and easy: https://github.com/dlang/dmd/pull/3615 ```d auto a[$] = [1,2,3]; ``` I was disappointed it never got accepted but I am sure there were good reasons. At the time I think it was "this should be a library solution" and that was probably where `staticArray` came from
May 03 2021
next sibling parent norm <norm.rowtree gmail.com> writes:
On Tuesday, 4 May 2021 at 01:59:48 UTC, norm wrote:
 ```d
 auto a[$] = [1,2,3];
 ```
gah! too much C not enough D lately; `auto[$] a = [1,2,3];`
May 03 2021
prev sibling parent reply Blatnik <blatblatnik gmail.com> writes:
On Tuesday, 4 May 2021 at 01:59:48 UTC, norm wrote:
 https://github.com/dlang/dmd/pull/3615

 ```d
 auto a[$] = [1,2,3];
 ```

 I was disappointed it never got accepted but I am sure there 
 were good reasons. At the time I think it was "this should be a 
 library solution" and that was probably where `staticArray` 
 came from
Oh that is pretty disappointing... I actually intuitively tried to do this while I was learning D. So IMO it fits the language perfectly. It looks like it wasn't merged because Andrei and Walter thought it complicates the language needlessly (https://github.com/dlang/dmd/pull/3615#issuecomment-72397283). There's still this DIP: https://github.com/dlang/DIPs/blob/master/DIPs/DIP1039.md & https://forum.dlang.org/thread/ucqyqkvaznbxkasvdjpx forum.dlang.org?page=3.
May 04 2021
next sibling parent Mike Parker <aldacron gmail.com> writes:
On Tuesday, 4 May 2021 at 10:09:59 UTC, Blatnik wrote:

 There's still this DIP: 
 https://github.com/dlang/DIPs/blob/master/DIPs/DIP1039.md & 
 https://forum.dlang.org/thread/ucqyqkvaznbxkasvdjpx forum.dlang.org?page=3.
The DIP author asked me to put this on hold until he can complete an implementation. His schedule prohibits that happening for a while yet. My current expectation is that we'll be ready to move forward with it by September.
May 04 2021
prev sibling parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Tuesday, 4 May 2021 at 10:09:59 UTC, Blatnik wrote:
 On Tuesday, 4 May 2021 at 01:59:48 UTC, norm wrote:
 [...]
Oh that is pretty disappointing... I actually intuitively tried to do this while I was learning D. So IMO it fits the language perfectly. It looks like it wasn't merged because Andrei and Walter thought it complicates the language needlessly (https://github.com/dlang/dmd/pull/3615#issuecomment-72397283). There's still this DIP: https://github.com/dlang/DIPs/blob/master/DIPs/DIP1039.md & https://forum.dlang.org/thread/ucqyqkvaznbxkasvdjpx forum.dlang.org?page=3.
Would be nice if that DIP got some love. But, that would *still* not enable stuff like ```d auto a = [1,2,3] + [3,2,1]; //[4,4,4] ``` right?
May 04 2021
prev sibling parent Q. Schroll <qs.il.paperinik gmail.com> writes:
On Saturday, 1 May 2021 at 19:49:51 UTC, russhy wrote:
 On Saturday, 1 May 2021 at 12:22:50 UTC, evilrat wrote:
 On Saturday, 1 May 2021 at 11:50:27 UTC, Adam D. Ruppe wrote:
 or you can use the library `.staticArray` thing to expressly 
 indicate your intention on the original foo

 foo([1,2,3].staticArray);
Is there one in Phobos? Anyway this works, but maybe it can be made more type safe with constraints or just with improved symtax. ```d // compiles with -vgc and -betterC (weird, also without import stdc.core.stdio) import std.range : ElementType; template staticArray(alias T) { enum ElementType!(typeof(T))[T.length] staticArray = T; } extern(C) void main() { import core.stdc.stdio; auto arr = staticArray!([1,2,3]); pragma(msg, typeof(arr)); // int[3] foreach(i; arr) printf("%d\n", i); } ```
don't you realize something is weird? someone is asking to be able to do auto a = [1, 2, 3] and you propose a template? this is asking people to look for alternative language ```D auto a = new[1,2,3] <== this should be allocated array auto a = [1,2,3] <== this should be static array ``` let's fix that, shall we? instead of telling people to bloat their files with templates
I agree that the non-obvious allocation is kind of a problem and `new [ 1, 2, 3 ]` would be more explicit, but where I see the actual issue isn't where you think it is. In ` nogc` code, the compiler tells you that an allocation takes place and you look for solutions to avoid it (there are multiple approaches, but no general one).
May 03 2021
prev sibling parent reply Blatnik <blatblatnik gmail.com> writes:
On Saturday, 1 May 2021 at 11:50:27 UTC, Adam D. Ruppe wrote:
 There's several other options you can consider, including 
 making foo take a static array
Yea this does work, but some functions really do need to take many different array sizes. And in that case I guess you could make the array size a template parameter. But this would lead to template bloat for no reason in most cases.
 or an array variadic:

 foo(int[] a...)
This doesn't really work. It has the obvious problem of not being able to pass 2 different arrays like this.
 or you can use the library `.staticArray` thing to expressly 
 indicate your intention on the original foo
But this does work! I didn't know `std.array` had this. Thanks.
 but a good part of it too is to make the default thing be less 
 likely to cause crash problems by accidentally escaping a 
 reference to the stack.
You mean stuff like: ```D int[] bug() { return [1, 2, 3]; } int[] a = bug(); a[0] = 42; // Works fine now, but use-after-free-ish if array literals are static arrays. ``` Yea I can see how that would be a problem if array literals were static arrays by default. But even right now the compiler is able to catch this mistake pretty easily: ```D int[] bug() { int[3] a = [1, 2, 3]; return a; // Error: Returning `a` escapes a reference to a local variable. } ``` So the `.staticArray` thing is great but wouldn't it be even better if we didn't have to import a library and type that in. I still see no reason `[1, 2, 3]` should ever _not_ be considered a `int[3]`, unless you explicitly ask for it: ```D auto x = [1, 2, 3]; // This really shouldn't allocate anything. auto y = [1, 2, 3].dup; // I explicitly asked for it, please allocate! ```
May 01 2021
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 1 May 2021 at 12:27:30 UTC, Blatnik wrote:
 Yea I can see how that would be a problem if array literals 
 were static arrays by default. But even right now the compiler 
 is able to catch this mistake pretty easily:
Yeah, it works now but that's again relatively new. It wasn't there when this stuff was designed. It'd probably break a lot of code if this were to change now.
 auto y = [1, 2, 3].dup; // I explicitly asked for it, please 
 allocate!
yeah that'd probably be ok.
May 01 2021
next sibling parent Blatnik <blatblatnik gmail.com> writes:
On Saturday, 1 May 2021 at 12:35:00 UTC, Adam D. Ruppe wrote:
 It'd probably break a lot of code if this were to change now.
But the compiler could probably catch the mistake everywhere it happens with DIP 1000. And then it's just a matter of replacing [...] with [...].dup where you actually need it. Although to be fair, even though the compiler (dmd) catches really simple cases, it doesn't catch more complex ones: ```D int[] bug1() { int[3] a = [1, 2, 3]; return a; // Error: Returning `a` escapes reference to a local variable. } int[] bug2() { int[3] a = [1, 2, 3]; int[] b = a; return b; // No error! } ``` But with DIP 1000 this is caught as well: ```D int[] bug2() { int[3] a = [1, 2, 3]; int[] b = a; return b; // Error: Scope variable `b` may not be returned. } ```
May 01 2021
prev sibling parent Blatnik <blatblatnik gmail.com> writes:
On Saturday, 1 May 2021 at 12:35:00 UTC, Adam D. Ruppe wrote:
 Yeah, it works now but that's again relatively new. It wasn't 
 there when this stuff was designed.

 It'd probably break a lot of code if this were to change now.
I guess the conclusion is, D's array literals are weird for historic reasons. There are definitely more important things that need fixing. This would be a breaking change with relatively not that much benefit. The `.staticArray` thing is good enough for me. Still there is some performance / language simplification to be gained here.
May 01 2021
prev sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Saturday, 1 May 2021 at 12:27:30 UTC, Blatnik wrote:

 I still see no reason `[1, 2, 3]` should ever _not_ be 
 considered a `int[3]`, unless you explicitly ask for it:
I strongly disagree. That array literals produce dynamic arrays made sense to me from the day I found D, and it still makes sense 18 years later. If they were to produce static arrays, then what happens here? ```d int[] a = [1, 2, 3]; return a; ``` In order for this to work as expected, then this particular literal would have to be allocated on the GC heap, which is then inconsistent with the normal behavior. Right now, the compiler is free to elide allocations for literals when it can, but that's not an optimization, not an inconsistency. And what about this? ```d doSomeMatrixStuff3x3( [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] ); ``` Now I'm passing 9 floats by value unless I remember to do whatever needs to be done to indicate that this should be dynamic (`.dup`). Static array literals just seem backwards to me. With dynamic array literals, I don't have to think about it. Moreover, I really would hate to see either ` nogc` or BetterC have any impact on language changes. Those are the *exceptional* cases. D is a GC'ed language. ` nogc` and BetterC are more restricted subsets.
May 01 2021
next sibling parent Mike Parker <aldacron gmail.com> writes:
On Saturday, 1 May 2021 at 15:14:49 UTC, Mike Parker wrote:


 but that's not an optimization, not an inconsistency.
but that's an optimization...
May 01 2021
prev sibling parent reply Blatnik <blatblatnik gmail.com> writes:
On Saturday, 1 May 2021 at 15:14:49 UTC, Mike Parker wrote:
 I strongly disagree. That array literals produce dynamic arrays 
 made sense to me from the day I found D, and it still makes 
 sense 18 years later.
I really can't argue here. If you just want to not think about it, then having it always be dynamically allocated is the way to go. But isn't D a systems level programming language where you _do_ want to care about things like what is dynamically allocated and what isn't? :D If so then the language should encourage you to allocate statically wherever possible. At least in my view.
 If they were to produce static arrays, then what happens here?

 ```d
 int[] a = [1, 2, 3];
 return a;
 ```
Well the way I saw my idea working is that the compiler would give you a hard error here, and tell you to fix it by allocating it with `return a.dup` if that's what you wanted, or make the function return a static array if _that's_ what you wanted.
 And what about this?

 ```d
 doSomeMatrixStuff3x3(
     [1.0, 0.0, 0.0,
      0.0, 1.0, 0.0,
      0.0, 0.0, 1.0]
 );
 ```

 Now I'm passing 9 floats by value unless I remember to do 
 whatever needs to be done to indicate that this should be 
 dynamic (`.dup`).
Unless `doSomeMatrixStuff3x3` does something stupid like copying the slice to a global variable, then you don't need to dynamically allocate the temporary before you pass it in anyway. So if the array literals were static, the compiler would turn the call above into something like: ```D float[9] __temporary = [1, 0, 0, 0, 1, 0, 0, 0, 1]; doSomeMatrixStuff3x3(__temporary[]); ``` This is what you end up doing in -betterC and nogc anyway, and without them this will still save you an unnecessary allocation. Note that if `doSomeMatrixStuff3x3` _does_ save the slice to a global variable or something, that's already incorrect today, as you could in theory pass in a stack allocated static array as a slice (exactly like it is being called above).
 Moreover, I really would hate to see either ` nogc` or BetterC 
 have any impact on language changes. Those are the 
 *exceptional* cases. D is a GC'ed language. ` nogc` and BetterC 
 are more restricted subsets.
I see your point. This change would make code without nogc slightly more annoying to write because of the error messages when you try to do something like the above, which is fine to do right now. But I guess in my view this could be a (slightly) helpful change for (every subset of) the language.
May 01 2021
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 1 May 2021 at 18:57:48 UTC, Blatnik wrote:
 But isn't D a systems level programming language where you _do_ 
 want to care about things like what is dynamically allocated 
 and what isn't? :D
D is an all-purpose programming language. Some purposes are easier or harder than others. The easier thing tries to be more correct than not, even if that means extra performance may take extra work.
May 01 2021
prev sibling parent MoonlightSentinel <moonlightsentinel disroot.org> writes:
On Saturday, 1 May 2021 at 18:57:48 UTC, Blatnik wrote:
 ```D
 float[9] __temporary = [1, 0, 0, 0, 1, 0, 0, 0, 1];
 doSomeMatrixStuff3x3(__temporary[]);
 ```

 This is what you end up doing in -betterC and  nogc anyway, and 
 without them this will still save you an unnecessary allocation.
The stack propagation is unrelated to -betterC, it only depends on the parameter being marked as scope.
May 01 2021
prev sibling next sibling parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Saturday, 1 May 2021 at 11:32:47 UTC, Blatnik wrote:
 I love how D redesigned the terrible C/C++ arrays. And it's 
 awesome that array operations like element wise +, -, etc. are 
 built into the language - it makes me want to use arrays and 
 slices for everything. But there are still some rough edges in 
 the design.

 [...]
Yeah, imo this is a rather strange limitation of the language. I would like to be able to do ```d int[] a = [1,2,3] * [4,5,6]; ``` for example, but this yields "array operation without destination memory not allowed" :(
May 01 2021
prev sibling next sibling parent Dennis <dkorpel gmail.com> writes:
On Saturday, 1 May 2021 at 11:32:47 UTC, Blatnik wrote:
 Why? What's the reason for this design?
As mentioned before, static arrays have limited life time, so the compiler allocates arrays using the GC unless it is certain no references to it could escape.
 It also means that functions that take a slice parameter:

 ```D
 void foo(int[] bar);
 ```

 Can't be called naturally in  nogc or -betterC.

 ```D
 foo([1, 2, 3]) // Error: Array literal may cause GC allocation.
 ```
In this case, `foo` could e.g. store `bar` in a global variable causing memory corruption. It does work in `-betterC` if you add `scope` to the parameter, which means that `bar` is not allowed to leave the scope of the function: ```D void foo(scope int[] bar) nogc {} extern(C) void main() nogc { foo([1, 2, 3]); } ```
 This decision to make array literals slice types by default 
 seems like a bad idea in all respects. It should be changed, 
 array literals (are) should be fixed size.
It would have to be done in a backwards compatible way, array literals are too common to introduce a breaking change.
 Any thoughts?
D's literals are full of somewhat ad-hoc rules that allow / disallow certain assignments that don't follow from their types. - a string literal converts to a C-style string `const(char)*`, but a `string` does not convert to a `const(char)*` - an integer literal converts to a `short` if it fits, though `int` does not convert to `short` (this is called "value range propagation") - an integer array literal `[1, 2, 3]` converts to a `float[]`, though an `int[]` does not convert to `float[]` - conversely, an invalid code point `0x110000` can *not* be assigned to a `dchar`, even though `int` converts to `dchar` The fact that static arrays are initialized using dynamic array literals is another instance of this. I'd personally be in favor of dedicated static array literals, but I'm afraid most people are satisfied with `import std.array: staticArray;`.
May 01 2021
prev sibling parent reply user1234 <user1234 12.de> writes:
On Saturday, 1 May 2021 at 11:32:47 UTC, Blatnik wrote:
 I love how D redesigned the terrible C/C++ arrays. And it's 
 awesome that array operations like element wise +, -, etc. are 
 built into the language - it makes me want to use arrays and 
 slices for everything. But there are still some rough edges in 
 the design.

 What do you expect to happen when you run this:

 ```D
 import std;
 void main() {
   writeln(typeid([1, 2, 3]));
 }
 ```

 Maybe I'm crazy, but I would expect `int[3]` to be printed. But 
 `int[]` gets printed instead.

 Why? What's the reason for this design?

 This automatic downconversion loses potentially useful type 
 information by default. It also means lazy code like this:

 ```D
 auto array = [1, 2, 3]; // Type deduced as int[], not int[3]
 ```

 performs an allocation, and thus it can't be used in  nogc or 
 -betterC. (Not to mention that it's a completely unnecessary 
 memory allocation).

 It also means that functions that take a slice parameter:

 ```D
 void foo(int[] bar);
 ```

 Can't be called naturally in  nogc or -betterC.

 ```D
 foo([1, 2, 3]) // Error: Array literal may cause GC allocation.
 ```
related : https://issues.dlang.org/show_bug.cgi?id=21756
 Instead you have to do this:

 ...
May 05 2021
parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Wednesday, 5 May 2021 at 08:58:41 UTC, user1234 wrote:
 On Saturday, 1 May 2021 at 11:32:47 UTC, Blatnik wrote:
 I love how D redesigned the terrible C/C++ arrays. And it's 
 awesome that array operations like element wise +, -, etc. are 
 built into the language - it makes me want to use arrays and 
 slices for everything. But there are still some rough edges in 
 the design.
I have experimented some and found a few workarounds which might be acceptable. But, I'm having some weird bug. On dmd and dmd-beta it works, but on dmd-nightly I get: cannot interpret array literal expression [1, 2, 3] + [3, 2, 1] at compile time I think this might be a regression? Like, this works as I want: https://run.dlang.io/is/rHRiP9 If I use dmd or dmd-beta. But if I change it to dmd-nightly it doesn't :( 😒😒😒
May 05 2021
next sibling parent reply user1234 <user1234 12.de> writes:
On Wednesday, 5 May 2021 at 09:18:58 UTC, Imperatorn wrote:
 If I use dmd or dmd-beta. But if I change it to dmd-nightly it 
 doesn't :(
That's because nightlies are broken. The compiler used is actually somewhere between 2.091 and 2.092 : https://run.dlang.io/is/foS0FX Also visible there : http://downloads.dlang.org/nightlies/. There are not even promoted on the main download page, as it used to be.
May 05 2021
parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Wednesday, 5 May 2021 at 09:26:39 UTC, user1234 wrote:
 On Wednesday, 5 May 2021 at 09:18:58 UTC, Imperatorn wrote:
 If I use dmd or dmd-beta. But if I change it to dmd-nightly it 
 doesn't :(
That's because nightlies are broken. The compiler used is actually somewhere between 2.091 and 2.092 : https://run.dlang.io/is/foS0FX Also visible there : http://downloads.dlang.org/nightlies/. There are not even promoted on the main download page, as it used to be.
Oh, what's happening? I thought nightly was nightly :D
May 05 2021
parent reply user1234 <user1234 12.de> writes:
On Wednesday, 5 May 2021 at 09:42:01 UTC, Imperatorn wrote:
 On Wednesday, 5 May 2021 at 09:26:39 UTC, user1234 wrote:
 On Wednesday, 5 May 2021 at 09:18:58 UTC, Imperatorn wrote:
 If I use dmd or dmd-beta. But if I change it to dmd-nightly 
 it doesn't :(
That's because nightlies are broken. The compiler used is actually somewhere between 2.091 and 2.092 : https://run.dlang.io/is/foS0FX Also visible there : http://downloads.dlang.org/nightlies/. There are not even promoted on the main download page, as it used to be.
Oh, what's happening? I thought nightly was nightly :D
They could be restored soon. There's a related PR https://github.com/dlang/dmd/pull/12491, it's not sure if it aims at restoring nighlies. It 90% sure tho.
May 05 2021
parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Wednesday, 5 May 2021 at 09:47:37 UTC, user1234 wrote:
 On Wednesday, 5 May 2021 at 09:42:01 UTC, Imperatorn wrote:
 On Wednesday, 5 May 2021 at 09:26:39 UTC, user1234 wrote:
 On Wednesday, 5 May 2021 at 09:18:58 UTC, Imperatorn wrote:
 If I use dmd or dmd-beta. But if I change it to dmd-nightly 
 it doesn't :(
That's because nightlies are broken. The compiler used is actually somewhere between 2.091 and 2.092 : https://run.dlang.io/is/foS0FX Also visible there : http://downloads.dlang.org/nightlies/. There are not even promoted on the main download page, as it used to be.
Oh, what's happening? I thought nightly was nightly :D
They could be restored soon. There's a related PR https://github.com/dlang/dmd/pull/12491, it's not sure if it aims at restoring nighlies. It 90% sure tho.
Thanks for the info!
May 05 2021
prev sibling parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Wednesday, 5 May 2021 at 09:18:58 UTC, Imperatorn wrote:
 On Wednesday, 5 May 2021 at 08:58:41 UTC, user1234 wrote:
 On Saturday, 1 May 2021 at 11:32:47 UTC, Blatnik wrote:
 I love how D redesigned the terrible C/C++ arrays. And it's 
 awesome that array operations like element wise +, -, etc. 
 are built into the language - it makes me want to use arrays 
 and slices for everything. But there are still some rough 
 edges in the design.
I have experimented some and found a few workarounds which might be acceptable. But, I'm having some weird bug. On dmd and dmd-beta it works, but on dmd-nightly I get: cannot interpret array literal expression [1, 2, 3] + [3, 2, 1] at compile time I think this might be a regression? Like, this works as I want: https://run.dlang.io/is/rHRiP9 If I use dmd or dmd-beta. But if I change it to dmd-nightly it doesn't :( 😒😒😒
Output locally from https://run.dlang.io/is/ZUFFfZ: PS C:\Temp\D\temp> dmd .\arrays.d 2096L PS C:\Temp\D\temp> .\arrays.exe [4, 4, 4] [4, 4, 4] [4, 4, 4] [4, 4, 4] [4, 4, 4] PS C:\Temp\D\temp> ldc2 .\arrays.d 2096L PS C:\Temp\D\temp> .\arrays.exe [4, 4, 4] [4, 4, 4] [4, 4, 4] [4, 4, 4] [4, 4, 4]
May 05 2021
parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Wednesday, 5 May 2021 at 09:28:45 UTC, Imperatorn wrote:
 On Wednesday, 5 May 2021 at 09:18:58 UTC, Imperatorn wrote:
 On Wednesday, 5 May 2021 at 08:58:41 UTC, user1234 wrote:
 On Saturday, 1 May 2021 at 11:32:47 UTC, Blatnik wrote:
 I love how D redesigned the terrible C/C++ arrays. And it's 
 awesome that array operations like element wise +, -, etc. 
 are built into the language - it makes me want to use arrays 
 and slices for everything. But there are still some rough 
 edges in the design.
I have experimented some and found a few workarounds which might be acceptable. But, I'm having some weird bug. On dmd and dmd-beta it works,
This all works with 2.096.0 and beta but not nightly ```d import std.stdio; immutable ic = [1, 2, 3] + [3, 2, 1]; const ca2 = [1, 2, 3] + [3, 2, 1]; enum ea2 = [1, 2, 3] + [3, 2, 1]; int[] i3 = [1, 2, 3] + [3, 2, 1]; auto a6 = [1, 2, 3] + [3, 2, 1]; void main() { pragma(msg, __VERSION__); auto a = [1, 2, 3]; auto b = [3, 2, 1]; enum ia2 = [1, 2, 3] + [3, 2, 1] + [1, 1, 1]; int[3] d; d = a[] + b[]; writeln(ia2); writeln(ic); writeln(ca2); writeln(ea2); writeln(a6); writeln(d); } ```
May 05 2021
parent user1234 <user1234 12.de> writes:
On Wednesday, 5 May 2021 at 09:33:47 UTC, Imperatorn wrote:
 On Wednesday, 5 May 2021 at 09:28:45 UTC, Imperatorn wrote:
 On Wednesday, 5 May 2021 at 09:18:58 UTC, Imperatorn wrote:
 On Wednesday, 5 May 2021 at 08:58:41 UTC, user1234 wrote:
 On Saturday, 1 May 2021 at 11:32:47 UTC, Blatnik wrote:
 I love how D redesigned the terrible C/C++ arrays. And it's 
 awesome that array operations like element wise +, -, etc. 
 are built into the language - it makes me want to use 
 arrays and slices for everything. But there are still some 
 rough edges in the design.
I have experimented some and found a few workarounds which might be acceptable. But, I'm having some weird bug. On dmd and dmd-beta it works,
This all works with 2.096.0 and beta but not nightly
lol, nightlies are not updated since 13 monthes... https://forum.dlang.org/post/avkkqfjtfrwtmnvpxbot forum.dlang.org
May 05 2021