Asking for the opinion of DMD developers

Elie Morisse syniurge at gmail.com
Sun Oct 13 15:06:11 UTC 2019


On Sunday, 13 October 2019 at 10:51:52 UTC, Stefanos Baziotis 
wrote:
> Hello everyone,
>
> I'm the author of DIP 1023 [1], [2].
>
> I'll try to keep this short to save you time by only mentioning 
> the important
> parts (and those are a lot anyway).
> Feel free to ask me to elaborate on anything that it's not 
> clear.
>
> So, first of all, D can't cope with alias templates used as 
> function
> parameters (in template functions). For example:
>
> struct TypeTemplate(T) {}
> alias AliasTemplate(T) = TypeTemplate!T;
> void functionTemplate(T)(AliasTemplate!T arg) {}
>
> void main()
> {
>     AliasTemplate!int inst;
>     functionTemplate(inst); /* "cannot deduce function from 
> argument types !()(TypeTemplate!int)" */
> }
>
> DIP 1023 was introduced because the reasoning was that this is 
> not simply
> a bug and the feature was in fact, under-specified.
> That is, a bug is when we have the form "When I do X, Z should 
> happen" but
> it doesn't. "Under-specified" means that "When I do X, it's not 
> even clear
> that Z should happen in the first place".
> So, this is where the compiler writer requests a specification 
> addition.
>
> My position is that while I believe that Alias Templates are in 
> general
> under-specified in D, adding any more specification won't help
> DMD writers _in this specific issue_.
>
> Let me elaborate: Let's say that we do have a good enough 
> specification,
> like C++'s.
>
> With the help of Nicholas Wilson who asked on reddit, I was 
> redirected
> to the C++ standard [3] in the sections 17.6.7 Alias Templates
> and 17.5 Type Equivalence.
>
> I think having such a specification won't help anyone here.
> To be even more specific, as far as I can understand,
> the issue at hand is handled in the C++ standard with 3 
> sentences (point 2,
> section 17.6.7):
>
> "When a template-id refers to the specialization of an alias 
> template, it is equivalent to the associated type obtained by 
> substitution of its template-arguments for the 
> template-parameters in the type-id of the alias
> template".
>
> And this something that we already know, yet can't solve the 
> issue.
>
> What's your opinion on this ?
>
> Btw, please consider that this is not my area of expertise. :)
>
> Best regards,
> Stefanos Baziotis
>
> [1] https://github.com/dlang/DIPs/pull/176
> [2] 
> https://forum.dlang.org/post/dnyqxmgdazczwmmvayjx@forum.dlang.org
> [3] 
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf

This is because DMD's current implementation of template argument 
deduction isn't advanced enough to cover this case, but it could 
be improved to cover it.

In your example, in "functionTemplate(inst);" inst has its type 
resolved to TypeTemplate!T and DMD's argument deduction tries 
matching the identifier "TypeTemplate" to the identifier 
"AliasTemplate", which fails. The argument deduction function in 
DMD doesn't know/check that AliasTemplate!T would actually 
resolve to TypeTemplate!T.

Regarding C++, C++ template argument deduction is more 
"sophisticated" but also has its limits, maybe to keep the 
complexity of the implementation at an acceptable level.
An example of C++ template function that doesn't work with the 
rules of C++ template argument deduction is 
std::forward<T>(std::remove_reference_t<T>& t) (see 
https://en.cppreference.com/w/cpp/utility/forward), C++ compilers 
cannot deduce T by matching the argument type to 
std::remove_reference<T>. Thus std::forward can only be used with 
an explicit template argument.

The C++ equivalent of your example does work, but alias templates 
are different in C++ and D. In C++ they only alias types, while 
in D there is no concept of alias template, your AliasTemplate 
may have one or more overloads that instantiate a variable or 
some other kind of symbol completely unrelated to aliases.
So C++ has it easier and the paragraph you quoted from the spec 
makes argument deduction possible by first substituting the 
function parameter by a "dummy instantiation of 
AliasTemplate<T>". A similar solution wouldn't be easy to 
implement in DMD for the aforementioned reasons, but it may be 
do-able.

IMHO if not done yet you should submit a bugzilla issue with your 
example and perhaps dive into DMD's code and try figuring out a 
solution.


More information about the Digitalmars-d mailing list