June 14, 2020
On 6/14/20 2:25 PM, Paul Backus wrote:
> On Sunday, 14 June 2020 at 16:26:17 UTC, Avrina wrote:
>>
>> The situation also applies to the only tuple implementation in D. If you are proposing a new type with emphasis on reducing the footprint of the tuple then I don't see a problem with that. Changing the existing tuple implementation would be problematic.
> 
> Presumably any such change would be made backwards-compatible. So Tuple.opIndex and Tuple.expand would still return elements in the order specified by the user, even if that order is different from the internal storage order.

Indeed.
June 14, 2020
On 6/14/20 3:36 PM, Timon Gehr wrote:
> On 14.06.20 20:25, Paul Backus wrote:
>> On Sunday, 14 June 2020 at 16:26:17 UTC, Avrina wrote:
>>>
>>> The situation also applies to the only tuple implementation in D. If you are proposing a new type with emphasis on reducing the footprint of the tuple then I don't see a problem with that. Changing the existing tuple implementation would be problematic.
>>
>> Presumably any such change would be made backwards-compatible. So Tuple.opIndex and Tuple.expand would still return elements in the order specified by the user, even if that order is different from the internal storage order.
> 
> Indeed, that's why I noted that the obvious way to achieve that does not work. Although some assumptions will break, for example, there might be code that assumes that tupleof does the same thing as expand.
> 
> I was thinking about e.g., manual cache optimization, but reducing size in the common case where such considerations are not made may well be more important. If it can be done at all; I am not currently aware of a workaround.

It's really easy if members in the layout are given internal names that include information about the original index.
June 15, 2020
On Saturday, 13 June 2020 at 19:11:33 UTC, Andrei Alexandrescu wrote:
> https://github.com/ZigaSajovic/optimizing-the-memory-layout-of-std-tuple
>
> Would be interesting to adapt it for std.tuple.

I can't see any way of making indexing work *except* by adding a Get template inside the tuple.

Currently Tuple supports indexing via `tuple[2]` => gets you the third value with its own type.

We cannot use opIndex for this because the tuple can consist of multiple types, and index is a runtime parameter when opIndex is called.

Now if we had something like `staticOpIndex` in the language maybe it could work. I could envision it being something like this:

```
struct Tuple (T...)
{
    T t;
    auto staticOpIndex (size_t index)()  // CT param
    {
        return t[index];  // or the rearranged index if fields are re-ordered
    }
}
```
June 15, 2020
On Monday, 15 June 2020 at 06:06:40 UTC, Andrej Mitrovic wrote:
> Currently Tuple supports indexing via `tuple[2]` => gets you the third value with its own type.

It does this via `alias fields this;` basically.
June 15, 2020
On Sunday, 14 June 2020 at 23:30:03 UTC, Andrei Alexandrescu wrote:
> It's really easy if members in the layout are given internal names that include information about the original index.

You can construct a list of member aliases in the original order and then 'alias this' that:

import std.meta;

struct Tuple(A...) {
    alias Reordered = AliasSeq!(A[1], A[2], A[0]);
    Reordered value;

    alias reordered = AliasSeq!(typeof(this).tupleof);
    alias original = AliasSeq!(reordered[2], reordered[0], reordered[1]);
    alias original this;
}

void main() {
    Tuple!(byte, int, short) t;

    static assert(is(typeof(t.tupleof) == AliasSeq!(int, short, byte)));

    static assert(is(typeof(t[0]) == byte));
    static assert(is(typeof(t[1]) == int));
    static assert(is(typeof(t[2]) == short));
}
June 15, 2020
On Monday, 15 June 2020 at 13:34:18 UTC, Max Samukha wrote:
> On Sunday, 14 June 2020 at 23:30:03 UTC, Andrei Alexandrescu wrote:
>> It's really easy if members in the layout are given internal names that include information about the original index.
>
> You can construct a list of member aliases in the original order and then 'alias this' that:

typeof(t[0]) works fine, but reading or assigning to such a field will not work. For example:

void main() {
    Tuple!(byte, int, short) t;
    writeln(t[0]);
}

> test.d(57,23): Error: need `this` for `__value_field_2` of type `byte`

June 15, 2020
On Monday, 15 June 2020 at 13:50:07 UTC, Andrej Mitrovic wrote:

> typeof(t[0]) works fine, but reading or assigning to such a field will not work. For example:
>
> void main() {
>     Tuple!(byte, int, short) t;
>     writeln(t[0]);
> }
>
>> test.d(57,23): Error: need `this` for `__value_field_2` of type `byte`

It should work. This works:

void main() {
    Tuple!(byte, int, short) t;

    t[0] = 0;
    t[1] = 2;
    t[2] = 3;

    auto a0 = t[0];
    auto a1 = t[1];
}
}
June 15, 2020
On Monday, 15 June 2020 at 13:57:01 UTC, Max Samukha wrote:

>> void main() {
>>     Tuple!(byte, int, short) t;
>>     writeln(t[0]);
>> }
>>
>>> test.d(57,23): Error: need `this` for `__value_field_2` of type `byte`
>
> It should work. This works:
>
> void main() {
>     Tuple!(byte, int, short) t;
>
>     t[0] = 0;
>     t[1] = 2;
>     t[2] = 3;
>
>     auto a0 = t[0];
>     auto a1 = t[1];
> }
> }

I cannot reproduce the error. writeln(t[0]) works here: https://run.dlang.io/is/kz6lFc

June 15, 2020
On 15.06.20 16:03, Max Samukha wrote:
> On Monday, 15 June 2020 at 13:57:01 UTC, Max Samukha wrote:
> 
>>> void main() {
>>>     Tuple!(byte, int, short) t;
>>>     writeln(t[0]);
>>> }
>>>
>>>> test.d(57,23): Error: need `this` for `__value_field_2` of type `byte`
>>
>> It should work. This works:
>>
>> void main() {
>>     Tuple!(byte, int, short) t;
>>
>>     t[0] = 0;
>>     t[1] = 2;
>>     t[2] = 3;
>>
>>     auto a0 = t[0];
>>     auto a1 = t[1];
>> }
>> }
> 
> I cannot reproduce the error. writeln(t[0]) works here: https://run.dlang.io/is/kz6lFc
> 

Apparently, it has been fixed in 2.092. Nice!
June 15, 2020
On Monday, 15 June 2020 at 14:18:38 UTC, Timon Gehr wrote:
> Apparently, it has been fixed in 2.092. Nice!

Oh wow that's fantastic. Does anyone know which changeset / PR fixed it?