Jump to page: 1 2
Thread overview
First Draft: Tuple Unpacking Syntax
Jul 25
Meta
OT: Tuple Syntax and Placeholders (Re: First Draft: Tuple Unpacking Syntax)
Jul 31
IchorDev
July 25

This DIP proposes built-in tuple unpacking syntax for D. A sample of the proposed syntax:

import std.typecons : tuple;

(int a, string b) = tuple(1, "2");
assert(a == 1);
assert(b == "2");

auto (a, b) = tuple(1, "2");
static assert(is(typeof(a) == int));
static assert(is(typeof(b) == string));

auto (a, immutable b, c) = tuple(1, "2", 3.0);
static assert(is(typeof(a) == int));
static assert(is(typeof(b) == immutable string));
static assert(is(typeof(c) == double));

The DIP is based on Timon Gehr's old DIP for tuple syntax in D (https://github.com/tgehr/DIPs/blob/tuple-syntax/DIPs/DIP1xxx-tg.md), but is solely limited to support for unpacking; it is not a full tuple-syntax DIP. If the reception and general sentiment for this DIP are positive, further enhancements to add built-in tuple support to D may be proposed in the future.

Thanks to Timon and Nick Treleaven for doing the bulk of the implementation and conceptual work on this proposal. I mainly just kickstarted things and am facilitating the DIP process.

The DIP:
https://github.com/MetaLang/DIPs/blob/bf357d16b1bce65ba4ed95a08d146d4015eeb2d7/DIPs/1NNN-JH-TG-NT.md

July 26
Overall quite good, just a couple of tweaks I'd prefer to have to make everyone's lives easier (such as custom runtime writers).



Proposal 3: Built-in tuple types and literals

Why are you putting it into object.d?

Its big enough as it is, and these types can be copied wholesale.

Putting them in a dedicated module would be a much better choice.



Proposal 6: Placeholder name _

This is guaranteed to break code, its going to have to wait for an edition to execute. No need to do it in two stages then.

July 26
This is a well written DIP. Congratulations!

The forward range tuple is pretty cool.

Let's move forward with this.

bearophile's example uses `_` as a placeholder, but I don't see it mentioned in the rest of the DIP?

For the example:
```
auto arr = [tuple(1, "2"), tuple(3, "4"), tuple(5, "6")];

foreach((x, y); arr) {
    writeln(x, " ", y); // "1 2\n3 4\n5 6"
}

foreach((int x, string y); arr) {
    writeln(x, " ", y);// "1 2\n3 4\n5 6"
}
```

shouldn't there be a trailing \n after the 6?
July 27
On 7/27/25 08:31, Walter Bright wrote:
> This is a well written DIP. Congratulations!
> 
> The forward range tuple is pretty cool.
> 
> Let's move forward with this.
> 
> bearophile's example uses `_` as a placeholder, but I don't see it mentioned in the rest of the DIP?
> ...

He had used it as a placeholder by convention, but it's just a valid identifier. It would not be possible to use it for two distinct variables in the same scope.

I.e., you can do:

```d
int _ = 2;
```

But not:

```d
int _ = 3;
int _ = 4;
```

Which would work with a true placeholder.

> For the example:
> ```
> auto arr = [tuple(1, "2"), tuple(3, "4"), tuple(5, "6")];
> 
> foreach((x, y); arr) {
>      writeln(x, " ", y); // "1 2\n3 4\n5 6"
> }
> 
> foreach((int x, string y); arr) {
>      writeln(x, " ", y);// "1 2\n3 4\n5 6"
> }
> ```
> 
> shouldn't there be a trailing \n after the 6?

Yes.

July 27
On 7/25/25 15:42, Richard (Rikki) Andrew Cattermole wrote:
> Overall quite good, just a couple of tweaks I'd prefer to have to make everyone's lives easier (such as custom runtime writers).
> ...

I think you were looking at the wrong document, seems you were reading my old draft that had a bigger scope. Neither of these features are proposed by the DIP.

That said:

> 
> 
> Proposal 3: Built-in tuple types and literals
> 
> Why are you putting it into object.d?
> 
> Its big enough as it is, and these types can be copied wholesale.
> 
> Putting them in a dedicated module would be a much better choice.
> ...
> 

