Thread overview
Inout table
Sep 09
nkm1
5 days ago
nkm1
September 09
There is this little table in https://dlang.org/spec/function.html#inout-functions:

Common qualifier of the two type qualifiers
                   mutable const  immutable inout inout const
mutable (= m)      m       c      c         c     c
const (= c)        c       c      c         c     c
immutable (= i)    c       c      i         wc    wc
inout (= w)        c       c      wc        w     wc
inout const (= wc) c       c      wc        wc    wc

I don't understand what it is trying to say. What is it that is calculated here? The qualifier for the return value?
And what's an "inout const"?
5 days ago
On 9/8/17 10:00 PM, nkm1 wrote:
> There is this little table in https://dlang.org/spec/function.html#inout-functions:
> 
> Common qualifier of the two type qualifiers
>                     mutable const  immutable inout inout const
> mutable (= m)      m       c      c         c     c
> const (= c)        c       c      c         c     c
> immutable (= i)    c       c      i         wc    wc
> inout (= w)        c       c      wc        w     wc
> inout const (= wc) c       c      wc        wc    wc
> 
> I don't understand what it is trying to say. What is it that is calculated here? The qualifier for the return value?

Correct. So given a function:

inout(int*) foo(inout(int*)p1, inout(int*)p2)

The table shows what inout is resolved as when calling the function.

If you consider the column the mutability of p1, and the row the mutability of p2, then the value in the table represents the mutability of the return value.

So for instance:

int *m;
const int *c;
immutable int *i;
inout int *w;

auto v1 = foo(m, m); // typeof(v1) is int*
auto v2 = foo(m, c); // typeof(v2) is const(int*)
auto v3 = foo(i, m); // typeof(v3) is const(int*)
auto v4 = foo(w, w); // typeof(v4) is inout(int*)
auto v5 = foo(w, i); // typeof(v5) is inout(const(int *))

etc.

> And what's an "inout const"?

inout(const(T)) resolves to either immutable or const, depending on what inout ultimately resolves to.

In other words, if inout is:

mutable -> /*mutable*/(const(T)) // note no keyword for mutable, so it's just const(T)
const -> const(const(T)) -> const(T)
immutable -> immutable(const(T)) -> immutable(T)

It was discovered that this extra mechanism has benefits (namely you can combine immutable data with inout data), so it now has it's own special place while using inout.

A use case might be returning a sentinel value from a function:

class Foo {}

immutable sentinel = new Foo;

inout(const(Foo)) foo(inout(Foo) f) { return someCond? sentinel : f; }

Whenever an immutable Foo is passed in as f, then the result will be immutable. Otherwise, it's const.

-Steve
5 days ago
On Wednesday, 13 September 2017 at 17:39:29 UTC, Steven Schveighoffer wrote:
> Correct. So given a function:
>
> inout(int*) foo(inout(int*)p1, inout(int*)p2)
>
> The table shows what inout is resolved as when calling the function.
>
> If you consider the column the mutability of p1, and the row the mutability of p2, then the value in the table represents the mutability of the return value.
>
> So for instance:
>
> int *m;
> const int *c;
> immutable int *i;
> inout int *w;
>
> auto v1 = foo(m, m); // typeof(v1) is int*
> auto v2 = foo(m, c); // typeof(v2) is const(int*)
> auto v3 = foo(i, m); // typeof(v3) is const(int*)
> auto v4 = foo(w, w); // typeof(v4) is inout(int*)
> auto v5 = foo(w, i); // typeof(v5) is inout(const(int *))
>
> etc.

Thank you. Now it is clear to me. The source of my confusion was that, say, given a function:
inout(int*) foo(inout(int*) p)
as per table, combining (mutable) argument int* m with parameter inout(int*) p would produce parameter type const(int*). But now I see that the table deduces the common type of all parameters, not the common type of a parameter and its argument (the documentation is kind of hard to parse: "If such a match occurs, the inout is considered the common qualifier of the matched qualifiers...").
5 days ago
On 9/13/17 3:04 PM, nkm1 wrote:

> Thank you. Now it is clear to me. The source of my confusion was that, say, given a function:
> inout(int*) foo(inout(int*) p)
> as per table, combining (mutable) argument int* m with parameter inout(int*) p would produce parameter type const(int*). But now I see that the table deduces the common type of all parameters, not the common type of a parameter and its argument (the documentation is kind of hard to parse: "If such a match occurs, the inout is considered the common qualifier of the matched qualifiers...").

Yeah, I should update that table and inout explanation...

-Steve