Feature request: __traits(canInstantiate), like __traits(compiles) but without suppressing syntax errors

Steven Schveighoffer schveiguy at gmail.com
Fri Jan 17 16:01:29 UTC 2020


On 1/17/20 10:34 AM, Petar Kirov [ZombineDev] wrote:
> On Friday, 17 January 2020 at 14:57:27 UTC, Steven Schveighoffer wrote:
>> On 1/17/20 12:54 AM, FeepingCreature wrote:
>>>
>>> Would be nice, but would be a hard spec change. This is the sort of 
>>> thing that D should have been doing from the beginning, but we may be 
>>> too far in now for __traits(compiles) to be changed to do this. 
>>> However, this is the behavior I would ask for for 
>>> __traits(canInstantiateWith).
>>>
>>
>> Just to point you at my previous thread on this: 
>> https://forum.dlang.org/post/q1jequ$r63$1@digitalmars.com
>>
>> I think more tools for diagnosing why something doesn't happen would 
>> be good, but the request of "tell me if I was stupid" is I think 
>> impossible for the compiler to figure out.
>>
> 
> In other languages, such as C#, TypeScript and Rust, generic functions 
> can use only properties of generic types iff such properties were 
> required in the function generic type constraints. AFAIK Nim's Concepts 
> [1] are also moving in that direction, even though their current way is 
> more similar to D (I chatted with one of their core developers, a couple 
> of months ago at a conference, but I may be misremembering some details).

Yes, concepts would be useful, but also would be limited for how D does 
duck typing. D's constraints are very much like concepts, but without 
having to declare everything up front for use in the function.

But it wouldn't work for UFCS either I don't think.

However, the real problem is things like typos that cause the function 
not to compile for reasons other than the intended failures.

For example:

T foo(T)(T x)
{
    return X + 5; // typo on parameter name
}

This will NEVER compile, because X will never exist. The intention was 
for it to compile with types that support addition to integers (i.e. 
it's EXPECTED to fail for strings), but instead it fails for all types. 
The result is that your code selects some other path when you don't want 
it to. Sometimes this just means it works but is slower, which is even 
harder to figure out.

But it's hard for the compiler to deduce intention from such typos. It 
would be great if the compiler could figure out this type of error, but 
I don't think it can.

The only "fix" really is to judiciously unittest with the calls you 
expect to work. And that generally doesn't happen (we are a lazy bunch!).

Perhaps, an "expected" clause or something to ensure it compiles for the 
expected types like: expected(T == int), which wouldn't unittest 
anything, just make sure it can compile for something that is expected.

-Steve


More information about the Digitalmars-d mailing list