December 29, 2021

On Wednesday, 29 December 2021 at 06:48:11 UTC, Walter Bright wrote:

>

On 12/28/2021 9:14 PM, Walter Bright wrote:

>

Actually, I agree with the need for tuples, and am very open to a good design for it.

I'd like to see something that unified arrays, structs, argument lists (for functions).

I think we should unify static arrays and tuples, and call it a day. A tuple or a static array still would not be the same as an argument list, but could be easily converted to one with .expand, just like the present-day tuple.

As for structs, I think it's better they're not interchangeable with other types by default. One reason is that we still want that overloads like this are possible:

void setBackgroundColour(RGB colour);
void setBackgroundColour(HSV colour);

This way, the author of a type can decide whether the type should be interchangeable:

// not interchangeable with other types of similar structure
struct Vector(size_t dim)
{ private float[dim] content;
  ref opIndex(size_t i){return content[i];}
}

// This would be interchangeable
alias Vector(size_t dim) = float[dim];

// Also interchangeable
alias Vector(size_t dim) = Tuple!(Repeat!(dim, float));

Also, If we accept https://github.com/dlang/DIPs/pull/173 (I definitely like it!), I suggest that we also make void the same type as Tuple!() and AnyType[0].

December 29, 2021
On Wednesday, 29 December 2021 at 05:14:43 UTC, Walter Bright wrote:
> Actually, I agree with the need for tuples, and am very open to a good design for it.


Yes please! some love for tuples is very much needed, recently feep shared his neat lang on the IRC, and  look at this beauty: https://github.com/Neat-Lang/neat/blob/master/test/runnable/tuples.nt#L6


No need of an import, no need of special types, it's built-in, using it would be sweet

It's similar in GO https://gobyexample.com/multiple-return-values

I love that, i wish it could be possible in D

December 29, 2021

On Monday, 11 October 2021 at 15:59:10 UTC, Atila Neves wrote:

>

I'm brainstorming about what I'll talk about at DConf, and during a conversation with Walter I thought it might be cool to talk about:

  • Worst features implemented in a non-toy language
  • Worst features (in your opinion) in D
  • Features you'd like to see in D

Ideas? Examples?

Thanks!

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.

January 03, 2022
On 12/29/21 7:48 AM, Walter Bright wrote:
> On 12/28/2021 9:14 PM, Walter Bright wrote:
>> Actually, I agree with the need for tuples, and am very open to a good design for it.
> 
> I'd like to see something that unified arrays, structs, argument lists (for functions).

I would like to do that, but I think it would break code like this:

void foo(int a,int b){}
void foo(int[2] x){}

After unification, those two function definitions would now be the same.

Is this what you have in mind?
January 03, 2022
On 1/3/22 8:40 AM, Timon Gehr wrote:
> On 12/29/21 7:48 AM, Walter Bright wrote:
>> On 12/28/2021 9:14 PM, Walter Bright wrote:
>>> Actually, I agree with the need for tuples, and am very open to a good design for it.
>>
>> I'd like to see something that unified arrays, structs, argument lists (for functions).
> 
> I would like to do that, but I think it would break code like this:
> 
> void foo(int a,int b){}
> void foo(int[2] x){}
> 
> After unification, those two function definitions would now be the same.
> 
> Is this what you have in mind?

And there is also this:

void foo(T...)(T args){}

int[2] x;

foo(x); // foo!(int[2]) and foo!(int,int) would now need to be the same
January 03, 2022
On 1/2/2022 11:40 PM, Timon Gehr wrote:
> On 12/29/21 7:48 AM, Walter Bright wrote:
>> On 12/28/2021 9:14 PM, Walter Bright wrote:
>>> Actually, I agree with the need for tuples, and am very open to a good design for it.
>>
>> I'd like to see something that unified arrays, structs, argument lists (for functions).
> 
> I would like to do that, but I think it would break code like this:
> 
> void foo(int a,int b){}
> void foo(int[2] x){}
> 
> After unification, those two function definitions would now be the same.
> 
> Is this what you have in mind?

Not exactly, since the ABI won't permit it. For example,

    struct S { byte b; int c; }
    byte b;
    int c;

    void func(byte, int);

I can't call func with S(b,c); because of the function call ABI. Having a struct implicitly convertible to a tuple will also likely cause overloading confusion and will break legacy code.

