Persistent list

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Mon Nov 16 18:41:29 PST 2015


On 11/16/15 9:00 PM, Meta wrote:
> On Tuesday, 17 November 2015 at 01:49:05 UTC, Steven Schveighoffer wrote:
>> I think it's quite clear that inout in its current form is a point of
>> huge confusion. I want to work to fix this perception (and fix the
>> broken corners of the implementation).
>>
>> What I would ask is for those who at the moment dislike it keep an
>> open mind, and hold back on your pitchforks. I need to prepare a
>> suitable defense, and it's difficult to shake off the "confusing and
>> complex" albatross without having sufficient time to create something
>> that is easy to understand/explain for something that is conceptually
>> simple, but requires a complex proof.
>>
>> What I am afraid of is that someone makes a decision that something is
>> bad, and by the time a good defense, or workable proposal is mounted,
>> the answer is "we already discussed that, it's bad. Let's move on."
>>
>> At least with this, we have a feature that is part of the language, so
>> is unlikely to go away. But I'd hate to see a mob of PR requests that
>> remove inout from all of phobos/druntime before I can counter this.
>>
>> I think inout is worth saving, it needs a few tweaks and a good
>> explanation.
>>
>
> Regarding my question on StackOverflow, I understand that I had an
> inaccurate picture of how inout works, which was causing my problem.
> These are also problems with const and immutable to a degree.

I can understand the confusion.

However, here is the truth: you only need to define opEquals for const 
or mutable. You don't need both (if your wrapped type defines both, then 
the const one can be called in both cases), and you don't need an inout 
version. Here is why: inout is simply *equivalent to const* (but without 
the implicit casting) when there is no inout on the return type. 
Originally this was flagged as an error, but because of templates and 
IFTI, it made writing template functions much harder.

But here is a working system that has no inout:

struct Wrapper(T)
{
     T t;

     static if(is(typeof(const(T).init == const(T).init)))
     {
         bool opEquals(const(Wrapper) other) const
         {
             return t == other.t;
         }
         bool opEquals(const(T) val) const
         {
             return t == val;
         }
     }
     else
     {
         bool opEquals(Wrapper other)
         {
             return t == other.t;
         }
         bool opEquals(T val)
         {
             return t == val;
         }
     }
}

struct Test
{
     bool opEquals(Test t)
     {
         return true;
     }
}

struct Test2
{
     bool opEquals(inout(Test2) t) inout
     {
         return true;
     }
}

struct Test3
{
     bool opEquals(const(Test3) t) const
     {
         return true;
     }
}

void foo(T)()
{
     Wrapper!T a, b;
     assert(a == b);
     assert(a == T());
}

void main()
{
     foo!Test();
     foo!Test2();
     foo!Test3();
}

This doesn't solve the case that has only a mutable and immutable 
opEquals, and no const version, but you get the idea.

> However,
> inout is like a fourth qualifier that you have to deal with that is
> separate from const and immutable, due to how it currently works. In
> that light, I still don't think it pulls its weight. What user will have
> the presence of mind to define their Foobar type with an
> inout/const/immutable toString function? Almost none, and so
> Nullable!Foobar.opEquals cannot be inout.

In almost all cases I've come across, inout isn't another thing that 
needs handling. It's simply an alternative to const (when applicable). 
In cases where it is applicable, you write MUCH LESS code. Where it 
breaks down is composition (i.e. creating a type with an inout member) 
and nested functions.

> I first encountered this
> problem trying to get Nullable.toString to work with inout, and
> couldn't. That's my main gripe with inout.

This may have hit one of the warts of inout.

-Steve


More information about the Digitalmars-d mailing list