Thread overview
TickDuration.to's second template parameter
Apr 08, 2012
Kapps
Apr 08, 2012
Jonathan M Davis
Apr 09, 2012
Jonathan M Davis
Apr 08, 2012
Jonathan M Davis
Apr 08, 2012
Kapps
Apr 08, 2012
Jonathan M Davis
April 07, 2012
Whenever I use TickDuration.to, I need to add the pesky second argument, e.g. TickDuration.to!("nsecs", uint). Would a default make sense there?

Also, double doesn't work, although I sometimes could use that.


Thoughts? Destroyers?

Andrei
April 08, 2012
On Saturday, 7 April 2012 at 20:59:48 UTC, Andrei Alexandrescu wrote:
> Whenever I use TickDuration.to, I need to add the pesky second argument, e.g. TickDuration.to!("nsecs", uint). Would a default make sense there?
>
> Also, double doesn't work, although I sometimes could use that.
>
>
> Thoughts? Destroyers?
>
> Andrei

Isn't this what the TickDuration.msecs / seconds / etc properties are for?
April 08, 2012
On Saturday, April 07, 2012 15:59:57 Andrei Alexandrescu wrote:
> Whenever I use TickDuration.to, I need to add the pesky second argument, e.g. TickDuration.to!("nsecs", uint). Would a default make sense there?

Well TickDuration.nsecs is a wrapper for TickDuration.to!("nsecs", long"), TickDuration.msecs is a wrapper for TickDuration.to!("msecs, long"), etc. So, that's basically how defaults were added. I question that it makes sense to add defaults to the to function itself - though having long chosen as the default doesn't really help you, since you'll either have to be explicit like you have been or cast using the default version.

auto value = td.to!("nsecs", uint)();

or

auto value = cast(uint)td.nsecs;

> Also, double doesn't work, although I sometimes could use that.

As for double not working, that sounds like a bug. It uses __traits(isFloating, T) if the type isn't an integral type and therefore should work with floating point values. IIRC, SHOO originally had some other wrapper functions for defaulting to real, which I removed because it made it too confusing to keep the long vs real functions straight, but double and real should still work. It _does_ look like real is used with it in some of the unit tests, but I don't think double is. If it doesn't work though, that sounds like a bug (either in dmd or druntime, depending on why it doesn't work).

- Jonathan M Davis
April 08, 2012
On Saturday, April 07, 2012 15:59:57 Andrei Alexandrescu wrote:
> Whenever I use TickDuration.to, I need to add the pesky second argument, e.g. TickDuration.to!("nsecs", uint). Would a default make sense there?
> 
> Also, double doesn't work, although I sometimes could use that.
> 
> 
> Thoughts? Destroyers?

That's odd. I was sure that I responded to this earlier, but my post seems to have disappeared. So, I'll try again.

TickDuration has the seconds, msecs, usecs, and nsecs functions which effectively gives you to with a default of long for each of the units supported by TickDuration. So, that's the closest that it has to default arguments. I don't think that it would really make sense to give to default arguments to to on top of that. So, if you really want uint rather than long, you'd do either

auto value = td.to!("nsecs", uint)();

or

auto value = cast(uint)td.nsecs;

As for double, it should work. SHOO had had functions similar to seconds, msecs, usecs, and nsecs which defaulted to real, but I removed them a while back, because it made it too confusing to keep them all straight. But to should work with integral values with a size of at least 4 bytes as well as all floating point types. The unit tests do test real, but they don't test double at all. So, it's possible that there's a bug which prevents it from working, but both float and double should work. If they don't, it's a bug which needs to be reported and fixed.

- Jonathan M Davis
April 08, 2012
On Sunday, 8 April 2012 at 04:09:45 UTC, Jonathan M Davis wrote:
> As for double, it should work. SHOO had had functions similar to seconds,
> msecs, usecs, and nsecs which defaulted to real, but I removed them a while
> back, because it made it too confusing to keep them all straight. But to
> should work with integral values with a size of at least 4 bytes as well as
> all floating point types. The unit tests do test real, but they don't test
> double at all. So, it's possible that there's a bug which prevents it from
> working, but both float and double should work. If they don't, it's a bug which
> needs to be reported and fixed.
>
> - Jonathan M Davis

That's actually something I've been wondering about for a while. I have never once (once I knew that they returned fixed point numbers and fixed the bugs that caused) used the msecs/seconds/etc properties, because you almost never want such low precision. It would be much nicer to be able to just write .seconds instead of .to!("float", seconds), but returning a ulong prevents me being able to do that. Is there any reason those properties don't return float or double? It's probably too late to do anything about that at this point though even if it was desired.

