Can't make inout work.

2019-03-15 Thread aliak via Digitalmars-d-learn
This is the set up I have, and I'm not sure how to get the main 
function at the bottom to compile. The error in the code below is 
that it cannot implicitly convert an inout(C) to a C in the 
constructor of S(T).


If you remove the constructor that takes an inout then you get a 
"cannot deduce function from argument types !()(inout(C))" 
because there's no constructor that can take in inout.


If you remove the inout form the function "f", then "a.f" cannot 
be deduced because there's no f that takes an inout(C).


If you remove the inout from the "make" function, then you get: 
"only parameters or stack based variables can be inout."


Anyone knows how to make this work?

struct S(T) {
T value = T.init;
}

auto ref make(T)(inout auto ref T value) {
return S!T(value);
}

auto ref f(T)(inout auto ref S!T s) {
return make(s.value);
}

void main() {
class C {}
const a = S!C();
a.f;
}

Cheers,
- Ali


Re: Can't make inout work.

2019-03-15 Thread Paul Backus via Digitalmars-d-learn

On Friday, 15 March 2019 at 23:57:15 UTC, aliak wrote:

Anyone knows how to make this work?


You need an explicit `inout` on the return value of `make`:

auto ref make(T)(inout auto ref T value) {
return inout(S!T)(value);
}


Re: Can't make inout work.

2019-03-16 Thread spir via Digitalmars-d-learn

On 16/03/2019 04:49, Paul Backus via Digitalmars-d-learn wrote:

On Friday, 15 March 2019 at 23:57:15 UTC, aliak wrote:

Anyone knows how to make this work?


You need an explicit `inout` on the return value of `make`:

auto ref make(T)(inout auto ref T value) {
     return inout(S!T)(value);
}


I think (but may be wrong) that you don't need inout here, since a plain 'ref' 
will (and does) work. This is accepted by me (I added vars to make the code 
clearer to myself):


struct S(T) {
T value = T.init;
}

auto ref make(T)(ref T value) {
return S!T(value);
}

auto ref f(T)(ref S!T s) {
return make(s.value);
}

void main() {
class C {}
C c ;
auto s1 = S!C(c) ;
auto s2 = make!C(c) ;
auto s3 = f!C(s2) ;
}



Re: Can't make inout work.

2019-03-16 Thread spir via Digitalmars-d-learn

PS: the chapter of Ali Çehreli's book on func args is great:
http://ddili.org/ders/d.en/function_parameters.html
diniz


Re: Can't make inout work.

2019-03-16 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 16 March 2019 at 11:55:56 UTC, spir wrote:
I think (but may be wrong) that you don't need inout here, 
since a plain 'ref' will (and does) work. This is accepted by 
me (I added vars to make the code clearer to myself):


struct S(T) {
T value = T.init;
}

auto ref make(T)(ref T value) {
return S!T(value);
}

auto ref f(T)(ref S!T s) {
return make(s.value);
}

void main() {
class C {}
C c ;
auto s1 = S!C(c) ;
auto s2 = make!C(c) ;
auto s3 = f!C(s2) ;
}


This code fails to compile if you change `auto s2` to `const 
s2`--in other words, it has the same problem as the original 
example.


Re: Can't make inout work.

2019-03-17 Thread aliak via Digitalmars-d-learn

On Saturday, 16 March 2019 at 03:49:26 UTC, Paul Backus wrote:

On Friday, 15 March 2019 at 23:57:15 UTC, aliak wrote:

Anyone knows how to make this work?


You need an explicit `inout` on the return value of `make`:

auto ref make(T)(inout auto ref T value) {
return inout(S!T)(value);
}


Ah! Thanks! So next problem with that:

import std.stdio;

struct S(T) {
T value;
}

auto make(T)(inout auto ref T val) {
return inout(S!T)(val);
}

void main() {
writeln(make("hello") == S!string("hello"));
}

Error: Error: incompatible types for (make("hello")) == 
(S("hello")): immutable(S!(char[])) and S!string


I think that's just this bug (which is marked as a diagnostic for 
some reason): https://issues.dlang.org/show_bug.cgi?id=19126


Thoughts on any workarounds?


Re: Can't make inout work.

2019-03-17 Thread Kagamin via Digitalmars-d-learn

struct S(T) {
T value;
bool opEquals(U:S!V,V)(in U r) const
{ return value==r.value; }
}


Re: Can't make inout work.

2019-03-17 Thread Kagamin via Digitalmars-d-learn

On Saturday, 16 March 2019 at 14:57:35 UTC, Paul Backus wrote:
This code fails to compile if you change `auto s2` to `const 
s2`--in other words, it has the same problem as the original 
example.


Maybe there's not much need for qualifiers anyway.

struct S(T) {
T value;
}

auto make(T)(ref T value) {
return S!T(value);
}

auto f(T)(ref T s) {
return make(s.value);
}

void f() {
class C {}
C c;
auto s1 = S!C(c);
const s2 = make!C(c);
auto s3 = f(s2);
}


Re: Can't make inout work.

2019-03-17 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 17 March 2019 at 10:49:03 UTC, aliak wrote:

Ah! Thanks! So next problem with that:

import std.stdio;

struct S(T) {
T value;
}

auto make(T)(inout auto ref T val) {
return inout(S!T)(val);
}

void main() {
writeln(make("hello") == S!string("hello"));
}

Error: Error: incompatible types for (make("hello")) == 
(S("hello")): immutable(S!(char[])) and S!string


I think that's just this bug (which is marked as a diagnostic 
for some reason): https://issues.dlang.org/show_bug.cgi?id=19126


Thoughts on any workarounds?


For some reason, when you call `make("hello")`, the template 
argument T is being inferred as char[] instead of string. (You 
can see this by putting `pragma(msg, T)` in the body of make.) It 
works if you instantiate make explicitly with 
`make!string("hello")`.


This seems like a bug to me. If you remove inout from the code, T 
is correctly deduced as string.


Re: Can't make inout work.

2019-03-17 Thread aliak via Digitalmars-d-learn

On Sunday, 17 March 2019 at 17:22:13 UTC, Kagamin wrote:

struct S(T) {
T value;
bool opEquals(U:S!V,V)(in U r) const
{ return value==r.value; }
}


Hmm, that actually works for opEquals. But now you just hit the 
same problem with some other construct, unfortunately:


auto x = [make("hello"), S!string("hi")];

same error.



Re: Can't make inout work.

2019-03-18 Thread aliak via Digitalmars-d-learn

On Sunday, 17 March 2019 at 20:23:44 UTC, Paul Backus wrote:

On Sunday, 17 March 2019 at 10:49:03 UTC, aliak wrote:

[...]


For some reason, when you call `make("hello")`, the template 
argument T is being inferred as char[] instead of string. (You 
can see this by putting `pragma(msg, T)` in the body of make.) 
It works if you instantiate make explicitly with 
`make!string("hello")`.


This seems like a bug to me. If you remove inout from the code, 
T is correctly deduced as string.


https://issues.dlang.org/show_bug.cgi?id=19749


Re: Can't make inout work.

2019-03-18 Thread spir via Digitalmars-d-learn

On 17/03/2019 18:34, Kagamin via Digitalmars-d-learn wrote:

On Saturday, 16 March 2019 at 14:57:35 UTC, Paul Backus wrote:
This code fails to compile if you change `auto s2` to `const s2`--in other 
words, it has the same problem as the original example.


Maybe there's not much need for qualifiers anyway.


This is what I meant as well.
diniz