I wish all qualifiers were revisited with an eye for simplification

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Fri Aug 14 13:45:56 UTC 2020


On 8/4/20 12:57 PM, Timon Gehr wrote:
>> * Every time "inout" comes within a radius of a mile of what I'm 
>> doing, it starts to stink like a skunk. I wish I could get a 
>> restraining order. I can't instantiate "inout" variables, so writing 
>> any tests or constraints becomes an advanced matter of defining 
>> functions and crap.
> 
> I have never understood the `(inout int){ T.init; }` idiom. Just use `(T 
> value){ value; }`.
> 
>> I get frustrated, I protest to this forum, and immediately a cabal is 
>> raised under Timon's leadership. The cabal convinces me that inout is 
>> actually great and that I'm an idiot. I do get convinced, which is 
>> more of a proof that Timon is very good, than a testament to the 
>> conviviality of inout. Then I leave and get back to my code, and it 
>> stinks of inout again. And I hate it and myself for having to deal 
>> with it.
>> ...
> 
> I am sure you are sincere, but I still think this is a 
> misrepresentation. I don't think I ever claimed that `inout` is great. I 
> merely understand what `inout` is supposed to be, but it comes way 
> short. See all of the issues I have opened that show that type checking 
> for `inout` is broken. When I tried to document inout properly in 2018 I 
> found multiple new type system holes, I think they are open to this day.

Well for what it's worth I have a simple question: how can I assess in 
druntime if a type T is copyable? I add the informal requirement that 
it's a simple query so it should be served with a proportionally simple 
answer.

My initial take:

static if (is(typeof((T x) { T y = x; }))) { ... }

i.e. a lambda can be created that takes a T and creates a copy of it. 
Beautiful.

This test, however, passes for inout types. And inout types cannot be 
considered really copyable, because they cannot be used in many places 
where one would expect to use a copyable type. To wit, a variety of 
unittests will fail (such as structs with copyable members), all 
protesting to the attempt of classifying inout types as copyable.

Second attempt:

static if (is(typeof((T x) { T y = x; })) && !is(T == inout U, U) { ... }

So a type is copyable as before, just let's special case inout for 
exclusion.

This already gets my diaper in a bunch because I need to special case a 
type of which utility I already am suspicious. And it's not only here - 
it's many, many similar places.

Also, this also does NOT work because inout(const(int)) passes the test. 
This could probably be classified as a bug in the language or its compiler.

So now I'm looking at things like importing "core.lifetime : emplace" 
and see if that compiles. Because the very complex implementation of 
emplace uses a complex mechanism to handle inout.

I could be convinced that this awful complexity is justified given the 
choices made in the definition of this or that, but it would be more 
difficult to convince ourselves this is good programming language 
design. Simple questions should have simple answers.


More information about the Digitalmars-d mailing list