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