December 21, 2014
On 12/20/14 3:36 AM, Jonathan Marler wrote:

> Nobody likes to use cast, but for now we are stuck with it. Creating
> alternatives to cast would be a great thing to discuss but doesn't
> really apply to the point at hand, which is, would cast(auto) be a
> useful extension to our current cast operator?  I think it could be.  In
> my opinion, if we allow return value types to be written as "auto" then
> it makes since to have cast(auto) as well.  In both cases the developer
> would need to look somewhere else to find what type "auto" actually gets
> resolved to.

You have to be careful here, when you think about who is in charge of what.

For an auto return, it is the function author who is deciding what auto should resolve to. But cast(auto) is letting the author of the called function dictate. This is a decoupling of who is responsible for the type vs. who is requesting the cast.

Now, just 'auto' is fine, because you are not subverting the type system, and unsafe behavior cannot result. But with something like 'cast', you are potentially playing with fire.

For instance, let's say you have a function which accepts an int, but the author changes it later to accept a pointer to an int. You are passing in a size_t, via cast(auto), now the compiler happily reinterprets the size_t as a pointer, and you are in dangerous territory.

You can think of it this way. With cast(T), you are saying "I've examined the possibilities of casting this value to type T, I know what I'm doing". With cast(auto) you are saying "I'm OK with this value casting to any other value that cast may work with. I know what I'm doing." I find that the requirement of just typing "cast(auto)" does not match the gravity of the analysis that is required to ensure that is true.

-Steve
December 21, 2014
On Sunday, 21 December 2014 at 03:04:05 UTC, Steven Schveighoffer wrote:
> On 12/20/14 3:36 AM, Jonathan Marler wrote:
>
>> Nobody likes to use cast, but for now we are stuck with it. Creating
>> alternatives to cast would be a great thing to discuss but doesn't
>> really apply to the point at hand, which is, would cast(auto) be a
>> useful extension to our current cast operator?  I think it could be.  In
>> my opinion, if we allow return value types to be written as "auto" then
>> it makes since to have cast(auto) as well.  In both cases the developer
>> would need to look somewhere else to find what type "auto" actually gets
>> resolved to.
>
> You have to be careful here, when you think about who is in charge of what.
>
> For an auto return, it is the function author who is deciding what auto should resolve to. But cast(auto) is letting the author of the called function dictate. This is a decoupling of who is responsible for the type vs. who is requesting the cast.
>
> Now, just 'auto' is fine, because you are not subverting the type system, and unsafe behavior cannot result. But with something like 'cast', you are potentially playing with fire.
>
> For instance, let's say you have a function which accepts an int, but the author changes it later to accept a pointer to an int. You are passing in a size_t, via cast(auto), now the compiler happily reinterprets the size_t as a pointer, and you are in dangerous territory.
>
> You can think of it this way. With cast(T), you are saying "I've examined the possibilities of casting this value to type T, I know what I'm doing". With cast(auto) you are saying "I'm OK with this value casting to any other value that cast may work with. I know what I'm doing." I find that the requirement of just typing "cast(auto)" does not match the gravity of the analysis that is required to ensure that is true.
>
> -Steve

That is a case I hadn't initially thought of.  I definitely don't like that.

As for the typed cast, what about when the function argument is changed from a byte to a short?  If the initial caller was using cast(byte) and doesn't change to cast(short), then you are also creating a bug.  I feel like you're going to get different bugs either way.  Both the typed and auto-typed cast seem to be just as dangerous.  That's not really an argument to have auto-cast, I'm just making an observation.

I noticed your other comment about wanting a double-typed cast.  I could see that being useful especially if we did something like this:

  When a cast is performed, the source and target type must match the expected types EXACTLY.

int y;
ushort x = cast(byte, int)y; // cast from int to byte

This should definitely produce an error.  This code could exist if x was initially a byte and was later changed to a ushort. I think this feature would make casts alot safer because any time a type was changed you would get an error saying you need to go update all your casts. What do you think?
December 21, 2014
On 12/21/14 3:23 AM, Jonathan Marler wrote:

> As for the typed cast, what about when the function argument is changed
> from a byte to a short?  If the initial caller was using cast(byte) and
> doesn't change to cast(short), then you are also creating a bug.  I feel
> like you're going to get different bugs either way.  Both the typed and
> auto-typed cast seem to be just as dangerous.  That's not really an
> argument to have auto-cast, I'm just making an observation.

But as the author, you have examined your code, and determined it's OK to have whatever expression you are using cast to a byte. This means you are sure it won't exceed the byte range. I don't see how this is a bug.

> I noticed your other comment about wanting a double-typed cast. I could
> see that being useful especially if we did something like this:
>
>    When a cast is performed, the source and target type must match the
> expected types EXACTLY.
>
> int y;
> ushort x = cast(byte, int)y; // cast from int to byte
>
> This should definitely produce an error.  This code could exist if x was
> initially a byte and was later changed to a ushort. I think this feature
> would make casts alot safer because any time a type was changed you
> would get an error saying you need to go update all your casts. What do
> you think?

