On 06/14/2017 12:45 AM, Steven Schveighoffer wrote:
No, the fact that immutable implicitly casts to const(inout) is a special property enabled by the knowledge that immutable data can NEVER change, so it's OK to assume it's (at least) const for all references. The same cannot be true of const or mutable.

In other words: Immutable can't ever become mutable, at most it can become const.

In the same vein: Mutable can't ever become immutable, at most it can become const.

I don't see the fundamental difference. Mutable and immutable act very much alike. They're just on opposing ends of the scale.

This code doesn't work, and I see no way to make it work:

----
inout(int*) f(inout int* x, inout int* y)
{
    return y;
}

auto g(inout int* x)
{
    int* y;
    return f(x, y);
}

void main()
{
    int* x;
    int* r1 = g(x);
}
----

This cannot work, because g() has no idea what the true mutability of x is. inout is not a template. This is why you can't implicitly cast inout to anything except const, and you can't implicitly cast anything to inout.

I don't follow. `inout const` doesn't need a template to do its thing. I'm not sure what you mean about implicit conversions. Obviously, an inout result matches the corresponding inout argument(s). Doesn't matter if that's an implicit conversion or whatever.

The goal is something that works just like `inout const`, but switching mutable and immutable.

I've realized that my example can be simplified:

----
bool condition;
auto f(inout int* x)
{
    immutable int* y;
    return condition ? x : y;
}
void main()
{
    const r1 = f(new int);
    immutable r2 = f(new immutable int);
}
----

That's `inout const` at work. Put a mutable or const int* in, you get a const int* out. Put immutable in, you get immutable out. You can't get mutable out, because the function might return y which is immutable, and it cannot become mutable.

Now, this code could be made to work:

----
bool condition;
auto f(inout int* x)
{
    int* y; /* mutable now */
    return condition ? x : y;
}
void main()
{
    int* r1 = f(new int);
    const r1 = f(new immutable int);
}
----

Mutable in, mutable out. Const in, const out. Immutable in, const out. You can't get immutable out, because y is mutable, and it cannot become immutable. Same principle as above. You never go from mutable to immutable or the other way around, so everything's fine, no?

Except, there's no type in D that has this meaning.

Reply via email to