April 24, 2020
On Fri, Apr 24, 2020 at 4:35 PM Walter Bright via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

>
> There's a lot of merit to the idea of arrays and tuples using a common
> syntax,
> which is what I'm proposing.
>

Your idea all falls over anywhere it encounters variadic args, or potential for overloads though. Without an explicit expression, the only way forward is to preserve existing D semantics (or it's a radically breaking change), and that will severely narrow the applicability of this proposal.

Consider this:

  alias Tup = AliasSeq!(0, 2, 3);
  void fun(int);
  fun(Tup);  // scalar argument receives tuple, it can expand, so: fun(0),
fun(1), fun(2)

Now someone introduces an overload:
  void fun(int, int, int);

To the previous expression expanded, but now it found an applicable call
and doesn't expand anymore.
Obviously that's far too dangerous to allow, so; functions MAY have
overloads (or just accept var args), and I think that simply means that
expansion can never be applied to function arguments.
That's a HUGE loss, because I do that extremely frequently. Probably more
than anything.

This same principle argument applies to templates which may receive
variadic arguments.
It weakens the value in my DIP by a huge amount to forego the explicit
syntax designed specifically to handle the resolution of ambiguous
expressions.

This doesn't rule out your proposition that `Tup + 10` can (and probably should) work though. Again, these are not mutually exclusive proposals.


April 24, 2020
On Wednesday, 22 April 2020 at 12:04:30 UTC, Manu wrote:
> https://github.com/dlang/DIPs/pull/188

My two cents; the idea is nice, however I would consider a bit different syntax.

1. We already have std.typecons.Tuple.expand, which does the similar thing. If it is doable with a library solution, it could be Expand!(TypeTuple).

2. If not, the ... operator is a good choice here, but I would suggest making it prefix, and not postfix. First, it would nicely differenciate it from variadic operator. Second, it would be straightforward and consistent for those using Javascript as well, as ... is a spread operator there - `call(...[a, b, c])` is equivalent to `call(a, b, c)`.

Such a spread operator in D could work for TypeTuples, value tuples and static arrays. Simple, conscise and similar with what one of the most widely used languages does.
April 24, 2020
This can resolve my complaint about syntax and I can happily but out of discussions if this is the direction we go :P
April 24, 2020
My two cents; the idea is nice, however I would consider a bit different syntax.

1. We already have std.typecons.Tuple.expand, which does the similar thing. If it is doable with a library solution, it could be Expand!(TypeTuple).

2. If not, the ... operator is a good choice here, but I would suggest making it prefix, and not postfix. First, it would nicely differenciate it from variadic operator. Second, it would be straightforward and consistent for those using Javascript as well, as ... is a spread operator there - `call(...[a, b, c])` is equivalent to `call(a, b, c)`.

Such a spread operator in D could work for TypeTuples, value tuples and static arrays. Simple, conscise and similar with what one of the most widely used languages does.
April 24, 2020
On 4/23/2020 11:52 PM, Manu wrote:
> On Fri, Apr 24, 2020 at 4:35 PM Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com <mailto:digitalmars-d@puremagic.com>> wrote:
> 
>     On 4/23/2020 10:51 PM, Manu wrote:
>      > Another reason I introduce `...` is for static fold.
>      > The follow-up to this DIP would make this expression work:
>      >
>      >    `Tup + ...`  ->  `Tup[0] + Tup[1] + ... + Tup[$-1]`
> 
>     I expect static foreach can handle that. But we can dig a little deeper. D
>     doesn't have a special syntax to sum the elements of an array, but it can use a
>     library function to do it. The next observation is that to sum the elements
>     of a
>     tuple, all the tuple members need to be implicitly convertible to a single
>     arithmetic type. There is a way to do that:
> 
>           [ Tup ]
> 
> 
> No, it's not necessary that they are common types. It's actually the opposite intent of the expression.

The only way:

  1 + 'a' + 1.0 + 1L + 2.0L

can be computed is if the operands are brought to a common arithmetic type.
April 24, 2020
On Fri, Apr 24, 2020 at 5:35 PM Walter Bright via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On 4/23/2020 11:52 PM, Manu wrote:
> > On Fri, Apr 24, 2020 at 4:35 PM Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com <mailto:digitalmars-d@puremagic.com>>
> wrote:
> >
> >     On 4/23/2020 10:51 PM, Manu wrote:
> >      > Another reason I introduce `...` is for static fold.
> >      > The follow-up to this DIP would make this expression work:
> >      >
> >      >    `Tup + ...`  ->  `Tup[0] + Tup[1] + ... + Tup[$-1]`
> >
> >     I expect static foreach can handle that. But we can dig a little
> deeper. D
> >     doesn't have a special syntax to sum the elements of an array, but
> it can use a
> >     library function to do it. The next observation is that to sum the
> elements
> >     of a
> >     tuple, all the tuple members need to be implicitly convertible to a
> single
> >     arithmetic type. There is a way to do that:
> >
> >           [ Tup ]
> >
> >
> > No, it's not necessary that they are common types. It's actually the
> opposite
> > intent of the expression.
>
> The only way:
>
>    1 + 'a' + 1.0 + 1L + 2.0L
>
> can be computed is if the operands are brought to a common arithmetic type.
>

It doesn't make much sense to think in terms of primitive types. As I just
said (but you truncated), operator overloads are almost certainly part of
this equation.
I think it's more common to do a fold like this with logical operators
though; `&&` appears 9 times out of 10 in my code.


April 24, 2020
On Thursday, 23 April 2020 at 22:00:40 UTC, Walter Bright wrote:
> On 4/22/2020 5:04 AM, Manu wrote:
>> [...]
>
> Well done, Manu! This looks like a very good idea. I'm optimistic about it. Thank you for pushing this forward!

That made my day a sunny day! :-P


April 24, 2020
On 4/24/2020 12:10 AM, Manu wrote:
> Your idea all falls over anywhere it encounters variadic args, or potential for overloads though. Without an explicit expression, the only way forward is to preserve existing D semantics (or it's a radically breaking change), and that will severely narrow the applicability of this proposal.
> 
> Consider this:
> 
>    alias Tup = AliasSeq!(0, 2, 3);
>    void fun(int);
>    fun(Tup);  // scalar argument receives tuple, it can expand, so: fun(0), fun(1), fun(2)

Write it as:

    Tup.fun();

Of course,

    fun(1, Tup);

cannot be rewritten in this way, but then a rationale will be necessary as to why it must be written as func(1, Tup) instead of fun(Tup, 1).


> This same principle argument applies to templates which may receive variadic arguments.
> It weakens the value in my DIP by a huge amount to forego the explicit syntax designed specifically to handle the resolution of ambiguous expressions.

Please enumerate examples, along with an explanation of why they are compelling and why it is unreasonable to do another way. (One such other way would be using static foreach.)


> This doesn't rule out your proposition that `Tup + 10` can (and probably should) work though.

At least we agree on something :-)

On a philosophical point, I am generally opposed to adding syntax just to support some unusual cases. I am sure one could come up with examples where the ... syntax won't work, too. For example, could it work with creating a new tuple out of every third tuple member? I'm not looking for a specific answer, but for a meta answer of "should we support these operations at all with special syntax"?

My predisposition is towards simple building blocks that can be combined to derive complex behaviors, not complex building blocks that we try to bash into simple behaviors. Simple things like applying the existing behaviors of array operations to tuples. D shouldn't consist of a mass of special rules, but a smaller set of rules that can be consistently applied across diverse situations.

We did the same thing with named function arguments - apply the existing rules for named struct initializers. It didn't support every behavior people desired, but it supported enough that the remainder wasn't particularly significant.
April 24, 2020
On 4/24/2020 1:03 AM, Walter Bright wrote:
> On 4/24/2020 12:10 AM, Manu wrote:
>> Your idea all falls over anywhere it encounters variadic args, or potential for overloads though. Without an explicit expression, the only way forward is to preserve existing D semantics (or it's a radically breaking change), and that will severely narrow the applicability of this proposal.
>>
>> Consider this:
>>
>>    alias Tup = AliasSeq!(0, 2, 3);
>>    void fun(int);
>>    fun(Tup);  // scalar argument receives tuple, it can expand, so: fun(0), fun(1), fun(2)
> 
> Write it as:
> 
>      Tup.fun();

Incidentally, belay that. That will currently produce: fun(0, 2, 3);
April 24, 2020
On 4/24/2020 12:39 AM, Manu wrote:
> It doesn't make much sense to think in terms of primitive types. As I just said (but you truncated), operator overloads are almost certainly part of this equation.

Operator overloads don't change it.

> I think it's more common to do a fold like this with logical operators though; `&&` appears 9 times out of 10 in my code.

    [ cast(bool)Tup ]