On 4/15/16 4:27 PM, Timon Gehr wrote:
On 15.04.2016 22:03, Steven Schveighoffer wrote:
On 4/15/16 3:48 PM, Timon Gehr wrote:
On 15.04.2016 17:22, Steven Schveighoffer wrote:
On 4/14/16 11:10 PM, Andrei Alexandrescu wrote:
Consider:

https://github.com/D-Programming-Language/phobos/blob/master/std/range/primitives.d#L152





It works around a limitation of inout that isn't necessary (even though
I thought it was being helpful when I suggested it). That is, functions
without inout parameters cannot declare local inout variables. But this
isn't really necessary, and should be fixed. I will discuss this in my
talk in a few weeks.
...

That's potentially dangerous. What about cases like the following?

void main(){
     inout(int)[] x=[1,2,3];
     immutable(int) a;
     int b;
     inout(int)[] foo(inout int){
         return x;
     }
     immutable(int)[] y=foo(a);
     int[] z=foo(b);
}

We don't need to guess:

void foo (inout int)
{
     inout(int)[] x=[1,2,3];
     immutable(int) a;
     int b;
     inout(int)[] foo(inout int){
         return x;
     }
     immutable(int)[] y=foo(a); // line 9
     int[] z=foo(b);  // line 10
}

testinout.d(9): Error: modify inout to immutable is not allowed inside
inout function
testinout.d(10): Error: modify inout to mutable is not allowed inside
inout function


I'm very aware of that: https://issues.dlang.org/show_bug.cgi?id=10758
main is not an inout function in the example above. I.e. if we just
change the compiler minimally such as to allow making inout local
variables, the above example will violate immutability guarantees. You
can also imagine cases where the inout local variable is defined only
after the local inout function has been declared and called with a
non-inout argument. At which point does the constraint become active?
etc. We cannot _simply_ allow declaring inout locals.

There's no difference between a function that declares its variables inout within its parameters or one that declares them locally.

They should be treated the same once the function starts compiling.




Note, the =0 part isn't necessary right now, since it's not called.
It's
just used to test if the function can compile.

In short, my opinion on inout is that it has some unnecessary
limitations, which can be removed, and inout will work as mostly
expected. These requirements to work around the limitations will go
away.
...

Other important limitations of inout are e.g.:
- inout variables cannot be fields.

I have a way to make this work.

Without syntax changes?
Can the struct/class instances with inout fields be returned from the
enclosing inout function?

Yes, as long as inout is wrapping inout. We run into this currently with inout functions that create local types. e.g. emplace.

Obviously inout cannot be unwrapped if it is typed on a field of a struct or class. So the unwrapping has to result in inout.

- There can be only one inout in scope.

This is not so much a problem I think.
...

I think it is. It's just not the prevalent limitation one runs in at the
moment. It will be more of a problem once functions can return structs
with inout fields. IMHO compositionality should be ensured for a
language feature from the start.

At the point where we need to tag multiple pools of inout parameters, the complexity of the language doesn't justify the benefits.

We could make it possible, for instance, to templatize the mutability modifier instead of using a specific keyword. Then you could have foo(int)[]. Then I think you could do all this (and scrap inout), but I wouldn't want to work in that language.

-Steve

Reply via email to