I didn't think of it that way, I would assume that cast(byte, int) would only error if the cast-from type is not int, not if the expression used the result in any way other than a byte.

But it does have appeal.

-Steve
December 21, 2014
>> I noticed your other comment about wanting a double-typed cast. I could
>> see that being useful especially if we did something like this:
>>
>>   When a cast is performed, the source and target type must match the
>> expected types EXACTLY.
>>
>> int y;
>> ushort x = cast(byte, int)y; // cast from int to byte
>>
>> This should definitely produce an error.  This code could exist if x was
>> initially a byte and was later changed to a ushort. I think this feature
>> would make casts alot safer because any time a type was changed you
>> would get an error saying you need to go update all your casts. What do
>> you think?
>
> I didn't think of it that way, I would assume that cast(byte, int) would only error if the cast-from type is not int, not if the expression used the result in any way other than a byte.
>
> But it does have appeal.
>
> -Steve

It seems alot of the potential bugs from casting can occur when one of the types change.  If we forced the cast operator to match the type(s) exactly then it would eliminate all these bugs.
December 21, 2014
On Sun, 21 Dec 2014 15:20:44 +0000
Jonathan Marler via Digitalmars-d <digitalmars-d@puremagic.com> wrote:

> It seems alot of the potential bugs from casting can occur when one of the types change.  If we forced the cast operator to match the type(s) exactly then it would eliminate all these bugs.
that is what i mean by "don't use hacks"! what many people think about when there is need to convert from one type to another? CAST IT! not "convert it", but "cast it". but we have idiomatic "to!" for type conversion.

still puzzled a little? ;-) i'm about "hide that cast in system module in faraway land" again.

  int z;
  short a;
  z.castassignto!(short)(a); // OK
  z.castassignto!(byte)(a); // FAIL

this is ugly? yes, exactly as it should be. this is working? yes. we can use it to enforce both types too:

  castassignto!(int, short)(z, a);

will this work? oops, nope... as we have no control on argument type deduction for templates, one can write:

  z.castassignto!(a);

ahem... is this `cast(auto)`? ;-)


ok, to make a long story short: the idea is to replace explicit casts by templated casts. templates gives us more control, can have more arguments and if we'll do a ER that allows us to control argument type deduction will give us way to control what must be specified and what can be omited.


December 21, 2014
On Sun, 21 Dec 2014 15:20:44 +0000
Jonathan Marler via Digitalmars-d <digitalmars-d@puremagic.com> wrote:

  `z.castassignto(a);`, of course. ;-)


December 24, 2014
On 12/20/14 6:47 PM, Steven Schveighoffer wrote:
> On 12/20/14 5:20 AM, Dicebot wrote:
>
>> I'd like to have a cast where you must define both "from" and "to" types
>> precisely.
>
> I was actually thinking the same thing. This would be almost
> future-proof (any changes to either side would result in failed
> compilation).
>
> -Steve

Specifying two types instead of one in a "to" call should achieve that. -- Andrei
December 29, 2014
On Wednesday, 24 December 2014 at 03:11:40 UTC, Andrei Alexandrescu wrote:
> On 12/20/14 6:47 PM, Steven Schveighoffer wrote:
>> On 12/20/14 5:20 AM, Dicebot wrote:
>>
>>> I'd like to have a cast where you must define both "from" and "to" types
>>> precisely.
>>
>> I was actually thinking the same thing. This would be almost
>> future-proof (any changes to either side would result in failed
>> compilation).
>>
>> -Steve
>
> Specifying two types instead of one in a "to" call should achieve that. -- Andrei

This is different. `to` is about "smart" conversion (and potentially costly with allocations flying around) - we are speaking about same basic dumb cast here, just more controlled.
December 29, 2014
On 12/29/14 6:08 AM, Dicebot wrote:
> On Wednesday, 24 December 2014 at 03:11:40 UTC, Andrei Alexandrescu wrote:
>> On 12/20/14 6:47 PM, Steven Schveighoffer wrote:
>>> On 12/20/14 5:20 AM, Dicebot wrote:
>>>
>>>> I'd like to have a cast where you must define both "from" and "to"
>>>> types
>>>> precisely.
>>>
>>> I was actually thinking the same thing. This would be almost
>>> future-proof (any changes to either side would result in failed
>>> compilation).
>>>
>>> -Steve
>>
>> Specifying two types instead of one in a "to" call should achieve
>> that. -- Andrei
>
> This is different. `to` is about "smart" conversion (and potentially
> costly with allocations flying around) - we are speaking about same
> basic dumb cast here, just more controlled.

I see. I guess it's easy to add std.conv.explicitCast and std.conv.implicitCast if there's enough impetus for it. -- Andrei

December 29, 2014
On Monday, 29 December 2014 at 15:50:15 UTC, Andrei Alexandrescu wrote:
> I see. I guess it's easy to add std.conv.explicitCast and std.conv.implicitCast if there's enough impetus for it. -- Andrei

Yes, exactly. That was why I have asked general opinion about it - don't want to add yet another utility no one uses. I will probably go and just add it anyway :  https://github.com/D-Programming-Language/phobos/pull/2822