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 13:56:47 UTC, Stefan Koch wrote:
> On Thursday, 23 April 2020 at 13:48:54 UTC, Steven Schveighoffer wrote:
>>
>> These kinds of puzzles are fun ;)
>>
>
> yeah no.
>
> It's not fun if you have to make sure the rewrite is what people expect.
>
> Foo!(AliasSeq(1,2)...)... will expand to Compiler_Tuple(Foo!(1), Foo!(2))
to make the point clearer:
----
template AliasSeq(seq...)
{
alias AliasSeq = seq;
}
template Foo(alias X)
{
struct S { typeof(X) v = X; }
enum Foo = S();
}
----
pragma(msg, Foo!(AliasSeq!(1, 2))...);
outputs:
----
tuple(S(1), S(2))
----
|
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 12:00 AM Stefan Koch via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
> On Thursday, 23 April 2020 at 13:48:54 UTC, Steven Schveighoffer wrote:
> >
> > These kinds of puzzles are fun ;)
> >
>
> yeah no.
>
> It's not fun if you have to make sure the rewrite is what people expect.
>
> Foo!(AliasSeq(1,2)...)... will expand to Compiler_Tuple(Foo!(1),
> Foo!(2))
I don't think that's true according to the current implementation. It will try and expand the expression `AliasSeq!(1, 2)`. there are no tuples in that expression, and no expansion will take place.
|
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 13:48:54 UTC, Steven Schveighoffer wrote:
>
> No, Foo!(AliasSeq!(1, 2)...)... is equivalent to Foo!(AliasSeq!(1, 2))
>
In the current implementation it's a parser error.
|
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 14:06:03 UTC, Stefan Koch wrote:
> On Thursday, 23 April 2020 at 13:48:54 UTC, Steven Schveighoffer wrote:
>>
>> No, Foo!(AliasSeq!(1, 2)...)... is equivalent to Foo!(AliasSeq!(1, 2))
>>
> In the current implementation it's a parser error.
I would assume that both
alias Numbers = AliasSeq!(1, 2);
Foo!(Numbers...)
and
Foo!(AliasSeq!(1, 2)...)
should do the same, no?
I think of something like (expr + Tuple)... as a simple map!(Item => expr + Item) - however the compiler automatically finding the Tuple and the scope of the expression really bugs me the most here because it feels so subjective.
Wouldn't some syntax like Tuple->{Tuple + 4} be clearer and easier to parse for both DMD and static analysis tools? To keep it as simple as possible it would just reuse the name of the tuple as item name, but then it's basically a fancy, clear map syntax, where you exactly control the tuple that's being expanded and avoid any issues with nested tuples in the expression tree.
|
April 24, 2020 Re: I dun a DIP, possibly the best DIP ever | ||||
---|---|---|---|---|
| ||||
Attachments:
| On Fri, Apr 24, 2020 at 12:05 AM Manu <turkeyman@gmail.com> wrote:
> On Fri, Apr 24, 2020 at 12:00 AM Stefan Koch via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
>
>> On Thursday, 23 April 2020 at 13:48:54 UTC, Steven Schveighoffer wrote:
>> >
>> > These kinds of puzzles are fun ;)
>> >
>>
>> yeah no.
>>
>> It's not fun if you have to make sure the rewrite is what people expect.
>>
>> Foo!(AliasSeq(1,2)...)... will expand to Compiler_Tuple(Foo!(1),
>> Foo!(2))
>
>
> I don't think that's true according to the current implementation. It will try and expand the expression `AliasSeq!(1, 2)`. there are no tuples in that expression, and no expansion will take place.
>
Oh no, I'm wrong. I think we have a bug there...
I don't think that should work that way, and I can see why it does; it's
because our code sees the template argument as a tuple identifier to
expand, and not as the expression being supplied.
I think semantic is being called eagerly somewhere that it shouldn't...
|
April 24, 2020 Re: I dun a DIP, possibly the best DIP ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to WebFreak001 Attachments:
| On Fri, Apr 24, 2020 at 12:20 AM WebFreak001 via Digitalmars-d < digitalmars-d@puremagic.com> wrote: > On Thursday, 23 April 2020 at 14:06:03 UTC, Stefan Koch wrote: > > On Thursday, 23 April 2020 at 13:48:54 UTC, Steven Schveighoffer wrote: > >> > >> No, Foo!(AliasSeq!(1, 2)...)... is equivalent to > >> Foo!(AliasSeq!(1, 2)) > >> > > In the current implementation it's a parser error. > > I would assume that both > > alias Numbers = AliasSeq!(1, 2); > Foo!(Numbers...) > > and > > Foo!(AliasSeq!(1, 2)...) > > should do the same, no? > Well, they both do nothing. You probably mean Foo!(Numbers)... Foo!(AliasSeq!(1, 2))... But even then, no; there's no tuple to expand in that second statement. What there is, is a template instantiation, and it _resolves_ to a tuple, but the current spec doesn't tunnel into post-evaluation tuples like that. If it did, I think it would be very unwieldy. Expansion occurs before expression evaluation... and it must, because the expression to evaluate is the result of the expansion. I think of something like (expr + Tuple)... as a simple map!(Item > => expr + Item) - however the compiler automatically finding the Tuple and the scope of the expression really bugs me the most here because it feels so subjective. > > Wouldn't some syntax like Tuple->{Tuple + 4} be clearer and easier to parse for both DMD and static analysis tools? To keep it as simple as possible it would just reuse the name of the tuple as item name, but then it's basically a fancy, clear map syntax, where you exactly control the tuple that's being expanded and avoid any issues with nested tuples in the expression tree. > What you're describing is something that starts to look like type functions, or a type lambda specifically. I'm all for type functions, but that's not what this DIP is. I'm in full support of a type functions DIP though! > clearer and easier to parse for both DMD This has been surprisingly easy to implement. It's trivial to parse, and semantic has been totally self-contained. The complexity we've discovered is pretty much 100% concerning the moment that expansion is applied vs semantic being run. Expansion must apply before the expression evaluation, because the expansion affects the expression to be evaluated. |
April 23, 2020 Re: I dun a DIP, possibly the best DIP ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | On Thursday, 23 April 2020 at 12:43:59 UTC, Simen Kjærås wrote:
> On Wednesday, 22 April 2020 at 12:04:30 UTC, Manu wrote:
>> This DIP single-handedly fixes compile-time issues in programs I've written by reducing template instantiations by near-100%, in particular, the expensive ones; recursive instantiations, usually implementing some form of static map.
>>
>> We should have done this a long time ago.
>
> This is beautiful and awesome (syntax and all).
>
> I was wondering if there's any way to to do a cross product with this, like fun(Xs, Ys)... expand to fun(Xs[0], Ys[0]), fun(Xs[0], Ys[1]), fun(Xs[1], Ys[0]), fun(Xs[1], Ys[1]), but that might very well be rare enough to not warrant special consideration.
>
I think ...-Expressions should first expand nested ...-Expressions (or equivalently explicitly ignore nested ...-Expressions). Then the cross-product can be expressed as:
template crossHelper(F, X, Y...) {
alias crossHelper = F(X, Y)...;
}
crossHelper!(S, X, Y...)...
=> S!(X[0], Y[0]), S!(X[1], Y[0]), ..., S!(X[n-1], X[m-1])
because the nested expression Y... is expanded first resulting in crossHelper!(S, X, Y[0]), ..., crossHelper!(S, X, Y[m-1]) which then has the X expanded.
|
April 23, 2020 Re: I dun a DIP, possibly the best DIP ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mafi | On Thursday, 23 April 2020 at 15:06:51 UTC, Mafi wrote:
> On Thursday, 23 April 2020 at 12:43:59 UTC, Simen Kjærås wrote:
>>[...]
>
> I think ...-Expressions should first expand nested ...-Expressions (or equivalently explicitly ignore nested ...-Expressions). Then the cross-product can be expressed as:
>
> template crossHelper(F, X, Y...) {
> alias crossHelper = F(X, Y)...;
> }
>
> crossHelper!(S, X, Y...)...
>
> => S!(X[0], Y[0]), S!(X[1], Y[0]), ..., S!(X[n-1], X[m-1])
>
> because the nested expression Y... is expanded first resulting in crossHelper!(S, X, Y[0]), ..., crossHelper!(S, X, Y[m-1]) which then has the X expanded.
that won't work.
F is a type parameter in crossHelper.
|
April 23, 2020 Re: I dun a DIP, possibly the best DIP ever | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | I like this idea, but I don't like the syntax. pragma(msg, (Values + OnlyTwo)...); alias staticMap(alias F, T...) = F!T...; The immediate impression I have reading this code is that the `...` postfix operator is modifying the result of `Values + OnlyTwo` or `F!T`, but this isn't the case. This syntax decision would make D less accessible to new people and would make code take just that little bit more effort to read even for people who know the syntax. I would suggest that something should be written postfixing or prefixing the alias sequence itself, so that it is more clear that the operation is changing the nature of that sequence and how it is operated upon, rather than acting upon the result of an operation involving that sequence. One example to illustrate what I mean by moving the operator: pragma(msg, (Values[...] + OnlyTwo[...])); alias staticMap(alias F, T...) = F[...]!T; I think something other than `[...]` or `...` would also be fine, it's the position specifically that I want to make a point about. |
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 15:11:16 UTC, Stefan Koch wrote:
> On Thursday, 23 April 2020 at 15:06:51 UTC, Mafi wrote:
>> On Thursday, 23 April 2020 at 12:43:59 UTC, Simen Kjærås wrote:
>>>[...]
>>
>> I think ...-Expressions should first expand nested ...-Expressions (or equivalently explicitly ignore nested ...-Expressions). Then the cross-product can be expressed as:
>>
>> template crossHelper(F, X, Y...) {
>> alias crossHelper = F(X, Y)...;
>> }
>>
>> crossHelper!(S, X, Y...)...
>>
>> => S!(X[0], Y[0]), S!(X[1], Y[0]), ..., S!(X[n-1], X[m-1])
>>
>> because the nested expression Y... is expanded first resulting in crossHelper!(S, X, Y[0]), ..., crossHelper!(S, X, Y[m-1]) which then has the X expanded.
>
> that won't work.
> F is a type parameter in crossHelper.
Well, then what about:
template crossHelper(alias F, X, Y...) {
alias crossHelper = F!(X, Y)...;
}
crossHelper!(S, X, Y...)...
|
Copyright © 1999-2021 by the D Language Foundation