Re: Make enum auto castable

2017-06-04 Thread Mike B Johnson via Digitalmars-d-learn

On Monday, 5 June 2017 at 03:15:46 UTC, Jonathan M Davis wrote:
On Monday, June 05, 2017 02:14:14 Mike B Johnson via 
Digitalmars-d-learn wrote:

On Monday, 5 June 2017 at 01:42:55 UTC, Jonathan M Davis wrote:
> On Monday, June 05, 2017 01:30:47 Mike B Johnson via
>
> Digitalmars-d-learn wrote:
>> [...]
>
> It's not a bug. The alias this conversion only goes one way. 
> It provides a way to convert _from_ the type that it's 
> declared on to another type, not from the other type to the 
> type that it's declared on. There is no way in D to declare 
> an implicit conversion in the direction you're trying. So, 
> if you have a struct that wraps an int like this, and you 
> want to assign it an int, you're going to need to explicitly 
> construct the struct - e.g. EnumX(1).

>
> - Jonathan M Davis

That's pretty crappy! Defeats the whole point!


Well, implicit conversions tend to cause a lot of bugs in C++ 
code, so Walter decided to restrict them quite a bit more in D 
than they are in C++. This therefore prevents a number of bugs 
in D, but it also prevents implicit conversions from being used 
in a number of situations where they're useful. Whether the end 
result is better or worse, I don't know and certainly YMMV. As 
it is, some of the implicit conversions that we still allow 
have a tendency to cause bugs (e.g. conversions between 
integral values and character types tend to be error-prone - 
especially when arrays are involved - and using implicit 
conversions with templated code is almost always a bad idea). 
So, at times, I tend to think that all implicit conversions 
should be banned. But at other times, it would be really nice 
to be able to have more than we do (e.g. it would be a lot more 
user-friendly if you could pass a T to a function that takes a 
Nullable!T).


In any case, I think that the reality of the matter with D is 
that you tend to have to use explicit conversions rather than 
implicit ones, and if you're looking to do much with implicit 
conversions, you're usually going to be frustrated, and 
obviously, that sucks, but at least you're less likely to have 
bugs related to implicit conversions.


- Jonathan M Davis


The problem is bugs are only a possibility. If you remove a 
feature from a language the feature does not exist, period.


So, throwing the baby out with the bath water because he pooped 
in it is not a solution.


Instead, if there is a problem with implicit autonomous 
conversion or construction, then the solution is not to remove 
all implicit conversions or constructions but to remove the 
autonomous part.


e.g., make the user specify the implicit conversion explicitly. 
This way, if bugs do creep in, it is due to the user. It is much 
easier to diagnose and fix then.




Re: Make enum auto castable

2017-06-04 Thread via Digitalmars-d-learn
On Sun, Jun 04, 2017 at 08:15:46PM -0700, Jonathan M Davis via 
Digitalmars-d-learn wrote:
> Well, implicit conversions tend to cause a lot of bugs in C++ code, so
> Walter decided to restrict them quite a bit more in D than they are in C++.

So D has plenty of implicit conversion. It is implicit *construction* that it 
lacks.

And alas, C++'s mistake is implicit is default, so it gets used in places it 
wasn't intended. We should have just had explicit default with implicit as an 
option.




Re: Make enum auto castable

2017-06-04 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, June 05, 2017 02:14:14 Mike B Johnson via Digitalmars-d-learn 
wrote:
> On Monday, 5 June 2017 at 01:42:55 UTC, Jonathan M Davis wrote:
> > On Monday, June 05, 2017 01:30:47 Mike B Johnson via
> >
> > Digitalmars-d-learn wrote:
> >> [...]
> >
> > It's not a bug. The alias this conversion only goes one way. It
> > provides a way to convert _from_ the type that it's declared on
> > to another type, not from the other type to the type that it's
> > declared on. There is no way in D to declare an implicit
> > conversion in the direction you're trying. So, if you have a
> > struct that wraps an int like this, and you want to assign it
> > an int, you're going to need to explicitly construct the struct
> > - e.g. EnumX(1).
> >
> > - Jonathan M Davis
>
> That's pretty crappy! Defeats the whole point!

