Getting the overload set of a template

Simen Kjærås simen.kjaras at gmail.com
Mon Apr 23 14:22:13 UTC 2018


On Monday, 23 April 2018 at 13:32:49 UTC, Alex wrote:
> On Monday, 23 April 2018 at 10:57:59 UTC, Simen Kjærås wrote:
>>> There is no official definition. That's because some natural 
>>> rewrite rules are implied, which are very general, I assume...
>>
>> How official do you want it to be? That's the only definition 
>> in common use by others in the context of compilers.
>
> Stating the existence of rewriting rules is a complex thing. 
> They is no place in the docu (which I could find until now) 
> where they are defined. Therefore, I rely on something which is 
> common.
> https://en.wikipedia.org/wiki/Natural_transformation
>
> We can discuss, whether a template is a functor, but I think 
> this would go beyond the scope of this thread.
>
> You mentioned a limited set of lowerings, defined by the 
> language. Where can I find them?  I'm very interested in that.

As with all things D, the only real spec is the compiler source 
code. :p :(

Again, lowerings are a compiler technique where one syntax is 
rewritten into a different syntax. They are hard-coded into the 
language (and optionally in the compiler - if a compiler writer 
finds an opportunity to use lowerings to simplify or otherwise 
improve the compiler without such a lowering being defined in the 
language, and with the same behavior, all the more power to 
him/her). Only these things are called lowerings. Template 
instantiations are not lowerings. Function inlining is not a 
lowering. Constant folding is not a lowering.

As far as I know, there is no canonical list of lowerings 
anywhere. :(


>> There is no template rewriting taking place in the language 
>> today - that seems to be a feature you are arguing for.
>
> Semantic rewriting is not something which one can take control 
> of. Either you have semantically equal constructs or not.

And we don't, so don't worry about it. :p


>> getOverloads should return the overloads of a template as they 
>> are defined in the language today.
>
> This is the topic of discussion. I argue, that getOverloads can 
> (so far) act only on functions, because only there the term 
> overload is well defined. I see, that it could be defined on 
> templates too, but not in the way you do.

But why not? Consider this case:

template foo() {}
template foo(int n) {}

In the compiler, this results in two `TemplateDeclaration`s being 
instantiated. Since they share the 'foo' name, they are 
considered an overload set by the compiler. The specific overload 
is chosen by overload resolution. They are iterated by the 
function overloadApply. The term template overload is also widely 
used in C++, from which D has inherited much.

Simply put, template overloads are clearly defined, everyone 
knows what they are, and many of us want a way to iterate over 
them, choose a specific overload in a different template, and 
just plain do sensible work with them.

If not how I define it, then how would the term 'overload' be 
defined for templates? We've established that creating a new 
overload for every potential static if breaks down in the 
presence of mixins, and is questionable in their absence. What 
I'm reading from your post is simply 'the current way is wrong, 
and there exists a better way'. If that's true, I'd love to hear 
what the better way is, but I fail to see that you've described 
it.


>> Template overloads are mentioned in the D spec[0], and are 
>> clearly a real thing that it's useful to be able to manipulate.
>
> Yes. But using the term "overload" for templates with the same 
> name does not justify to wrongly apply existing features to 
> more abstract objects. This is what you try to do by using 
> getOverloads with templates.

It's a term with decades of history in C++, and has been used in 
D since its inception. Even C# mentions overloads for generic 
functions or types with different constraints.


>> You seem to be arguing against a feature on the basis that if 
>> the language were significantly different from what it is, the 
>> feature would be confusing. The language isn't that way, so 
>> the feature isn't confusing in that way.
>
> Well, as we both saw with the pragma output, the language is 
> exactly that way I'm describing it.

Then, once more, I must have misunderstood your description. 
Proving that two templates are equivalent is in general 
impossible, since any amount of wasted computation could be 
performed before the end result is returned, and inputs must be 
tested exhaustively for the proof to be valid. The fact that two 
templates give the same result in one special case does not mean 
that they are equivalent in the general case, and the compiler 
needs to care about the general case.


> New getOverload functionality would introduce a new constraint 
> in comparison to the current state.

The new functionality does not in any way stop you from using 
getOverloads in exactly the way it's been used before. In 
addition to that, you may pass an additional argument to it to 
get template overloads (actually, every symbol by that name in 
the specified aggregate). How is this in any way a constraint?


>> Having getOverloads return template overloads solves a real 
>> issue right now, and would be useful even if your suggested 
>> change were implemented (though the behavior would be slightly 
>> different).
>
> What I'm saying is: it would be useful only then, if my 
> suggested change were implemented. Otherwise, it is a new 
> constraint and not a feature.

That's just plain false. I have use cases for the feature right 
now, so it's provably useful. Can you describe in which ways your 
suggested change is superior, rather than simply asserting that 
it is?

--
   Simen


More information about the Digitalmars-d-learn mailing list