Something like `core.internal.tuple` or similar will probably be better.

> 
> Proposal 6: Placeholder name _
> 
> This is guaranteed to break code, its going to have to wait for an edition to execute. No need to do it in two stages then.
> 

Yes. This is why this is not part of this DIP.
July 28
You are so right, I looked at the wrong document.

In that case I'd like to point out:

1. The wording around ``ref`` and ``out`` could be improved. The behavior of each should be matching and it does seem to read as such, even if it isn't in the same paragraph.

2. Moving elements should be in DIP even if implementation doesn't support it. I don't think anything special needs to be done here. My understanding is the compiler should be seeing the VarDeclaration -> VarDeclaration assignment and handle it normally.
July 31

On Friday, 25 July 2025 at 04:27:53 UTC, Meta wrote:

>

The DIP:
https://github.com/MetaLang/DIPs/blob/bf357d16b1bce65ba4ed95a08d146d4015eeb2d7/DIPs/1NNN-JH-TG-NT.md
[...]
Moving elements (rather than copying) from the value sequence is not supported.

Could you please add an explanation for this? I really don't understand why it wouldn't be supported, and I would certainly prefer for unpacking to be a move rather than a copy in general.

>

Postponed: Unpacking assignments

Unpacking a tuple into lvalues is postponed until tuple literals are supported, because both redefine the comma operator syntax.

auto t = (1, 2); // tuple literal
int x, y;
(x, y) = t;
assert(x == 1);
assert(y == 2);

You can pretty-much already do this like so:

int x, y;
AliasSeq!(x, y) = t;
August 01

On Sunday, 27 July 2025 at 21:52:15 UTC, Richard (Rikki) Andrew Cattermole wrote:

>
  1. Moving elements should be in DIP even if implementation doesn't support it. I don't think anything special needs to be done here. My understanding is the compiler should be seeing the VarDeclaration -> VarDeclaration assignment and handle it normally.

I think you are asking for something special:

    T a, b;
    alias seq = AliasSeq!(a, b);
    // auto (x, y) = a;
    auto x = a[0];
    auto y = a[1];

a[0] and a[1] are not moved by the lowered code.

Do you have an example where there should be a move?

August 01

On Friday, 1 August 2025 at 10:08:09 UTC, Nick Treleaven wrote:

>

On Sunday, 27 July 2025 at 21:52:15 UTC, Richard (Rikki) Andrew Cattermole wrote:

>
  1. Moving elements should be in DIP even if implementation doesn't support it. I don't think anything special needs to be done here. My understanding is the compiler should be seeing the VarDeclaration -> VarDeclaration assignment and handle it normally.

I think you are asking for something special:

    T a, b;
    alias seq = AliasSeq!(a, b);
    // auto (x, y) = a;
    auto x = a[0];
    auto y = a[1];

Sorry, wrong code above.

    T a, b;
    alias seq = AliasSeq!(a, b);
    // auto (x, y) = seq;
    auto x = seq[0];
    auto y = seq[1];
>

a[0] and a[1] are not moved by the lowered code.

Do you have an example where there should be a move?

August 02
On 01/08/2025 10:08 PM, Nick Treleaven wrote:
> On Sunday, 27 July 2025 at 21:52:15 UTC, Richard (Rikki) Andrew Cattermole wrote:
>> 2. Moving elements should be in DIP even if implementation doesn't support it. I don't think anything special needs to be done here. My understanding is the compiler should be seeing the VarDeclaration -> VarDeclaration assignment and handle it normally.
> 
> I think you are asking for something special:
> 
> ```d
>      T a, b;
>      alias seq = AliasSeq!(a, b);
>      // auto (x, y) = a;
>      auto x = a[0];
>      auto y = a[1];
> ```
> 
> `a[0]` and `a[1]` are not moved by the lowered code.
> 
> Do you have an example where there should be a move?

You are getting to what I was thinking, there is no reason to mention copying or moving. Its defined behavior elsewhere.

« First   ‹ Prev
1 2