Well, implicit conversions tend to cause a lot of bugs in C++ code, so
Walter decided to restrict them quite a bit more in D than they are in C++.
This therefore prevents a number of bugs in D, but it also prevents implicit
conversions from being used in a number of situations where they're useful.
Whether the end result is better or worse, I don't know and certainly YMMV.
As it is, some of the implicit conversions that we still allow have a
tendency to cause bugs (e.g. conversions between integral values and
character types tend to be error-prone - especially when arrays are involved
- and using implicit conversions with templated code is almost always a bad
idea). So, at times, I tend to think that all implicit conversions should be
banned. But at other times, it would be really nice to be able to have more
than we do (e.g. it would be a lot more user-friendly if you could pass a T
to a function that takes a Nullable!T).

In any case, I think that the reality of the matter with D is that you tend
to have to use explicit conversions rather than implicit ones, and if you're
looking to do much with implicit conversions, you're usually going to be
frustrated, and obviously, that sucks, but at least you're less likely to
have bugs related to implicit conversions.

- Jonathan M Davis



Re: Make enum auto castable

2017-06-04 Thread Mike B Johnson via Digitalmars-d-learn

On Monday, 5 June 2017 at 01:42:55 UTC, Jonathan M Davis wrote:
On Monday, June 05, 2017 01:30:47 Mike B Johnson via 
Digitalmars-d-learn wrote:

[...]


It's not a bug. The alias this conversion only goes one way. It 
provides a way to convert _from_ the type that it's declared on 
to another type, not from the other type to the type that it's 
declared on. There is no way in D to declare an implicit 
conversion in the direction you're trying. So, if you have a 
struct that wraps an int like this, and you want to assign it 
an int, you're going to need to explicitly construct the struct 
- e.g. EnumX(1).


- Jonathan M Davis


That's pretty crappy! Defeats the whole point!


Re: Make enum auto castable

2017-06-04 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, June 05, 2017 01:30:47 Mike B Johnson via Digitalmars-d-learn 
wrote:
> enum X : EnumX
> {
> a = 1,
> }
>
>
> struct EnumX
> {
>   int x;
>   alias x this;
>   void opAssign(int y)
>   {
>   x = y;
>   }
>   double opCall()
>   {
>  return x;
>   }
> }
>
> doesn't work because "1" is not castable to EnumX, even though
> EnumX is aliased to an int, and hence it should work fine.
>
> Seems like a bug to me.

It's not a bug. The alias this conversion only goes one way. It provides a
way to convert _from_ the type that it's declared on to another type, not
from the other type to the type that it's declared on. There is no way in D
to declare an implicit conversion in the direction you're trying. So, if you
have a struct that wraps an int like this, and you want to assign it an int,
you're going to need to explicitly construct the struct - e.g. EnumX(1).

- Jonathan M Davis



Re: Make enum auto castable

2017-06-04 Thread Mike B Johnson via Digitalmars-d-learn

On Monday, 5 June 2017 at 00:51:15 UTC, Jonathan M Davis wrote:
On Monday, June 05, 2017 00:16:15 Mike B Johnson via 
Digitalmars-d-learn wrote:

On Sunday, 4 June 2017 at 23:39:11 UTC, Jonathan M Davis wrote:
> [...]

I might be able to change the enum, I assume you mean 
something like


enum myenum : S { }

where S is the struct that implicitly converts?


Yes.

However, be aware that you can currently only define one alias 
this per type. So, the rest of the code will then need to be 
able to deal with the fact that the enum is a struct that 
implicitly converts to VARIANT and does not implicitly convert 
to int. So, if you're just passing the enums around and 
comparing them, you're fine, but if you need to treat them as 
ints somewhere, then you'll need to provide an explicit 
conversion (via overloading opCast or by creating a specific 
function for it or just exposing a member with the int value or 
whatever), and that could get annoying in the same way that 
you're annoyed about the VARIANT issue right now.


But if you don't actually need to treat the enum as an int, and 
you can make it a struct that implicitly converts to VARIANT 
instead, then that will fix your VARIANT conversion problem.


- Jonathan M Davis




enum X : EnumX
{
   a = 1,
}


struct EnumX
{
int x;
alias x this;
void opAssign(int y)
{
x = y;
}
double opCall()
{
return x;
}
}

doesn't work because "1" is not castable to EnumX, even though 
EnumX is aliased to an int, and hence it should work fine.


Seems like a bug to me.



Re: Make enum auto castable

