Re: How to avoid inout type constructor with Optional type wrapper undoing string type

2018-07-29 Thread aliak via Digitalmars-d-learn
On Sunday, 29 July 2018 at 12:30:58 UTC, Steven Schveighoffer 
wrote:

On 7/28/18 6:06 PM, aliak wrote:

[...]


What I meant was that string is actually mutable (the data 
isn't mutable, but the string can be re-assigned to another 
one), so Optional!string is more useful than 
immutable(Optional!(char[])). I shouldn't have said that 
immutable(Optional!T) is useless, you are right, and it 
wouldn't make sense for the defined flag to change there anyway.


[...]


Ah right. So it seems inout is removing head qualifiers on by-val 
parameters?


Filed what I think I understood from this:

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


Re: How to avoid inout type constructor with Optional type wrapper undoing string type

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

On 7/28/18 6:06 PM, aliak wrote:

On Friday, 27 July 2018 at 14:52:20 UTC, Steven Schveighoffer wrote:

On 7/23/18 2:39 PM, aliak wrote:

Hi,

I'm playing around with an Optional wrapper type. It stores a type T 
and a bool that defines whether a value is defined or not:


struct Optional(T) {
   T value;
   bool defined = false;
   this(U : T)(auto ref inout(U) value) inout {
 this.value = value;
 this.defined = true;
   }
}


Don't use inout here. The point of inout on the constructor is to 
*transfer* the mutability of the parameter to the struct instance. But 
you want to simply copy the type into the struct (an 
immutable(Optional!T) is quite useless, no?)


Just use U, not inout(U), and don't put inout on the constructor.



But then it only works for mutable Optional right? Why would an 
immutable(Optional!T) be useless? Data can be "forever" empty or a 
certain value.


What I meant was that string is actually mutable (the data isn't 
mutable, but the string can be re-assigned to another one), so 
Optional!string is more useful than immutable(Optional!(char[])). I 
shouldn't have said that immutable(Optional!T) is useless, you are 
right, and it wouldn't make sense for the defined flag to change there 
anyway.


But I see a problem here. string *is* mutable, yet, the parameter is 
accepted as inout(char[]). This seems unreasonable, I may want to 
preserve the head mutability. I didn't realize IFTI would do this. May 
be a bug, but I'm not certain.


But you have it as auto ref, which means since you only sent in rvalues 
of strings, you didn't test the ref-ness of it. Indeed, if you do:


string s = "hello";
auto a = defined(s);

you get what you expected!

This doesn't make a whole lot of sense. I wouldn't expect different 
types using IFTI this way. I'd recommend filing a bug on inout and IFTI. 
There isn't a good way around this...


-Steve


Re: How to avoid inout type constructor with Optional type wrapper undoing string type

2018-07-28 Thread aliak via Digitalmars-d-learn
On Friday, 27 July 2018 at 14:52:20 UTC, Steven Schveighoffer 
wrote:

On 7/23/18 2:39 PM, aliak wrote:

Hi,

I'm playing around with an Optional wrapper type. It stores a 
type T and a bool that defines whether a value is defined or 
not:


struct Optional(T) {
   T value;
   bool defined = false;
   this(U : T)(auto ref inout(U) value) inout {
     this.value = value;
     this.defined = true;
   }
}


Don't use inout here. The point of inout on the constructor is 
to *transfer* the mutability of the parameter to the struct 
instance. But you want to simply copy the type into the struct 
(an immutable(Optional!T) is quite useless, no?)


Just use U, not inout(U), and don't put inout on the 
constructor.


-Steve


But then it only works for mutable Optional right? Why would an 
immutable(Optional!T) be useless? Data can be "forever" empty or 
a certain value.


Re: How to avoid inout type constructor with Optional type wrapper undoing string type

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

On 7/23/18 2:39 PM, aliak wrote:

Hi,

I'm playing around with an Optional wrapper type. It stores a type T and 
a bool that defines whether a value is defined or not:


struct Optional(T) {
   T value;
   bool defined = false;
   this(U : T)(auto ref inout(U) value) inout {
     this.value = value;
     this.defined = true;
   }
}


Don't use inout here. The point of inout on the constructor is to 
*transfer* the mutability of the parameter to the struct instance. But 
you want to simply copy the type into the struct (an 
immutable(Optional!T) is quite useless, no?)


