www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How useful should inout be?

reply "Infiltrator" <Lt.Infiltrator gmail.com> writes:
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
Mar 23 2014
next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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
Mar 24 2014
prev sibling parent reply "Kagamin" <spam here.lot> writes:
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.
Mar 25 2014
parent "Kagamin" <spam here.lot> writes:
* for function parameters
Mar 25 2014