2017-06-04 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, June 05, 2017 01:12:20 Mike B Johnson via Digitalmars-d-learn 
wrote:
> Well, I do need to to treat it as an int at times and opCast only
> works with cast. While I could set it up to do a cast(VARIANT),
> which is better than nothing, I'd get same result as to!VARIANT,
> which is shorter and effectively the same.
>
> When will we get multiple alias this? all I need is two?
>
> Hell, why not make alias this an "overloadable" function similar
> to opCast and such?

I don't know when we're getting multiple alias thises. TDPL talks about it
being a thing, and the spec claims that it's a thing, but until someone
implements it, we won't have it, and it hasn't been a priority for Walter.
IIRC, someone tried to implement it at one point, but I don't know where
that went. There was a thread in the main newsgroup a couple of months ago
about how to simulate multiple alias thises, so you might want to check that
out:

https://forum.dlang.org/post/uniyvmvjopeyyxmph...@forum.dlang.org

- Jonathan M Davis



Re: Make enum auto castable

2017-06-04 Thread Mike B Johnson via Digitalmars-d-learn

On Monday, 5 June 2017 at 00:51:15 UTC, Jonathan M Davis wrote:
On Monday, June 05, 2017 00:16:15 Mike B Johnson via 
Digitalmars-d-learn wrote:

On Sunday, 4 June 2017 at 23:39:11 UTC, Jonathan M Davis wrote:
> On Sunday, June 04, 2017 22:52:55 Mike B Johnson via
>
> Digitalmars-d-learn wrote:
>> [...]
>
> Aside from whatever implicit conversions are built into the 
> language, the only way to define an implicit conversion in D 
> is via alias this on a user-defined type, which then tells 
> that type that it can convert to whatever type the result of 
> the alias this is. e.g. if you have

>
> [...]

I might be able to change the enum, I assume you mean 
something like


enum myenum : S { }

where S is the struct that implicitly converts?


Yes.

However, be aware that you can currently only define one alias 
this per type. So, the rest of the code will then need to be 
able to deal with the fact that the enum is a struct that 
implicitly converts to VARIANT and does not implicitly convert 
to int. So, if you're just passing the enums around and 
comparing them, you're fine, but if you need to treat them as 
ints somewhere, then you'll need to provide an explicit 
conversion (via overloading opCast or by creating a specific 
function for it or just exposing a member with the int value or 
whatever), and that could get annoying in the same way that 
you're annoyed about the VARIANT issue right now.


But if you don't actually need to treat the enum as an int, and 
you can make it a struct that implicitly converts to VARIANT 
instead, then that will fix your VARIANT conversion problem.


- Jonathan M Davis


Well, I do need to to treat it as an int at times and opCast only 
works with cast. While I could set it up to do a cast(VARIANT), 
which is better than nothing, I'd get same result as to!VARIANT, 
which is shorter and effectively the same.


When will we get multiple alias this? all I need is two?

Hell, why not make alias this an "overloadable" function similar 
to opCast and such?




Re: Make enum auto castable

2017-06-04 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, June 05, 2017 00:16:15 Mike B Johnson via Digitalmars-d-learn 
wrote:
> On Sunday, 4 June 2017 at 23:39:11 UTC, Jonathan M Davis wrote:
> > On Sunday, June 04, 2017 22:52:55 Mike B Johnson via
> >
> > Digitalmars-d-learn wrote:
> >> [...]
> >
> > Aside from whatever implicit conversions are built into the
> > language, the only way to define an implicit conversion in D is
> > via alias this on a user-defined type, which then tells that
> > type that it can convert to whatever type the result of the
> > alias this is. e.g. if you have
> >
> > [...]
>
> I might be able to change the enum, I assume you mean something
> like
>
> enum myenum : S { }
>
> where S is the struct that implicitly converts?

Yes.

However, be aware that you can currently only define one alias this per
type. So, the rest of the code will then need to be able to deal with the
fact that the enum is a struct that implicitly converts to VARIANT and does
not implicitly convert to int. So, if you're just passing the enums around
and comparing them, you're fine, but if you need to treat them as ints
somewhere, then you'll need to provide an explicit conversion (via
overloading opCast or by creating a specific function for it or just
exposing a member with the int value or whatever), and that could get
annoying in the same way that you're annoyed about the VARIANT issue right
now.

But if you don't actually need to treat the enum as an int, and you can make
it a struct that implicitly converts to VARIANT instead, then that will fix
your VARIANT conversion problem.

- Jonathan M Davis



Re: Make enum auto castable

