Rant: Date and Time fall short of simplicity in D

Steven Schveighoffer schveiguy at yahoo.com
Fri Mar 29 19:46:27 PDT 2013


On Fri, 29 Mar 2013 18:08:28 -0400, Jonathan M Davis <jmdavisProg at gmx.com>  
wrote:

> std.conv.to is the standard way to convert one type to another. I see no
> reason to introduce stuff specific to core.time or std.datetime to do
> conversions. It should just hook into the standard stuff for that. If
> everything uses std.conv.to for coverting between types, then you don't  
> have
> to worry about figuring out how a particular programmer decided that  
> their API
> should do it - be it with casts or asOtherType toOtherType or whatever.
> std.conv.to is specifically designed so that any type can hook their own
> conversions into it, and then you can just always use std.conv.to for
> converting types.

But the one doing the work is core.time.  In essence, you have locked away  
part of the API behind cast, and in order to get it out without using  
cast, you have to import another module.

opCast is just a function, it could easily be called opTo, or simply  
to(T)().

>> If std.conv.to cannot work on type-defined conversions without opCast,
>> then it is poorly implemented. There needs to be a better mechanism.
>
> I don't see why. std.conv.to specifically checks for opCast, not just  
> that it
> can cast. So, there's nothing unsafe about it. Having it look for a  
> function
> named convert wouldn't be any safer.

Right, it's not std.conv.to that is the problem, it's the fact that you  
then have to expose your type to possible arbitrary casting.  One mistake,  
or refactor, and you have have thrown away const inadvertently.

There should be a safer way to hook 'to'.

> The only reason I see to object to opCast being used is that it's then
> possible to use cast(Type) rather than to!Type, and if you object to  
> casts
> being used that way, then having std.conv.to use opCast makes it more  
> likely
> that cast(Type) will work, because people will define it on their types  
> so that
> they'll work with std.conv.to.

This is exactly my objection.  People (like the OP in this thread) don't  
think about opCast being specifically for use with std.conv.to, they just  
use it as cast(X), which can be dangerous.

> But since opCast is really just syntactic sugar that allows you to use  
> the
> cast operator, and casting rarely works on user-defined types without  
> opCast
> anyway (aside from converting between classes in an inheritance  
> hierarchy), I
> really don't agree that opCast is particularly dangerous. If opCast isn't
> defined, odds are the cast won't work. And if it is, then there's really  
> no
> difference between using the cast operator and an explicit function  
> except that
> by using the cast operator, you're plugging into the language's  
> conversion
> mechanism syntactically, and std.conv.to will then work for your type.  
> And if
> you prefer std.conv.to to casting, then just use std.conv.to.

I've already found problems with std.conv.to and arbitrary casting.  See  
this bug:

http://d.puremagic.com/issues/show_bug.cgi?id=6288

If you aren't careful, you can easily end up casting away const without  
intending to.  If phobos can get it wrong, so can average developers.

> But the built-in casts are restricted enough on user-defined types, that  
> I
> really don't see any problem with using opCast on user-defined types and  
> then
> casting, and std.conv.to goes the extra mile of only using the cast if  
> opCast
> is explicitly defined, so it won't use any dangerous casts even if there  
> are
> any.

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 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.

-Steve


More information about the Digitalmars-d mailing list