April 23, 2020 Re: I dun a DIP, possibly the best DIP ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | On Thursday, 23 April 2020 at 20:08:51 UTC, Stefan Koch wrote:
>
> k tuples with n elements can only expand to 1 tuple with k*n elements.
> They can't get more.
Acutely let me be more specific.
given TTup = T!(int, long, double, float)
the expression cast(TTup)0... yields
tuple(0, 0L, 0.0, 0.0f)
given VTup = T!(1, 2, 3, 4)
you can write the expression cast(TTup)VTup...
which yields tuple(1, 2L, 3.0, 4.0f)
should the length's of the tuple in and subexpression using multiple tuples differ, that's an error.
|
April 23, 2020 Re: I dun a DIP, possibly the best DIP ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | On 4/23/20 4:08 PM, Stefan Koch wrote:
> On Thursday, 23 April 2020 at 19:27:31 UTC, Steven Schveighoffer wrote:
>> On 4/23/20 3:02 PM, Stefan Koch wrote:
>>> On Thursday, 23 April 2020 at 18:57:04 UTC, Steven Schveighoffer wrote:
>>>> [...]
>>>
>>> It's the latter.
>>> you cannot re-expand.
>>
>> Those 2 are contradictory statements.
>>
>> If it's the latter, then tuple1... is expanded to a tuple that is then used in the outer expansion.
>>
>
> k tuples with n elements can only expand to 1 tuple with k*n elements.
> They can't get more.
You have lost me.
Can you go through a blow-by-blow of how this nested expansion happens?
alias tuple1 = AliasSeq!(1, 2, 3);
alias tuple2 = AliasSeq!(4, 5, 6)
AliasSeq!(tuple1..., tuple2)...
-Steve
|
April 23, 2020 Re: I dun a DIP, possibly the best DIP ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Thursday, 23 April 2020 at 20:23:03 UTC, Steven Schveighoffer wrote:
> On 4/23/20 4:08 PM, Stefan Koch wrote:
>> On Thursday, 23 April 2020 at 19:27:31 UTC, Steven Schveighoffer wrote:
>>> On 4/23/20 3:02 PM, Stefan Koch wrote:
>>>> On Thursday, 23 April 2020 at 18:57:04 UTC, Steven Schveighoffer wrote:
>>>>> [...]
>>>>
>>>> It's the latter.
>>>> you cannot re-expand.
>>>
>>> Those 2 are contradictory statements.
>>>
>>> If it's the latter, then tuple1... is expanded to a tuple that is then used in the outer expansion.
>>>
>>
>> k tuples with n elements can only expand to 1 tuple with k*n elements.
>> They can't get more.
>
> You have lost me.
>
> Can you go through a blow-by-blow of how this nested expansion happens?
>
> alias tuple1 = AliasSeq!(1, 2, 3);
> alias tuple2 = AliasSeq!(4, 5, 6)
>
> AliasSeq!(tuple1..., tuple2)...
>
> -Steve
This nested expression does not parse.
And I don't think it should.
Because we cannot nest tuples in tuples.
|
April 23, 2020 Re: I dun a DIP, possibly the best DIP ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | On 4/23/20 4:34 PM, Stefan Koch wrote:
> On Thursday, 23 April 2020 at 20:23:03 UTC, Steven Schveighoffer wrote:
>> On 4/23/20 4:08 PM, Stefan Koch wrote:
>>> On Thursday, 23 April 2020 at 19:27:31 UTC, Steven Schveighoffer wrote:
>> You have lost me.
>>
>> Can you go through a blow-by-blow of how this nested expansion happens?
>>
>> alias tuple1 = AliasSeq!(1, 2, 3);
>> alias tuple2 = AliasSeq!(4, 5, 6)
>>
>> AliasSeq!(tuple1..., tuple2)...
>>
>
> This nested expression does not parse.
> And I don't think it should.
> Because we cannot nest tuples in tuples.
OK, so the answer is, you can only have one ... per expression?
-Steve
|
April 23, 2020 Re: I dun a DIP, possibly the best DIP ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | 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!
|
April 24, 2020 Re: I dun a DIP, possibly the best DIP ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer Attachments:
| On Fri, Apr 24, 2020 at 2:30 AM Steven Schveighoffer via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
> On 4/23/20 9:53 AM, Manu wrote:
>
> >
> > You can do this by expanding tuples with the appropriate indices:
> > fun(Xs[CrossIndexX], Ys[CrossIndexY])...
> > Where CrossIndexX is (0, 0, 1, 1) and CrossIndexY is (0, 1, 0, 1).
>
> I don't think this works, aren't Xs and Ys tuples also?
>
> I think what you need is to expand the Xs and Ys into further tuples:
>
> alias XParams = Xs[CrossIndexX]...;
> alias YParams = Ys[CrossIndexY]...;
> fun(XParams, YParams)...;
>
> Which would work I think.
>
> this means you need 4 pre-expression declarations! Two for the X and Y expansions, and two for the indexes.
>
> -Steve
>
Oh yeah, it was too late at night. Your solution looks right.
On a slightly unrelated note; there's a really interesting idea up-thread
about making nested `...` not be expanded by the outer `...`
For instance:
template T(A, B...) { ... }
T!(Tup1, Tup2...)...
What we're saying here is, Tup2 gets the identity expansion, but that result is NOT expanded with the outer; so the expansion above is:
T!(Tup1, Tup2...)... -> ( T!(Tup1[0], Tup2...), T!(Tup1[1], Tup2...),
..., T!(Tup1[$-1], Tup2...) )
This is opposed to currently where we recurse through nested expansions, effectively:
T!(Tup1, Tup2)... -> ( T!(Tup1[0], Tup2[0]), T!(Tup1[1], Tup2[1]),
..., T!(Tup1[$-1], Tup2[$-1]) )
So, despite Tup2's expansion is the identity expansion, this syntax allows
Tup2 to be passed to T!()'s variadic args as the tuple it is, rather than
expanded like Tup.
Using `...` in nested context this way gives articulate control over cases
where multiple Tuples in the tree should or shouldn't be expanded by `...`
I think this is also the natural rule; it follows from the claim that expansion is performed pre-semantic evaluation; nested `...` is only a tuple AFTER evaluation, so it seems natural that it should not be expanded by the outer expansion.
|
April 24, 2020 Re: I dun a DIP, possibly the best DIP ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch Attachments:
| On Fri, Apr 24, 2020 at 5:05 AM Stefan Koch via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
> On Thursday, 23 April 2020 at 18:57:04 UTC, Steven Schveighoffer wrote:
> > On 4/23/20 2:18 PM, Stefan Koch wrote:
> >> [...]
> >
> > The question is whether the expanded inner expression is considered a tuple for expansion later or not.
> >
> > alias tuple1 = AliasSeq!(1, 2, 3);
> > alias tuple2 = AliasSeq!(4, 5, 6);
> > pragma(msg, [AliasSeq!(tuple1..., tuple2)...]);
> >
> > If it expands tuple1 first, then expands tuple 2 without re-expanding the result of tuple1..., then it should be:
> >
> > [1, 2, 3, 4, 1, 2, 3, 5, 1, 2, 3, 6]
> >
> > If it expands both tuple1 and tuple2 together, it should be:
> >
> > [1, 4, 2, 5, 3, 6]
> >
> > -Steve
>
> It's the latter.
> you cannot re-expand.
>
I think the former is correct though. And that's a trivial change.
Our existing code will evaluate the latter, but that only happens because I put a special-case for doing that... and I think that special case is wrong. Natural semantics with no special handling is preferred. It allows much more articulate control, and creates more opportunities.
|
April 24, 2020 Re: I dun a DIP, possibly the best DIP ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright Attachments:
| On Fri, Apr 24, 2020 at 8:05 AM Walter Bright via Digitalmars-d < digitalmars-d@puremagic.com> 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!
>
🎉🎉🎉
Huzzah! The suspense is lifted!
|
April 24, 2020 Re: I dun a DIP, possibly the best DIP ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | On Thursday, 23 April 2020 at 20:34:20 UTC, Stefan Koch wrote:
> Because we cannot nest tuples in tuples.
Not yet anyway.
|
April 23, 2020 Re: I dun a DIP, possibly the best DIP ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On 4/22/2020 5:04 AM, Manu wrote: > [...] Ok, I've had a chance to think about it. It's a scathingly brilliant idea! But (there's always a but!) something stuck out at me. Consider arrays: void test() { auto a = [1, 2, 3]; int[3] b = a[]*a[]; // b[0] = a[0]*a[0]; b[1] = a[1]*a[1]; b[2] = a[2]*a[2]; int[3] c = a[]*2; // c[0] = a[0]*2; c[1] = a[1]*2; c[2] = a[2]*2; } These look familiar! D tuples already use array syntax - they can be indexed and sliced. Instead of the ... syntax, just use array syntax! The examples from the DIP: ===================================== --- DIP (Tup*10)... --> ( Tup[0]*10, Tup[1]*10, ... , Tup[$-1]*10 ) --- Array syntax Tup*10 ==================================== --- DIP alias Tup = AliasSeq!(1, 2, 3); int[] myArr; assert([ myArr[Tup + 1]... ] == [ myArr[Tup[0] + 1], myArr[Tup[1] + 1], myArr[Tup[2] + 1] ]); --- Array alias Tup = AliasSeq!(1, 2, 3); int[] myArr; assert([ myArr[Tup + 1] ] == [ myArr[Tup[0] + 1], myArr[Tup[1] + 1], myArr[Tup[2] + 1] ]); =================================== ---DIP alias Values = AliasSeq!(1, 2, 3); alias Types = AliasSeq!(int, short, float); pragma(msg, cast(Types)Values...); ---Array alias Values = AliasSeq!(1, 2, 3); alias Types = AliasSeq!(int, short, float); pragma(msg, cast(Types)Values); ================================= ---DIP alias OnlyTwo = AliasSeq!(10, 20); pragma(msg, (Values + OnlyTwo)...); ---Array alias OnlyTwo = AliasSeq!(10, 20); pragma(msg, Values + OnlyTwo); The idea is simply if we have: t op c where t is a tuple and c is not, the result is: tuple(t[0] op c, t[1] op c, ..., t[length - 1] op c) For: t1 op t2 the result is: tuple(t1[0] op t2[0], t1[1] op t2[1], ..., t1[length - 1] op t2[length - 1]) The AST doesn't have to be walked to make this work, just do it as part of the usual bottom-up semantic processing. The advantage is: 1. no new grammar 2. no new operator precedence rules 3. turn expressions that are currently errors into doing the obvious thing Why does C++ use ... rather than array syntax? Because C++ doesn't have arrays! |
Copyright © 1999-2021 by the D Language Foundation