2017-06-04 Thread Mike B Johnson via Digitalmars-d-learn

On Sunday, 4 June 2017 at 23:39:11 UTC, Jonathan M Davis wrote:
On Sunday, June 04, 2017 22:52:55 Mike B Johnson via 
Digitalmars-d-learn wrote:

[...]


Aside from whatever implicit conversions are built into the 
language, the only way to define an implicit conversion in D is 
via alias this on a user-defined type, which then tells that 
type that it can convert to whatever type the result of the 
alias this is. e.g. if you have


[...]


I might be able to change the enum, I assume you mean something 
like


enum myenum : S { }

where S is the struct that implicitly converts?


Re: Make enum auto castable

2017-06-04 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, June 04, 2017 22:52:55 Mike B Johnson via Digitalmars-d-learn 
wrote:
> I am dealing with some COM stuff and some functions use VARIANT,
> which can hold an enum.
>
> Instead of having to manually convert the enum(and for that
> matter, other things) to VARIANT, is it possible to have them
> automatically converted?
>
> This is because an enum is always convertible to a VARIANT but
> not the other way around. So, when a enum is passed to a function
> accepting a VARIANT, it should just work. Overloading is not an
> option.

Aside from whatever implicit conversions are built into the language, the
only way to define an implicit conversion in D is via alias this on a
user-defined type, which then tells that type that it can convert to
whatever type the result of the alias this is. e.g. if you have

struct S
{
int x;
alias x this;
}

then S can implicitly convert to int, and when it does, the value of x is
used (alternatively, a member function could be used, in which case, the
result of the member function would be used as the result of the
conversion). So, that allows you to tell how to convert a type _to_ another
type, but it does not allow you to convert _from_ another type. So, if
you're implicitly converting from type A to type B, it will work if type A
has been told how to convert to B, but there is no way for B to say that an
A can be converted to a B. Only A can define the conversion.

So, if you have control of the definition of the base type of the enum, then
you can define an alias this on it to convert to a VARIANT, but if you don't
have control over the definition of the base type of the enum (e.g. if it's
int, as is the default), then you're out of luck. And if you're dealing with
COM, then I'm guessing that your enum has a base type of int, and you
obviously don't control the definition of int, so you can't add an alias
this to it.

So, if you can't change the enum, and you can't change the function that
you're calling, then you'll have to insert something in between - be it a
conversion function, an explicit construction of VARIANT with the enum, or
some kind of wrapper function around the one that you're calling. But unless
the enum itself knows how to implicitly convert to a VARIANT thanks to alias
this, there is no implicit conversion.

std.typecons.Nullable has this sort of problem, which has historically
forced folks to do stuff like Nullable!int(42) when passing the actual type
to a function that accepts a Nullable wrapper around the type, which is
pretty annoying. Recently, a nullable function was added to std.typecons
which uses IFTI to infer the type of the Nullable

auto nullable(T)(T t)
{
return Nullable!T(t);
}

and then you could pass nullable(42) instead of Nullable!int(42), so it's
more user-friendly, but it still requires an explicit conversion unless you
overload the function. It's a downside to D's stricter approach to implicit
conversions.

- Jonathan M Davis



Re: Make enum auto castable

2017-06-04 Thread Laeeth Isharc via Digitalmars-d-learn

On Sunday, 4 June 2017 at 22:52:55 UTC, Mike B Johnson wrote:
I am dealing with some COM stuff and some functions use 
VARIANT, which can hold an enum.


Instead of having to manually convert the enum(and for that 
matter, other things) to VARIANT, is it possible to have them 
automatically converted?


This is because an enum is always convertible to a VARIANT but 
not the other way around. So, when a enum is passed to a 
function accepting a VARIANT, it should just work. Overloading 
is not an option.


Not sure if this breaks your requirement but you could generate 
overloads or rather templated version of your variant accepting 
function  with a mixin that introspects on functions with a 
certain uda in the module.  See excel-d for an example.




Make enum auto castable

2017-06-04 Thread Mike B Johnson via Digitalmars-d-learn
I am dealing with some COM stuff and some functions use VARIANT, 
which can hold an enum.


Instead of having to manually convert the enum(and for that 
matter, other things) to VARIANT, is it possible to have them 
automatically converted?


This is because an enum is always convertible to a VARIANT but 
not the other way around. So, when a enum is passed to a function 
accepting a VARIANT, it should just work. Overloading is not an 
option.