January 07
I'm concerned about what would happen to the following.

All these are considered equivalent currently:

(a,b,c)
(a,(b,c))
((a,b,c))
((a,b),(c))
((a),(b),(c))

[Of course, using the __tuple syntax.]

Does your proposal change that? I can't quite be sure.
January 08
On Thursday, 6 January 2022 at 13:18:56 UTC, Timon Gehr wrote:

> void foo(string x,){}      // <- unary tuple

While you are correct, it is likely to be a breaking change. Currently (string x,) is allowed and means the same as (string x).
January 08

On Wednesday, 29 December 2021 at 20:07:20 UTC, data pulverizer wrote:

>

For me there are two main ones:

  • A lot of people have said this one but I'll +1 it. Tuples fully built into the language with destructuring and all the common features. A year or two ago I thought this was definitely going to happen.

  • Relaxing policy on symbolic and infix/prefix/postfix/binary/unary notation, perhaps having protections against using obvious things like "." but relatively free elsewhere. From a science/math point of view this would be great, and it can greatly improve code readability in such applications.

One more thing, native string interpolation similar to f-strings style in Python or Julia style strings for example

auto my_variable = 42;
auto output = "The meaning of life is ${my_variable}"

I think this also seemed like it was in the works a year or two ago.

January 08
On 1/3/2022 7:11 PM, Timon Gehr wrote:
> On 04.01.22 04:09, Timon Gehr wrote:
>>
>> To be very clear, I want this:
>>
>> [(1,2),(3,4)].map!((a,b)=>a+b).each!writeln;
>>
>> An this is generally what people mean when they talk about "tuples".
> 
> 
> (I understand that there is something in the DMD source code already named "Tuple", but that's not really a tuple, it's a sequence of values that will auto expand into any context. Being able to return that from functions would be nice, but I think it's independent of what people are talking about when they want tuples.)

Yes, and reconciling this will be the problem.
January 08
On 1/4/2022 11:28 PM, Timon Gehr wrote:
> How about something like opArgs, dealing specifically with this case? (i.e., a function call `foo(x)` with a single argument is immediately rewritten to `foo(x.opArgs)` if `x` has a member `opArgs`, and this rewrite is applied exactly once.)

Sounds like a promising idea.
January 09
On 1/8/22 02:01, Walter Bright wrote:
> On 1/3/2022 8:30 PM, Timon Gehr wrote:
>> On 29.12.21 06:09, Walter Bright wrote:
>>> @live currently does that for pointers, but not for non-pointers.
>> It removes the variable from the scope? (And anyway, @live is a function annotation, which makes little sense.)
> 
> @live applies to all the contents of the function.
> ...

And none of the calling context. As I said, makes little sense.

> `scope` is ignored for non-pointer variables, whether they are @live or not.
> ...

The language can't know what's designed to act like a pointer.

> 
>>> What's the use case for it?
>>> ...
>>
>> This is just how moving things works. If you move it, it's no longer where it was. If the variable disappears, we don't have to bother with putting `x` into some safe default state. Some types can't even naturally support a safe default state. The simplest example is indeed a `struct` implementing a unique non-null pointer managing its own memory. (By whatever means you want, it does not even have to have any pointer members to implement such semantics.)
>>
>>>
>>>> int y=move(y); // ok
>>>> ```
>>>
>>> I see what you mean, but since D disallows:
>>>
>>>      int x; { int x; }
>>>
>>> which prevents a number of bugs, so I can't see allowing that.
>>
>> I don't see how that's related. It's two variables `y` whose lifetimes do not overlap. It's more like this:
>>
>> {int x; } { int x; }
>>
>> Which D allows.
> 
> 
> You are pedantically correct, but it's one of those things that would be disallowed because it *looks* like a bug.

Perhaps that's what it looks like to you, but to other people it just looks like the typestate pattern, for example.

> There's no ambiguity to
> 
>      int x; { int x; }
> 
> either, it just *looks* like a bug, and a good chunk of the time it is not intended by the user and is a bug. I haven't seen a case yet where such code is needed.
> ...

I fully agree that variable hiding is error prone, but that's just not what's going on here.

> I don't see a necessity to allow the y redeclaration.

_Redeclaring_ an _existing_ variable is of course disallowed. Declaring a variable of the same name as one that's consumed in its initializer is rather common (e.g. typestate pattern). And it is convenient and not error prone at all.
January 09
On 1/8/22 02:39, Walter Bright wrote:
> I'm concerned about what would happen to the following.
> 
> All these are considered equivalent currently:
> 
> (a,b,c)
> (a,(b,c))
> ((a,b,c))
> ((a,b),(c))
> ((a),(b),(c))
> ...

x is equivalent to (x). (Always, and a design that changes that is broken.)

Therefore, `(a,b,c)`, `((a,b,c))` and `((a),(b),(c))` are the same, a triple with components a, b, and c.

> [Of course, using the __tuple syntax.]
> 
> Does your proposal change that? I can't quite be sure.

`(a,(b,c))` is not the same as `((a,b),c)` in my proposals, those are always pairs, where the second and first component, respectively, are also pairs. Both are distinct from `(a,b,c)`, which is always a triple.

However, I don't propose to _change_ any existing auto-expanding behavior, I want to add tuple syntax and actual tuple behavior for something similar to a Phobos tuple. (I.e., based on a `struct` template.)
January 09
On 1/9/22 11:05, Timon Gehr wrote:
> 
> `(a,(b,c))` is not the same as `((a,b),c)` in my proposals, those are always pairs, where the second and first component, respectively, are also pairs. Both are distinct from `(a,b,c)`, which is always a triple.

(Technically, I guess if `a, b or c` is an expression/expanded tuple of the variety that DMD already supports, the number of components of the results can be different.)
January 09
On 1/8/22 11:28, Max Samukha wrote:
> On Thursday, 6 January 2022 at 13:18:56 UTC, Timon Gehr wrote:
> 
>> void foo(string x,){}      // <- unary tuple
> 
> While you are correct, it is likely to be a breaking change. Currently (string x,) is allowed and means the same as (string x).

True.
January 09
On 1/9/22 00:03, Walter Bright wrote:
> On 1/3/2022 7:11 PM, Timon Gehr wrote:
>> On 04.01.22 04:09, Timon Gehr wrote:
>>>
>>> To be very clear, I want this:
>>>
>>> [(1,2),(3,4)].map!((a,b)=>a+b).each!writeln;
>>>
>>> An this is generally what people mean when they talk about "tuples".
>>
>>
>> (I understand that there is something in the DMD source code already named "Tuple", but that's not really a tuple, it's a sequence of values that will auto expand into any context. Being able to return that from functions would be nice, but I think it's independent of what people are talking about when they want tuples.)
> 
> Yes, and reconciling this will be the problem.
I agree. This is what I had in mind:

- "tuple": the new thing, has an address
- "expanded tuple": the existing thing

If you have a tuple `t`, you can get an expanded tuple using `t.expand`, to transform an expanded tuple `e` into a tuple, you use `(e,)`. (This is a single-element tuple, this syntax is the same as in e.g. Python. Due to auto-expanding of `e`, it can have more than one element.)

In practice, I think expanding is useful, but I'd mostly prefer to use tuples that don't auto-expand and expand them explicitly with `t.expand` if needed. `t.expand` itself is of course an auto-expanding expression.


In `void foo(T...)(T args)`, `args` would probably still be an expanded tuple.

The main challenge is this:

```d
void foo(T)(T arg){}
```

right now, this will never match the following call:

```d
foo(1,2)
```

But with tuples, we could just instantiate it with `T=(int,int)` and then the call should match. This is the main reason why the tuple DIP did not attempt to allow calling a function with a single tuple parameter with multiple arguments, but of course ideally it should work...