Overloading based on attributes - is it a good idea?

Jonathan Marler johnnymarler at gmail.com
Tue May 28 17:35:04 UTC 2019


On Tuesday, 28 May 2019 at 17:27:08 UTC, Walter Bright wrote:
> On 5/28/2019 9:08 AM, Andrei Alexandrescu wrote:
>> int fun(int) pure;
>> int fun(int);
>> 
>> pure int gun(int x)
>> {
>>     return fun(x);
>> }
>> 
>> This doesn't work, but on the face of it it's not ambiguous - 
>> the second overload of fun() would not compile anyway.
>> 
>> I was wondering whether allowing overloading on attributes in 
>> general would be a good idea. I suspect templates and 
>> attribute deduction make that difficult.
>
> More than difficult. I suspect it's impossible in the general 
> case. D does inference of types and attributes from the bottom 
> up, but this would be bottom up and top down. It's easy to know 
> what to do for trivial cases, but for multiple levels and 
> choices, that's graph theory that would be very complex to find 
> a unique solution, and if a unique solution cannot be found, 
> imagine the problems with informing the user just why.
>
> It's like overloading based on return value:
>
>   long fun(int);
>   int fun(int);
>
>   int gun(int x)
>   {
>      return fun(x);
>   }
>
> It's ambiguous even though the first overload of fun() would 
> give an error.
>
> Another consideration:
>
>     class A { int fun() pure; }
>     class B : A { overload int fun(); }
>
> Because of covariance/contravariance, B.fun doesn't need to 
> have the pure attribute added, the pureness is inherited from 
> A.fun.

At first glance this does seem correct.

After reading Walter's response here, another thought came to 
mind that instead of attribute overloading, a template with 
static-if could also be used.

void foo()()
{
     static if (__traits(gcAllowedHere))
     {
         // the GC implementation
     }
     else
     {
         // the nogc implementation
     }
}

void bar1() @nogc
{
     foo(); // calls the nogc implementation
}
void bar2()
{
     foo(); // calls the GC implementation
}

And the same thing could be applied for purity with something 
like __traits(inpureAllowedHere).

Although, I think we could use existing traits for these, with an 
"isCompiles" or something.


More information about the Digitalmars-d mailing list