Array literals are weird.

Q. Schroll qs.il.paperinik at gmail.com
Tue May 4 20:26:21 UTC 2021


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);
}
```


More information about the Digitalmars-d mailing list