Just use U, not inout(U), and don't put inout on the constructor.

-Steve


Re: How to avoid inout type constructor with Optional type wrapper undoing string type

2018-07-25 Thread Timoses via Digitalmars-d-learn

On Tuesday, 24 July 2018 at 14:11:51 UTC, Ali Çehreli wrote:

On 07/24/2018 02:47 AM, Timoses wrote:

> Why does this fail while it works when replacing T with U in
struct
> W(T)?? It's so odd. Both T and U seem to resolve to "string".
>
>  struct W(T) {
>  const T value;
>  // Replacing `T value` with `U value` compiles
>  this(U : T)(auto ref const T value) {

That means, "any U that can implicitly be converted to string". 
However, when U does not appear in the function parameter list, 
there is no way for the compiler to deduce U. (I don't think 
there is syntax to specify constructor template parameters 
explicitly.)


And if the parameter is always T, why is the constructor a 
template? Ok, perhaps U is used inside the constructor and the 
programmer needs to specify it... Still, I don't think there is 
such syntax.


Ali


Ah, thanks!


Re: How to avoid inout type constructor with Optional type wrapper undoing string type

2018-07-24 Thread Ali Çehreli via Digitalmars-d-learn

On 07/24/2018 02:47 AM, Timoses wrote:

> Why does this fail while it works when replacing T with U in struct
> W(T)?? It's so odd. Both T and U seem to resolve to "string".
>
>  struct W(T) {
>  const T value;
>  // Replacing `T value` with `U value` compiles
>  this(U : T)(auto ref const T value) {

That means, "any U that can implicitly be converted to string". However, 
when U does not appear in the function parameter list, there is no way 
for the compiler to deduce U. (I don't think there is syntax to specify 
constructor template parameters explicitly.)


And if the parameter is always T, why is the constructor a template? Ok, 
perhaps U is used inside the constructor and the programmer needs to 
specify it... Still, I don't think there is such syntax.


Ali



Re: How to avoid inout type constructor with Optional type wrapper undoing string type

2018-07-24 Thread Timoses via Digitalmars-d-learn

On Monday, 23 July 2018 at 18:39:59 UTC, aliak wrote:

Hi,

I'm playing around with an Optional wrapper type. It stores a 
type T and a bool that defines whether a value is defined or 
not:


struct Optional(T) {
  T value;
  bool defined = false;
  this(U : T)(auto ref inout(U) value) inout {
this.value = value;
this.defined = true;
  }
}

To facilitate it's use I have two type constructors:

inout(Optional!T) some(T)(auto ref inout(T) value) {
return inout(Optional!T)(value);
}

Optional!T no(T)() {
return Optional!T();
}

The above produces a problem when working with strings. 
Basically the type information gets slightly altered so you 
can't do this:


auto a = [no!string, some("hello")];

You get a type mismatch:

* no!string = Optional!string
* some("hello") = immutable(Optional!(char[]))

I've created a short code gist, so basically I'm wondering how 
to get it to compile without changing what's in main()


https://run.dlang.io/is/BreNdZ

I guess I can specialize on string type T, but this is a more 
general problem that can be shown with:


struct S {}
alias Thing = immutable S;
Thing thing = S();

auto x = some(thing);
auto y = no!Thing;
auto arr = [x, y]; // no can do buddy

Cheers,
- Ali



I'm not being very helpful here, just throwing in more questions 
again:


Why does this fail while it works when replacing T with U in 
struct W(T)?? It's so odd. Both T and U seem to resolve to 
"string".


struct W(T) {
const T value;
// Replacing `T value` with `U value` compiles
this(U : T)(auto ref const T value) {
pragma(msg, T); // string
pragma(msg, U); // string
this.value = value;
}
}

auto defined(T)(auto ref const T value) {
return W!T(value);
}

void main() {
auto a = defined("hello");
}

Is this a bug?


Re: How to avoid inout type constructor with Optional type wrapper undoing string type

2018-07-23 Thread aliak via Digitalmars-d-learn

On Monday, 23 July 2018 at 19:31:42 UTC, aliak wrote:
Ok, now I'm totally confused. Defining an extra type 
constructor makes everything work. I.e add a const one to the 
inout one:


auto defined(T)(const auto ref T value) {
return W!T(value);
}

and everything works!

Can anyone say why that is?


Boh, seems other problems crop up now as doing this:

auto a = defined!(int*)(null);

produces error:

onlineapp.d(13): Error: inout constructor 
onlineapp.W!(int*).W.__ctor!(int*).this creates const object, not 
mutable
onlineapp.d(30): Error: template instance 
`onlineapp.defined!(int*)` error instantiating


https://run.dlang.io/is/BWYxA8


Re: How to avoid inout type constructor with Optional type wrapper undoing string type

2018-07-23 Thread aliak via Digitalmars-d-learn

On Monday, 23 July 2018 at 19:22:13 UTC, aliak wrote:

On Monday, 23 July 2018 at 19:02:02 UTC, Jacob Carlborg wrote:


This [1] compiles the first example but not the second.

[1] https://run.dlang.io/is/SJ02kP


Aye it does, but it also sets T to always const which is 
unfortunately impractical for my use case :(


Ok, now I'm totally confused. Defining an extra type constructor 
makes everything work. I.e add a const one to the inout one:


auto defined(T)(const auto ref T value) {
return W!T(value);
}

and everything works!

Can anyone say why that is?


Re: How to avoid inout type constructor with Optional type wrapper undoing string type

2018-07-23 Thread aliak via Digitalmars-d-learn

On Monday, 23 July 2018 at 19:02:02 UTC, Jacob Carlborg wrote:


This [1] compiles the first example but not the second.

[1] https://run.dlang.io/is/SJ02kP


Aye it does, but it also sets T to always const which is 
unfortunately impractical for my use case :(




Re: How to avoid inout type constructor with Optional type wrapper undoing string type

2018-07-23 Thread Jacob Carlborg via Digitalmars-d-learn

On 2018-07-23 20:39, aliak wrote:

Hi,

I'm playing around with an Optional wrapper type. It stores a type T and 
a bool that defines whether a value is defined or not:


struct Optional(T) {
   T value;
   bool defined = false;
   this(U : T)(auto ref inout(U) value) inout {
     this.value = value;
     this.defined = true;
   }
}

To facilitate it's use I have two type constructors:

inout(Optional!T) some(T)(auto ref inout(T) value) {
     return inout(Optional!T)(value);
}

Optional!T no(T)() {
     return Optional!T();
}

The above produces a problem when working with strings. Basically the 
type information gets slightly altered so you can't do this:


auto a = [no!string, some("hello")];

You get a type mismatch:

* no!string = Optional!string
* some("hello") = immutable(Optional!(char[]))

I've created a short code gist, so basically I'm wondering how to get it 
to compile without changing what's in main()


https://run.dlang.io/is/BreNdZ

I guess I can specialize on string type T, but this is a more general 
problem that can be shown with:


struct S {}
alias Thing = immutable S;
Thing thing = S();

auto x = some(thing);
auto y = no!Thing;
auto arr = [x, y]; // no can do buddy


This [1] compiles the first example but not the second.

[1] https://run.dlang.io/is/SJ02kP

--
/Jacob Carlborg


How to avoid inout type constructor with Optional type wrapper undoing string type

2018-07-23 Thread aliak via Digitalmars-d-learn

Hi,

I'm playing around with an Optional wrapper type. It stores a 
type T and a bool that defines whether a value is defined or not:


struct Optional(T) {
  T value;
  bool defined = false;
  this(U : T)(auto ref inout(U) value) inout {
this.value = value;
this.defined = true;
  }
}

To facilitate it's use I have two type constructors:

inout(Optional!T) some(T)(auto ref inout(T) value) {
return inout(Optional!T)(value);
}

Optional!T no(T)() {
return Optional!T();
}

The above produces a problem when working with strings. Basically 
the type information gets slightly altered so you can't do this:


auto a = [no!string, some("hello")];

You get a type mismatch:

* no!string = Optional!string
* some("hello") = immutable(Optional!(char[]))

I've created a short code gist, so basically I'm wondering how to 
get it to compile without changing what's in main()


https://run.dlang.io/is/BreNdZ

I guess I can specialize on string type T, but this is a more 
general problem that can be shown with:


struct S {}
alias Thing = immutable S;
Thing thing = S();

auto x = some(thing);
auto y = no!Thing;
auto arr = [x, y]; // no can do buddy

Cheers,
- Ali