Thread overview
How useful should inout be?
Mar 23, 2014
Infiltrator
Mar 25, 2014
Kagamin
Mar 25, 2014
Kagamin
March 23, 2014
So, following on from monarchdodra's comment [0] in the bug tracker, how exactly should inout work?  For example, should the following work?

----------------------------------------------------
import std.algorithm : map;

class L {
   auto fun(const S s) inout nothrow pure @safe {
      if(point[0] is s)
         return point[1];
      else
         return point[0];
   }
   this(S a, S b) {
      point = [a, b];
   }
   S[2] point;
}

class S {
   @property auto foo() inout nothrow pure @safe {
      return arr.map!(e => e.fun(this));
   }
   L[] arr;
}

void main() { }
----------------------------------------------------


Writing foo imperatively causes no problems with inout:
----------------------------------------------------
   @property auto foo() inout nothrow pure @safe {
      inout(S)[] tmp;
      foreach(e; arr)
         tmp ~= e.fun(this);
      return tmp;
   }
----------------------------------------------------


Of course, the functional style looks cleaner, neater, and more immediately obvious what is being done.

So, is this a limitation with inout, part of its design, or am I misunderstaning something more fundamental?


[0] https://d.puremagic.com/issues/show_bug.cgi?id=12408#c4
March 24, 2014
On Sun, 23 Mar 2014 06:28:52 -0400, Infiltrator <Lt.Infiltrator@gmail.com> wrote:

> So, following on from monarchdodra's comment [0] in the bug tracker, how exactly should inout work?  For example, should the following work?
>
> ----------------------------------------------------
> import std.algorithm : map;
>
> class L {
>     auto fun(const S s) inout nothrow pure @safe {
>        if(point[0] is s)
>           return point[1];
>        else
>           return point[0];
>     }
>     this(S a, S b) {
>        point = [a, b];
>     }
>     S[2] point;
> }
>
> class S {
>     @property auto foo() inout nothrow pure @safe {
>        return arr.map!(e => e.fun(this));
>     }
>     L[] arr;
> }
>
> void main() { }
> ----------------------------------------------------
>
>
> Writing foo imperatively causes no problems with inout:
> ----------------------------------------------------
>     @property auto foo() inout nothrow pure @safe {
>        inout(S)[] tmp;
>        foreach(e; arr)
>           tmp ~= e.fun(this);
>        return tmp;
>     }
> ----------------------------------------------------
>
>
> Of course, the functional style looks cleaner, neater, and more immediately obvious what is being done.
>
> So, is this a limitation with inout, part of its design, or am I misunderstaning something more fundamental?

inout has issues when it comes to delegates. Note that inout has two modes of operation, one is as a type constructor, which is distinct from const and immutable, and has its own rules. The other is a link between the parameters and the return value to determine what the return value can bind to.

The issue is that as you nest delegates, the lines become blurred as to what inout actually means, and what it binds to. There can be several levels of inout, and all are accessible from the nested delegate function. The link between the parameters and the return value depends on the type constructor being consistent within the function. If we allow delegates to access inout variables outside the function, bad things can happen.

So it is a limitation, it wasn't exactly part of the design, and there have been ideas to fix it, but nothing has happened so far. Timon Gehr has a very good grasp of the issues and how they need to be fixed.

-Steve
March 25, 2014
On Sunday, 23 March 2014 at 10:28:54 UTC, Infiltrator wrote:
> So, is this a limitation with inout, part of its design, or am I misunderstaning something more fundamental?

It's fundamental: inout makes sense for function attributes only and can't be used as a template parameter or struct/class field (what map attempts). Opaque template parameters would solve the issue and can be also used for other purposes, but on the first sight they seem like a task of galactic scale, hence nonviable.
March 25, 2014
* for function parameters