March 31, 2018 Re: #dbugfix Issue 16486 200$ | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | On Friday, 30 March 2018 at 13:56:45 UTC, Stefan Koch wrote:
> Ah that is an interesting bug which further demonstrates that templates are a tricky thing :)
> Basically you cannot _generally_ proof that one template just forwards to another.
> Therefore you have to create separate types.
> And since you create separate types the alias is not an alias but a separate template.
> Solving this may be possible for special cases but in the general case is infeasible.
If a template is used as a type it should be resolved to a type, no? And template resolves to a type in a straightforward way. Where does it fail? Judging by the error message "cannot deduce function from argument types !()(TestType!int)" it does successfully resolve alias to a type.
|
March 31, 2018 Re: #dbugfix Issue 16486 200$ | ||||
---|---|---|---|---|
| ||||
Posted in reply to jmh530 | On Friday, 30 March 2018 at 15:49:30 UTC, jmh530 wrote:
> On Friday, 30 March 2018 at 15:21:26 UTC, jmh530 wrote:
>> [snip]
>>
>
> Doesn't extend to multiple template parameters that well...
>
> import std.traits : TemplateOf;
>
> struct TestType(T, U) {}
> alias TestAlias(T) = TestType!(T, int);
>
> template testFunction(T, alias U = TemplateOf!(TestAlias!T))
What you're showing here is a somewhat different case. First, you're telling TestAlias to turn into a TestType. Then you ask which template that type is an instance of. That's going to be TestType, every single time. And it being anything else would be a source of great confusion:
auto a = TestType!(string, int)();
auto b = TestAlias!string();
// We expect this to be true:
assert(is(typeof(a) == typeof(b)));
// And I'll be damned if this ain't:
assert(__traits(isSame, TemplateOf!(typeof(a)), TemplateOf!(typeof(b))));
--
Simen
|
March 31, 2018 Re: #dbugfix Issue 16486 200$ | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Saturday, 31 March 2018 at 13:34:18 UTC, Kagamin wrote:
> On Friday, 30 March 2018 at 13:56:45 UTC, Stefan Koch wrote:
>> Ah that is an interesting bug which further demonstrates that templates are a tricky thing :)
>> Basically you cannot _generally_ proof that one template just forwards to another.
>> Therefore you have to create separate types.
>> And since you create separate types the alias is not an alias but a separate template.
>> Solving this may be possible for special cases but in the general case is infeasible.
>
> If a template is used as a type it should be resolved to a type, no? And template resolves to a type in a straightforward way. Where does it fail? Judging by the error message "cannot deduce function from argument types !()(TestType!int)" it does successfully resolve alias to a type.
You're starting in the wrong end - the type cannot yet be considered, since the compiler doesn't know the correct arguments to TestAlias. Given this code:
struct S(T...) {}
alias SS(T...) = S!(T, int);
void foo(T)(SS!T arg) {}
unittest {
foo(SS!string());
}
The error message is "template foo cannot deduce function from argument types !()(S!(string, int)), candidates are: foo(T)(SS!T arg)".
What the compiler needs to do is figure out what T needs to be in order for SS to return the type S!(int, int). SS hasn't resolved to a type yet at that point, because the compiler has no idea which arguments to give it.
These are the steps the compiler does when it evaluates a function call (simplified):
1) Figure out the overload set.
2) Weed out non-matching overloads.
3) Check that exactly one overload matches*.
4) Use that overload.
In step 2, the compiler looks at the types when the overload is a regular function. When it's a function template, it doesn't know the types yet, and IFTI tries to figure it out by a sort of pattern matching. In the case above, it doesn't find a S!(/*something*/) anywhere, and gives up.
If the compiler were to do something other than give up, we would need some algorithm to define what it should try, and in which order. As human beings, with impressive collections of pattern-matching circuits, we can easily see that it should try putting the first template argument into T. Getting to that conclusion is a lot harder for the poor, stupid compiler.
--
Simen
*In the case where multiple overloads are a match, the best fit is chosen. If there's more than one best fit, or there's no match, you get a compile error.
|
March 31, 2018 Re: #dbugfix Issue 16486 200$ | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | On 31.03.2018 18:34, Simen Kjærås wrote:
> On Saturday, 31 March 2018 at 13:34:18 UTC, Kagamin wrote:
>> On Friday, 30 March 2018 at 13:56:45 UTC, Stefan Koch wrote:
>>> Ah that is an interesting bug which further demonstrates that templates are a tricky thing :)
>>> Basically you cannot _generally_ proof that one template just forwards to another.
>>> Therefore you have to create separate types.
>>> And since you create separate types the alias is not an alias but a separate template.
>>> Solving this may be possible for special cases but in the general case is infeasible.
>>
>> If a template is used as a type it should be resolved to a type, no? And template resolves to a type in a straightforward way. Where does it fail? Judging by the error message "cannot deduce function from argument types !()(TestType!int)" it does successfully resolve alias to a type.
>
> You're starting in the wrong end - the type cannot yet be considered, since the compiler doesn't know the correct arguments to TestAlias. Given this code:
>
> struct S(T...) {}
> alias SS(T...) = S!(T, int);
>
> void foo(T)(SS!T arg) {}
>
> unittest {
> foo(SS!string());
> }
>
> The error message is "template foo cannot deduce function from argument types !()(S!(string, int)), candidates are: foo(T)(SS!T arg)".
> ...
>
> If the compiler were to do something other than give up, we would need some algorithm to define what it should try, and in which order.
It should simply run a limited semantic analysis on the function parameters before matching.
void foo(T)(SS!T arg) -> void foo(T)(S!(T, int) arg)
To support Ilya's use case, it suffices to expand unconstrained alias templates.
|
April 20, 2018 Re: #dbugfix Issue 16486 200$ | ||||
---|---|---|---|---|
| ||||
Posted in reply to 9il | On Friday, 30 March 2018 at 06:11:22 UTC, 9il wrote: > [snip] > > They are used in mir-lapack [5]. The bug fix also required for mir (Sparse, CompressedTensor), and for the future Dlang image library. I was experimenting with one of the open methods matrix examples [1] and trying to replace the virtual methods with templates. My example [3] does it statically and with structs so that it could be used with mir. However, the moment you try to make it a little bit more complicated and allow the type of the underlying matrix data to be templated, then it hits up against this issue and you can't rely on aliases any more. I would support a DIP. [1] https://github.com/jll63/openmethods.d/tree/master/examples/matrix/source [2] http://www.di.unipi.it/~nids/docs/templates_vs_inheritance.html [3] https://run.dlang.io/gist/9da210e321af95e1ce373b5a6621e4f8 |
April 20, 2018 Re: #dbugfix Issue 16486 200$ | ||||
---|---|---|---|---|
| ||||
Posted in reply to 9il | On Friday, 30 March 2018 at 06:11:22 UTC, 9il wrote: > [snip] > > They are used in mir-lapack [5]. The bug fix also required for mir (Sparse, CompressedTensor), and for the future Dlang image library. I was experimenting with one of the open methods matrix examples [1] and trying to replace the virtual methods with templates. My example [3] does it statically and with structs so that it could be used with mir. However, the moment you try to make it a little bit more complicated and allow the type of the underlying matrix data to be templated, then it hits up against this issue and you can't rely on aliases any more. I would support a DIP. [1] https://github.com/jll63/openmethods.d/tree/master/examples/matrix/source [2] http://www.di.unipi.it/~nids/docs/templates_vs_inheritance.html [3] https://run.dlang.io/gist/9da210e321af95e1ce373b5a6621e4f8 |
April 20, 2018 Re: #dbugfix Issue 16486 200$ | ||||
---|---|---|---|---|
| ||||
Posted in reply to 9il | On Friday, 30 March 2018 at 06:11:22 UTC, 9il wrote: > [snip] > > They are used in mir-lapack [5]. The bug fix also required for mir (Sparse, CompressedTensor), and for the future Dlang image library. I was experimenting with one of the open methods matrix examples [1] and trying to replace the virtual methods with templates. My example [3] does it statically and with structs so that it could be used with mir. However, the moment you try to make it a little bit more complicated and allow the type of the underlying matrix data to be templated, then it hits up against this issue and you can't rely on aliases any more. I would support a DIP. [1] https://github.com/jll63/openmethods.d/tree/master/examples/matrix/source [2] http://www.di.unipi.it/~nids/docs/templates_vs_inheritance.html [3] https://run.dlang.io/gist/9da210e321af95e1ce373b5a6621e4f8 |
April 20, 2018 Re: #dbugfix Issue 16486 200$ | ||||
---|---|---|---|---|
| ||||
Posted in reply to 9il | On Friday, 30 March 2018 at 06:11:22 UTC, 9il wrote: > [snip] > > They are used in mir-lapack [5]. The bug fix also required for mir (Sparse, CompressedTensor), and for the future Dlang image library. I was experimenting with one of the open methods matrix examples [1] and trying to replace the virtual methods with templates. My example [3] does it statically and with structs so that it could be used with mir. However, the moment you try to make it a little bit more complicated and allow the type of the underlying matrix data to be templated, then it hits up against this issue and you can't rely on aliases any more. I would support a DIP. [1] https://github.com/jll63/openmethods.d/tree/master/examples/matrix/source [2] http://www.di.unipi.it/~nids/docs/templates_vs_inheritance.html [3] https://run.dlang.io/gist/9da210e321af95e1ce373b5a6621e4f8 |
April 20, 2018 Re: #dbugfix Issue 16486 200$ | ||||
---|---|---|---|---|
| ||||
Posted in reply to 9il | On Friday, 30 March 2018 at 06:11:22 UTC, 9il wrote: > [snip] > > They are used in mir-lapack [5]. The bug fix also required for mir (Sparse, CompressedTensor), and for the future Dlang image library. I was experimenting with one of the open methods matrix examples [1] and trying to replace the virtual methods with templates. My example [3] does it statically and with structs so that it could be used with mir. However, the moment you try to make it a little bit more complicated and allow the type of the underlying matrix data to be templated, then it hits up against this issue and you can't rely on aliases any more. I would support a DIP. [1] https://github.com/jll63/openmethods.d/tree/master/examples/matrix/source [2] http://www.di.unipi.it/~nids/docs/templates_vs_inheritance.html [3] https://run.dlang.io/gist/9da210e321af95e1ce373b5a6621e4f8 |
April 20, 2018 Re: #dbugfix Issue 16486 200$ | ||||
---|---|---|---|---|
| ||||
Posted in reply to jmh530 | On Friday, 20 April 2018 at 16:03:40 UTC, jmh530 wrote:
> On Friday, 30 March 2018 at 06:11:22 UTC, 9il wrote:
>> [...]
>
> I was experimenting with one of the open methods matrix examples [1] and trying to replace the virtual methods with templates. My example [3] does it statically and with structs so that it could be used with mir. However, the moment you try to make it a little bit more complicated and allow the type of the underlying matrix data to be templated, then it hits up against this issue and you can't rely on aliases any more.
>
> I would support a DIP.
>
> [1] https://github.com/jll63/openmethods.d/tree/master/examples/matrix/source
>
> [2] http://www.di.unipi.it/~nids/docs/templates_vs_inheritance.html
>
> [3] https://run.dlang.io/gist/9da210e321af95e1ce373b5a6621e4f8
Sorry, the stupid thing keeps telling me it's down for maintenance.
|
Copyright © 1999-2021 by the D Language Foundation