Re: immutable / inout / pure headaches

2018-07-06 Thread Timoses via Digitalmars-d-learn
On Friday, 6 July 2018 at 15:44:28 UTC, Steven Schveighoffer 
wrote:


I'm long overdue for an inout article...

I can point you at my talk from 2016: 
https://www.youtube.com/watch?v=UTz55Lv9FwQ

Thanks, will definitely take a look when I get home.




I never really used 'pure' and just now found a use case with 
immutable [1], i.e. to return unique objects from functions 
which can be assigned to a mutable or immutable reference.
What other "use cases" or reasons to use 'pure' are there 
(aside from compiler optimizations)?


The reason pure functions allow mutability changes is due to 
the nature of what pure means semantically -- you have 
guarantees that nothing else goes in or out, so it's possible 
to deduce what is unique and what is not.


This is powerful to a human reader of a function as well! 
Without seeing the insides, it tells you exactly what it can 
and cannot affect, giving you more understanding of when it can 
be used and when it can't. It helps write safer more tractable 
code, IMO.


In the end, all these attributes are to help reason about large 
code bases without having to read ALL the code.


Sounds like a good idea to always use it whenever possible. For 
me as a kind of novice it takes time to understand the purpose 
and meaning of each of those attributes. I guess I got one step 
closer to understanding "Why pure?".


That leaves @nogc, @safe and @trusted :D. I feel the best way to 
understand these idioms is to experience the "trouble" oneself. I 
knew in some way what pure functions were from the spec, but I 
didn't have an example at hand that made "non-usage" of pure 
painful.


Re: immutable / inout / pure headaches

2018-07-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/6/18 11:22 AM, Timoses wrote:

On Friday, 6 July 2018 at 14:28:39 UTC, Steven Schveighoffer wrote:
inout is not a compile-time wildcard, it's a runtime one. So it 
doesn't know how to convert an immutable to an inout. Essentially, 
inside this function, the compiler has no idea whether the real thing 
is an immutable, const, mutable, etc.


The fix is simple, replace both your constructors with one inout 
constructor:


this(inout(S) t) inout { this.s = t; }


Slowly getting acquainted to inout... Feels like magic.


I'm long overdue for an inout article...

I can point you at my talk from 2016: 
https://www.youtube.com/watch?v=UTz55Lv9FwQ


"viral" is very fitting. Throw in pure and I quickly reach the bottom of 
my program hitting a library function I used which is not pure.


I never really used 'pure' and just now found a use case with immutable 
[1], i.e. to return unique objects from functions which can be assigned 
to a mutable or immutable reference.
What other "use cases" or reasons to use 'pure' are there (aside from 
compiler optimizations)?


The reason pure functions allow mutability changes is due to the nature 
of what pure means semantically -- you have guarantees that nothing else 
goes in or out, so it's possible to deduce what is unique and what is not.


This is powerful to a human reader of a function as well! Without seeing 
the insides, it tells you exactly what it can and cannot affect, giving 
you more understanding of when it can be used and when it can't. It 
helps write safer more tractable code, IMO.


In the end, all these attributes are to help reason about large code 
bases without having to read ALL the code.


-Steve


Re: immutable / inout / pure headaches

2018-07-06 Thread Timoses via Digitalmars-d-learn
On Friday, 6 July 2018 at 14:28:39 UTC, Steven Schveighoffer 
wrote:
inout is not a compile-time wildcard, it's a runtime one. So it 
doesn't know how to convert an immutable to an inout. 
Essentially, inside this function, the compiler has no idea 
whether the real thing is an immutable, const, mutable, etc.


The fix is simple, replace both your constructors with one 
inout constructor:


this(inout(S) t) inout { this.s = t; }


Slowly getting acquainted to inout... Feels like magic.


And it will work for everything.

One word of caution though -- inout is viral (just like 
immutable). Everything you use has to support it, or it breaks 
down.


