Getting the overload set of a template
Alex
sascha.orlov at gmail.com
Mon Apr 23 08:07:52 UTC 2018
On Monday, 23 April 2018 at 07:49:39 UTC, Simen Kjærås wrote:
> On Monday, 23 April 2018 at 04:58:38 UTC, Alex wrote:
>> On Monday, 23 April 2018 at 00:26:23 UTC, Simen Kjærås wrote:
>>> There is a limited set of lowerings, and they are defined in
>>> the language, not in user code. They include operator
>>> overloading (where `a op b` is translated to
>>> `a.opBinary!op(b)`), foreach over ranges (where `foreach(e;
>>> range) { }` becomes `for (auto e = range.front;
>>> !range.empty(); range.popFront()) { }`), string switching
>>> (which is forwarded to a template in druntime), and more that
>>> I can't recall right now. This is compiler magic meant to
>>> make implementating new features and reasoning about existing
>>> features, easier. They are briefly described in the article
>>> you linked, but I agree it offers limited insight. I've not
>>> found any other great sources of information about it, sadly.
>>
>> This is not true, in my opinion.
>> As an example, Walter gives the rewrite of a while-loop and a
>> foreach-loop into a for-loop, stating that by the ability to
>> do this, the for-loop is more basic than both of the former.
>>
>> So, in my mind, every action of rewriting of something into
>> something else is "lowering". And if you can do this (of
>> course, maintaining the full semantic equivalence), available
>> actions have to remain the same.
>
> That's not the definition of lowering used elsewhere, and so
> will lead to confusion and misunderstanding. I would strongly
> suggest you rethink your definition of lowering.
>
There is no official definition. That's because some natural
rewrite rules are implied, which are very general, I assume...
>
>> Said this, I'm not against the new getOverloads. On the
>> contrary, I find the feature cool. But if it is present, it
>> has to yield the same results for foo1 and foo2, just like the
>> pragmas.
>
> In the general case, this is impossible. Even just limiting
> ourselves to simple usages of static if it gets unwieldy. This
> template is from Phobos (all unnecessary code removed). It has
> 224 different possible combinations of features:
>
> private struct _Cache(R, bool bidir)
> {
> static if (bidir) {}
> else {}
> static if (isInfinite!R) {}
> else {}
> static if (hasLength!R) {}
> version(assert) {}
> static if (isForwardRange!R) {}
> static if (hasSlicing!R) {
> static if (hasEndSlicing) {}
> static if (!isInfinite!R) {}
> else static if (hasEndSlicing) {}
> }
> }
>
> And that's before we even instantiate any templates that this
> template references - any templates used inside _Cache could
> increase the number of combinations.
>
> But wait, there's more! How many does this have?
>
> struct Bar(string s) {
> mixin(s);
> }
>
> If that's just one overload because of the impossibility of
> generating the options, what if we introduce a single static if
> inside it? Is that still one, or is it two? Do we count the
> possibilities introduced by a template mixin, but not by a
> string mixin? What if the template mixin comes from a template
> argument?
>
> Sorry if I come off as very dismissive right now - I kind of
> like the idea, but it seems impossible in practice.
>
>
>> I'm not sure about the procedure... should I post this as a
>> question to the GitHub, so it can be discussed? pull 2351 or
>> 8195?
>
> What you are suggesting would be a fundamental change in the
> language, and should be discussed in the digitalmars.D forum.
> Either PR is not the right place to discuss it. If there's any
> interest, you will have to write a DIP for how the change will
> work.
>
> --
> Simen
My point, is that if it is impossible to catch all cases of
template rewriting (which I'm advocating from the beginning)
getOverloads should not be extended to templates, as this would
be a fundamental change in the language.
More information about the Digitalmars-d-learn
mailing list