Rant: Date and Time fall short of simplicity in D

Artur Skawina art.08.09 at gmail.com
Sat Mar 30 01:53:49 PDT 2013


On 03/30/13 09:22, Jonathan M Davis wrote:
> On Saturday, March 30, 2013 09:15:24 Artur Skawina wrote:
>> On 03/30/13 07:12, Jonathan M Davis wrote:
>>> On Friday, March 29, 2013 22:46:27 Steven Schveighoffer wrote:
>>>> The issue is when you think you are invoking the opCast operator, but you
>>>> inadvertently end up casting using the compiler's type-bypassing version.
>>>> I agree the opCast call is safe, it's that its name coincides with the
>>>> "throw all typechecks away" operator.
>>>
>>> I'd have to experiment to see exactly what is and isn't accepted, but in
>>> my
>>> experience, the compiler rarely allows casting to or from structs without
>>> opCast (the same with classes except for the inheritance tree). So, I
>>> really don't think that there's much risk of accidentally using a cast on
>>> a user- defined type and have it use the built-in cast operator.
>>>
>>>> I don't think to should ignore opCast, or not use it, but there should be
>>>> a way to hook 'to' without using opCast.  And most types should prefer
>>>> that.
>>>
>>> I really just don't see a problem here. If opCast is defined, it's
>>> perfectly safe regardless of what would happen if you tried to cast
>>> without opCast being defined. It's also the language-defined way to do
>>> type conversions. And I really don't see any need to use anything else to
>>> make std.conv.to work. By using opCast, there's a standard way to define
>>> type conversion, and there's a standard way for it to hook into
>>> std.conv.to, which seems way better to me than trying to support every
>>> which way that a particular programmer wants to try and define a
>>> conversion function. Clearly, you think that using opCast is a problem,
>>> but I just don't agree. It's safe; it's standard; and it works.
>>    struct S {
>>       ubyte[] p;
>>    }
>>
>>    import std.stdio;
>>
>>    void main() {
>>       immutable a = S(null);
>>       // ...
>>       auto b = cast(S)a;
>>       writeln(typeof(a.p).stringof);
>>       writeln(typeof(b.p).stringof);
>>    }
>>
>> which can easily happen in generic code. And you can't tell w/o looking
>> at the S implementation whether it's safe or not (with an appropriate
>> opCast it could be).
> 
> You're casting away immutable. You pretty much have to assume that that's 
> unsafe and should never do it unless you know exactly what's going on with the 
> types involved. And no opCast is involved here, so I don't see how it's even 
> relevant to the discussion.

You can't tell if there is an opCast w/o looking at S. So it's either
a perfectly fine conversion, no-op, a potentially dangerous operation, or
an error. The compiler would have been able to catch the error, but by
overloading 'cast' you've prevented it from doing that.

> Built-in casts are dangerous. opCast is a completely different ballgame.

Exactly - this is the whole point. Overloading safe conversions and
raw explicit casts introduces a kind of bugs, which wouldn't be there
otherwise.

artur


More information about the Digitalmars-d mailing list