"viral" is very fitting. Throw in pure and I quickly reach the 
bottom of my program hitting a library function I used which is 
not pure.


I never really used 'pure' and just now found a use case with 
immutable [1], i.e. to return unique objects from functions which 
can be assigned to a mutable or immutable reference.
What other "use cases" or reasons to use 'pure' are there (aside 
from compiler optimizations)?


[1]: 
https://forum.dlang.org/post/nmcnuenazaghjlxod...@forum.dlang.org


Re: immutable / inout / pure headaches

2018-07-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/6/18 7:10 AM, Timoses wrote:
I dared once again getting into immutable by adding an "immutable" 
keyword which causes a chain of actions to be taken.
I feel like I'm lost in a jungle of immutable, inout and pure (perhaps 
more will join the party...).


To start off, why does this not work?


 class Test
 {
     private S s;
     this(S t) { this.s = t; }
     this(immutable S t) immutable { this.s = t; }

     inout(Test) get() inout
     {
     // Error: none of the overloads of __ctor are callable 
using a inout object, candidates are:

//onlineapp.d(10):    onlineapp.Test.this(S t)
//onlineapp.d(11):    onlineapp.Test.this(immutable(S) t)
  return new inout Test(this.s);
     }


inout is not a compile-time wildcard, it's a runtime one. So it doesn't 
know how to convert an immutable to an inout. Essentially, inside this 
function, the compiler has no idea whether the real thing is an 
immutable, const, mutable, etc.


The fix is simple, replace both your constructors with one inout 
constructor:


this(inout(S) t) inout { this.s = t; }

And it will work for everything.

One word of caution though -- inout is viral (just like immutable). 
Everything you use has to support it, or it breaks down.


-Steve


Re: immutable / inout / pure headaches

2018-07-06 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, July 06, 2018 11:10:27 Timoses via Digitalmars-d-learn wrote:
> I dared once again getting into immutable by adding an
> "immutable" keyword which causes a chain of actions to be taken.
> I feel like I'm lost in a jungle of immutable, inout and pure
> (perhaps more will join the party...).
>
> To start off, why does this not work?
>
>
>   class Test
>   {
>   private S s;
>   this(S t) { this.s = t; }
>   this(immutable S t) immutable { this.s = t; }
>
>  inout(Test) get() inout
>  {
>  // Error: none of the overloads of __ctor are
> callable using a inout object, candidates are:
> //onlineapp.d(10):onlineapp.Test.this(S t)
> //onlineapp.d(11):onlineapp.Test.this(immutable(S) t)
>   return new inout Test(this.s);
>  }
>   }
>
>   struct S
>   {
>   int[] a;
>   }
>   void main()
>   {
>   immutable S s = immutable S([1,2,3]);
>   auto t = new immutable Test(s);
>   }

You have no constructor that will work with inout - only mutable amd
immutable. inout is only going to work when the object is always treated as
either inout or const, because it could be an object that's mutable, const,
or immutable. It can't ever treat it as mutable or immutable within the
function that marks it as inout.

- Jonathan M Davis



immutable / inout / pure headaches

2018-07-06 Thread Timoses via Digitalmars-d-learn
I dared once again getting into immutable by adding an 
"immutable" keyword which causes a chain of actions to be taken.
I feel like I'm lost in a jungle of immutable, inout and pure 
(perhaps more will join the party...).


To start off, why does this not work?


class Test
{
private S s;
this(S t) { this.s = t; }
this(immutable S t) immutable { this.s = t; }

inout(Test) get() inout
{
// Error: none of the overloads of __ctor are 
callable using a inout object, candidates are:

//onlineapp.d(10):onlineapp.Test.this(S t)
//onlineapp.d(11):onlineapp.Test.this(immutable(S) t)
return new inout Test(this.s);
}
}

struct S
{
int[] a;
}
void main()
{
immutable S s = immutable S([1,2,3]);
auto t = new immutable Test(s);
}