April 08, 2012
On Sunday, April 08, 2012 06:45:20 Kapps wrote:
> On Sunday, 8 April 2012 at 04:09:45 UTC, Jonathan M Davis wrote:
> > As for double, it should work. SHOO had had functions similar
> > to seconds,
> > msecs, usecs, and nsecs which defaulted to real, but I removed
> > them a while
> > back, because it made it too confusing to keep them all
> > straight. But to
> > should work with integral values with a size of at least 4
> > bytes as well as
> > all floating point types. The unit tests do test real, but they
> > don't test
> > double at all. So, it's possible that there's a bug which
> > prevents it from
> > working, but both float and double should work. If they don't,
> > it's a bug which
> > needs to be reported and fixed.
> > 
> > - Jonathan M Davis
> 
> That's actually something I've been wondering about for a while. I have never once (once I knew that they returned fixed point numbers and fixed the bugs that caused) used the msecs/seconds/etc properties, because you almost never want such low precision. It would be much nicer to be able to just write .seconds instead of .to!("float", seconds), but returning a ulong prevents me being able to do that. Is there any reason those properties don't return float or double? It's probably too late to do anything about that at this point though even if it was desired.

There were properties which did both, but they were confusing, because it wasn't obvious which used long and which used real. Using long matched everything else in core.time and std.datetime, and none of the rest used floating point values for anything, so that's what was kept. But you should be able to use to!("float", seconds). If that doesn't work, it's a bug. float, double, and real should all work with TickDuration's to.

- Jonathan M Davis
April 09, 2012
On Sat, 07 Apr 2012 20:03:25 -0400, Jonathan M Davis <jmdavisProg@gmx.com> wrote:

> On Saturday, April 07, 2012 15:59:57 Andrei Alexandrescu wrote:
>> Whenever I use TickDuration.to, I need to add the pesky second argument,
>> e.g. TickDuration.to!("nsecs", uint). Would a default make sense there?
>
> Well TickDuration.nsecs is a wrapper for TickDuration.to!("nsecs", long"),
> TickDuration.msecs is a wrapper for TickDuration.to!("msecs, long"), etc. So,
> that's basically how defaults were added. I question that it makes sense to
> add defaults to the to function itself - though having long chosen as the
> default doesn't really help you, since you'll either have to be explicit like
> you have been or cast using the default version.

I think what Andrei is asking for is to change this:

T to(string units, T)() @safe const pure nothrow

Into this:

T to(string units, T = long)() @safe const pure nothrow

Which I don't think will hurt anything.

An additional annoyance that I would think is solved is you always have to include the parentheses.  i.e.:

td.to!"msecs"()

vs.

td.to!("msecs", long)();

-Steve
April 09, 2012
On Monday, April 09, 2012 09:36:45 Steven Schveighoffer wrote:
> On Sat, 07 Apr 2012 20:03:25 -0400, Jonathan M Davis <jmdavisProg@gmx.com>
> 
> wrote:
> > On Saturday, April 07, 2012 15:59:57 Andrei Alexandrescu wrote:
> >> Whenever I use TickDuration.to, I need to add the pesky second argument, e.g. TickDuration.to!("nsecs", uint). Would a default make sense there?
> > 
> > Well TickDuration.nsecs is a wrapper for TickDuration.to!("nsecs",
> > long"),
> > TickDuration.msecs is a wrapper for TickDuration.to!("msecs, long"),
> > etc. So,
> > that's basically how defaults were added. I question that it makes sense
> > to
> > add defaults to the to function itself - though having long chosen as the
> > default doesn't really help you, since you'll either have to be explicit
> > like
> > you have been or cast using the default version.
> 
> I think what Andrei is asking for is to change this:
> 
> T to(string units, T)() @safe const pure nothrow
> 
> Into this:
> 
> T to(string units, T = long)() @safe const pure nothrow
> 
> Which I don't think will hurt anything.
> 
> An additional annoyance that I would think is solved is you always have to include the parentheses. i.e.:
> 
> td.to!"msecs"()
> 
> vs.
> 
> td.to!("msecs", long)();

We could add that, but why? td.msecs already does what td.to!"msecs"() would do if to defaulted to long. I don't see any reason to use to directly unless you're using something other than long. And if you use a type of than long, you're going to have to provide the whole thing anyway - e.g. td.to!("msecs", uint)().

- Jonathan M Davis
April 09, 2012
On Mon, 09 Apr 2012 13:05:09 -0400, Jonathan M Davis <jmdavisProg@gmx.com> wrote:

> On Monday, April 09, 2012 09:36:45 Steven Schveighoffer wrote:
>> I think what Andrei is asking for is to change this:
>>
>> T to(string units, T)() @safe const pure nothrow
>>
>> Into this:
>>
>> T to(string units, T = long)() @safe const pure nothrow
>
> We could add that, but why?

I don't know.  Andrei has the use case ;)  Perhaps he has a template string instead of directly calling the symbol.

I was just clarifying what I think he was asking for, it seemed to be misunderstood...

-Steve
April 09, 2012
On 4/9/12 12:05 PM, Jonathan M Davis wrote:
> We could add that, but why? td.msecs already does what td.to!"msecs"() would
> do if to defaulted to long. I don't see any reason to use to directly unless
> you're using something other than long. And if you use a type of than long,
> you're going to have to provide the whole thing anyway - e.g. td.to!("msecs",
> uint)().

My bad, I didn't know about td.msecs and friends.

Andrei