It turns out it's quite hard to have @safe pure nothrow functions. Oh, and const.

Timon Gehr via Digitalmars-d digitalmars-d at puremagic.com
Sun Sep 14 06:09:16 PDT 2014


On 09/14/2014 10:50 AM, Kagamin wrote:
> On Sunday, 14 September 2014 at 01:38:33 UTC, Jakob Ovrum wrote:
>> This is necessary for `inout` to work with callback functions, such as
>> with internal iteration (i.e. `opApply`).
>
> Can you write a pass and xfail test for it? This scenario looks
> non-trivial.
> ...

struct S{
     int[] a;
     int opApply(scope int delegate(ref inout int) dg)inout{
         foreach(ref x;a) if(auto r=dg(x)) return r;
         return 0;
     }
}

void main(){
     auto s=S([1,2,3]);
     foreach(ref x;s) x++; // ok
     const(S) s2=s;
     foreach(ref x;s2){
         import std.stdio;
         writeln(x);
         // x++; error
     }
}


>> It can be worked around exactly the same way you would work around it
>> with functions that return a value - by duplicating the function. It
>> is essentially the same problem and thus `inout` could easily be used
>> to fix it.
>
> Can you elaborate? I don't quite understand, what you mean.

inout's primary goal is to eliminate patterns similar to:

struct S{
     int[] a;
     int opApply(scope int delegate(ref int) dg){
         foreach(ref x;a) if(auto r=dg(x)) return r;
         return 0;
     }
     int opApply(scope int delegate(ref const int) dg)const{
         foreach(ref x;a) if(auto r=dg(x)) return r;
         return 0;
     }
     int opApply(scope int delegate(ref immutable int) dg)immutable{
         foreach(ref x;a) if(auto r=dg(x)) return r;
         return 0;
     }
}




More information about the Digitalmars-d mailing list