Thread overview
inout after function
Nov 25, 2017
Dave Jones
Nov 25, 2017
Ali Çehreli
Nov 26, 2017
Dave Jones
Nov 26, 2017
Adam D. Ruppe
Nov 26, 2017
Dave Jones
Nov 25, 2017
Adam D. Ruppe
Nov 26, 2017
Guillaume Piolat
November 25, 2017
What does the "inout" after front() do here...


@property ref inout(T) front() inout
{
    assert(_data.refCountedStore.isInitialized);
    return _data._payload[0];
}

Cant seem to find an explanation in the docs or forums :(
November 25, 2017
On 11/25/2017 01:51 PM, Dave Jones wrote:
> What does the "inout" after front() do here...
>
>
> @property ref inout(T) front() inout
> {
>      assert(_data.refCountedStore.isInitialized);
>      return _data._payload[0];
> }
>
> Cant seem to find an explanation in the docs or forums :(

It's for member functions. Without it, and if you needed, you would have to write separate functions for mutable, const, and immutable objects of that type.

For example, the following function works for all three qualifications. It won't compile if you remove that inout:

struct S {
    int i;

    @property ref inout(int) front() inout {
        return i;
    }
}

void main() {
    auto m = S(1);
    auto c = const(S)(2);
    static assert(is(typeof(m.front) == int));
    static assert(is(typeof(c.front) == const(int)));
}

Ali
November 25, 2017
On Saturday, 25 November 2017 at 21:51:41 UTC, Dave Jones wrote:
> What does the "inout" after front() do here...

Applies the `inout` modifier to the hidden `this` variable inside the function.

https://dlang.org/spec/function.html#inout-functions

It basically makes it const inside the function, but on the outside, it matches whatever the constness was of the object it is called on.
November 26, 2017
On Saturday, 25 November 2017 at 21:59:54 UTC, Ali Çehreli wrote:
> On 11/25/2017 01:51 PM, Dave Jones wrote:
> > What does the "inout" after front() do here...
> >
> >
> > @property ref inout(T) front() inout
> > {
> >      assert(_data.refCountedStore.isInitialized);
> >      return _data._payload[0];
> > }
> >
> > Cant seem to find an explanation in the docs or forums :(
>
> It's for member functions. Without it, and if you needed, you would have to write separate functions for mutable, const, and immutable objects of that type.
>
> For example, the following function works for all three qualifications. It won't compile if you remove that inout:
>
> struct S {
>     int i;
>
>     @property ref inout(int) front() inout {
>         return i;
>     }
> }
>
> void main() {
>     auto m = S(1);
>     auto c = const(S)(2);
>     static assert(is(typeof(m.front) == int));
>     static assert(is(typeof(c.front) == const(int)));
> }
>
> Ali

So it makes it a const/immutable/mutable method depending on whether the instance it is called on is const/immutable/mutable?

So

>     @property ref inout(int) front() inout {
>         return i++;
>     }

Would fail if you called it on an immutable instance of S.



November 26, 2017
On Sunday, 26 November 2017 at 01:35:01 UTC, Dave Jones wrote:
> So it makes it a const/immutable/mutable method depending on whether the instance it is called on is const/immutable/mutable?

On the outside, yes.

> So
>
>>     @property ref inout(int) front() inout {
>>         return i++;
>>     }
>
> Would fail if you called it on an immutable instance of S.

That wouldn't compile in any case: on the inside of the function, inout == const (this is the only way the one function can be used for all three). The inout propagation is just seen at the call site.
November 26, 2017
On Sunday, 26 November 2017 at 04:51:08 UTC, Adam D. Ruppe wrote:
> On Sunday, 26 November 2017 at 01:35:01 UTC, Dave Jones wrote:
>> So it makes it a const/immutable/mutable method depending on whether the instance it is called on is const/immutable/mutable?
>
> On the outside, yes.
>
>> So
>>
>>>     @property ref inout(int) front() inout {
>>>         return i++;
>>>     }
>>
>> Would fail if you called it on an immutable instance of S.
>
> That wouldn't compile in any case: on the inside of the function, inout == const (this is the only way the one function can be used for all three). The inout propagation is just seen at the call site.

Ahh ok, makes sense now.
November 26, 2017
On Saturday, 25 November 2017 at 21:51:41 UTC, Dave Jones wrote:
> What does the "inout" after front() do here...
>
>
> @property ref inout(T) front() inout
> {
>     assert(_data.refCountedStore.isInitialized);
>     return _data._payload[0];
> }
>
> Cant seem to find an explanation in the docs or forums :(

https://p0nce.github.io/d-idioms/#Knowing-inout-inside-out