But we could support conversions. For example, a tuple could be converted to an anonymous struct with the syntax `struct(b,c)`. (A tuple can already be used to package up arguments to a function parameter list.)

The ABI has no way to return a tuple from a function. But a function returning a tuple can be done by packing it into an anonymous struct and then unpacking it at the call site. This can happen under the hood, the user just sees a tuple.

So, no, implicit conversions of Array <=> Struct <=> Tuple will likely cause many problems. But explicit conversions should work.
January 03, 2022
On 1/2/2022 11:42 PM, Timon Gehr wrote:
> And there is also this:
> 
> void foo(T...)(T args){}
> 
> int[2] x;
> 
> foo(x); // foo!(int[2]) and foo!(int,int) would now need to be the same

With such implicit conversions, the language would just descend into chaos. So no :-)
January 04, 2022
On 03.01.22 10:27, Walter Bright wrote:
> On 1/2/2022 11:42 PM, Timon Gehr wrote:
>> And there is also this:
>>
>> void foo(T...)(T args){}
>>
>> int[2] x;
>>
>> foo(x); // foo!(int[2]) and foo!(int,int) would now need to be the same
> 
> With such implicit conversions, the language would just descend into chaos. So no :-)

It's not an implicit conversion. I am mostly trying to figure out what constitutes "unification" for you. (In the programming languages I built, `int×int` and `int^2` are literally the same type, there is subtyping, but all actual type conversions are explicit.)

Personally, the single thing I care most about in terms of "unification" is that this works:

void foo(int a,int b){}
(int,int) t;
foo(t); // ok, function expects (int,int), and (int,int) was given

But *not* this:

void foo((int,int) a,int b){}

(int,int,int) t;
foo(t); // error, function expects ((int,int),int), not (int,int,int)

I do not care much about `is((int,int)==int[2])`, but when you say you want to unify tuples and static arrays, that's what I think of.
January 04, 2022
On 03.01.22 10:08, Walter Bright wrote:
> On 1/2/2022 11:40 PM, Timon Gehr wrote:
>> On 12/29/21 7:48 AM, Walter Bright wrote:
>>> On 12/28/2021 9:14 PM, Walter Bright wrote:
>>>> Actually, I agree with the need for tuples, and am very open to a good design for it.
>>>
>>> I'd like to see something that unified arrays, structs, argument lists (for functions).
>>
>> I would like to do that, but I think it would break code like this:
>>
>> void foo(int a,int b){}
>> void foo(int[2] x){}
>>
>> After unification, those two function definitions would now be the same.
>>
>> Is this what you have in mind?
> 
> Not exactly, since the ABI won't permit it. For example,
> 
>      struct S { byte b; int c; }
>      byte b;
>      int c;
> 
>      void func(byte, int);
> 
> I can't call func with S(b,c); because of the function call ABI. ...

My DIP draft extends "alias this" to allow this (which should work anyway):

alias Seq(T...)=T;
struct S{
    byte b;
    int c;
    alias this=Seq!(b,c);
}

void func(byte,int);

func(S());

Then it proposes to make tuples a struct template with such an alias this.

Of course, it would also be possible to make tuples a built-in type, which would be my preferred design for a new language.

> Having a struct implicitly convertible to a tuple will also likely cause overloading confusion and will break legacy code.

Yes, I don't want that. The benefit of introducing tuples as a struct template is precisely that it is a lot less likely to cause confusion in legacy code. It does have some significant drawbacks, e.g. `foo(int,int)` and `foo((int,int))` would have a different ABI and the second overload can't be called as `foo(1,2);`...

> But we could support conversions. For example, a tuple could be converted to an anonymous struct with the syntax `struct(b,c)`. (A tuple can already be used to package up arguments to a function parameter list.)
> 
> The ABI has no way to return a tuple from a function. But a function returning a tuple can be done by packing it into an anonymous struct and then unpacking it at the call site. This can happen under the hood, the user just sees a tuple.
> ...

Returning expanded values from functions is interesting (and my compiler frontend allows it), but I don't think that's really the main issue here.

> So, no, implicit conversions of Array <=> Struct <=> Tuple will likely cause many problems. But explicit conversions should work.


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".
January 04, 2022
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.)