www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Please vote on std.datetime

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jonathan M. Davis has diligently worked on his std.datetime proposal, 
and it has been through a few review cycles in this newsgroup.

It's time to vote. Please vote for or against inclusion of datetime into 
Phobos, along with your reasons.


Thank you,

Andrei
Dec 09 2010
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday 09 December 2010 16:26:13 Andrei Alexandrescu wrote:
 Jonathan M. Davis has diligently worked on his std.datetime proposal,
 and it has been through a few review cycles in this newsgroup.
 
 It's time to vote. Please vote for or against inclusion of datetime into
 Phobos, along with your reasons.
Well, I'm obviously voting for inclusion. ;) I wrote it. I'm not about to claim that it's perfect, but overall I like it and think that it's quite good. Unfortunately, either most everyone likes it and has said nothing, or they (understandably) didn't want to read it. I would point out though, that as it stands, including std.datetime would require including my time module as core.time (which has been discussed to some extent with Sean, since it was pretty much his idea in the first place that some level of integration should occur there) as well as including my unittests module as something like std.unittests (which was reviewed here on some level, and has definitely been improved from its initial version, but hasn't exactly had overwhelming support). The unittest functions could be integrated privately into std.datetime, but I think that that would be a disservice to the community at large. Regardless, I'm obviously for including it. - Jonathan M Davis P.S. The most recent code is here: http://is.gd/hYwOV
Dec 09 2010
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/9/10 6:40 PM, Jonathan M Davis wrote:
 On Thursday 09 December 2010 16:26:13 Andrei Alexandrescu wrote:
 Jonathan M. Davis has diligently worked on his std.datetime proposal,
 and it has been through a few review cycles in this newsgroup.

 It's time to vote. Please vote for or against inclusion of datetime into
 Phobos, along with your reasons.
Well, I'm obviously voting for inclusion. ;) I wrote it. I'm not about to claim that it's perfect, but overall I like it and think that it's quite good. Unfortunately, either most everyone likes it and has said nothing, or they (understandably) didn't want to read it. I would point out though, that as it stands, including std.datetime would require including my time module as core.time (which has been discussed to some extent with Sean, since it was pretty much his idea in the first place that some level of integration should occur there) as well as including my unittests module as something like std.unittests (which was reviewed here on some level, and has definitely been improved from its initial version, but hasn't exactly had overwhelming support). The unittest functions could be integrated privately into std.datetime, but I think that that would be a disservice to the community at large. Regardless, I'm obviously for including it. - Jonathan M Davis P.S. The most recent code is here: http://is.gd/hYwOV
Duly noted, but you can't vote for your own proposal. Jury, please remove that from your memory. Andrei
Dec 09 2010
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday 09 December 2010 19:04:05 Andrei Alexandrescu wrote:
 On 12/9/10 6:40 PM, Jonathan M Davis wrote:
 On Thursday 09 December 2010 16:26:13 Andrei Alexandrescu wrote:
 Jonathan M. Davis has diligently worked on his std.datetime proposal,
 and it has been through a few review cycles in this newsgroup.
 
 It's time to vote. Please vote for or against inclusion of datetime into
 Phobos, along with your reasons.
Well, I'm obviously voting for inclusion. ;) I wrote it. I'm not about to claim that it's perfect, but overall I like it and think that it's quite good. Unfortunately, either most everyone likes it and has said nothing, or they (understandably) didn't want to read it. I would point out though, that as it stands, including std.datetime would require including my time module as core.time (which has been discussed to some extent with Sean, since it was pretty much his idea in the first place that some level of integration should occur there) as well as including my unittests module as something like std.unittests (which was reviewed here on some level, and has definitely been improved from its initial version, but hasn't exactly had overwhelming support). The unittest functions could be integrated privately into std.datetime, but I think that that would be a disservice to the community at large. Regardless, I'm obviously for including it. - Jonathan M Davis P.S. The most recent code is here: http://is.gd/hYwOV
Duly noted, but you can't vote for your own proposal. Jury, please remove that from your memory.
LOL. True enough. My vote obviously doesn't count. It would obviously be a bad sign though if I didn't think that it should be included. - Jonathan M Davis
Dec 09 2010
prev sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
Jonathan M Davis Wrote:
 
 I would point out though, that as it stands, including std.datetime would 
 require including my time module as core.time (which has been discussed to
some 
 extent with Sean, since it was pretty much his idea in the first place that
some 
 level of integration should occur there) as well as including my unittests 
 module as something like std.unittests (which was reviewed here on some level, 
 and has definitely been improved from its initial version, but hasn't exactly
had 
 overwhelming support). The unittest functions could be integrated privately
into 
 std.datetime, but I think that that would be a disservice to the community at 
 large.
I don't mean to confuse the issue, but since neither of these are necessary attributes of std.datetime, they shouldn't be considered as such. I think it's entirely reasonable for the unittest stuff to be made private and std.unittests to be created later, or for some code movement from Phobos to Druntime to occur later as well. For the uninformed, the latter issue came up because Druntime needs some structured way to represent durations for operations like Thread.sleep(), and the argument was made that Druntime use whatever duration type is in std.datetime rather than having a functionally similar type, possibly with a similar name, etc.
Dec 09 2010
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday 09 December 2010 22:39:39 Sean Kelly wrote:
 Jonathan M Davis Wrote:
 I would point out though, that as it stands, including std.datetime would
 require including my time module as core.time (which has been discussed
 to some extent with Sean, since it was pretty much his idea in the first
 place that some level of integration should occur there) as well as
 including my unittests module as something like std.unittests (which was
 reviewed here on some level, and has definitely been improved from its
 initial version, but hasn't exactly had overwhelming support). The
 unittest functions could be integrated privately into std.datetime, but
 I think that that would be a disservice to the community at large.
I don't mean to confuse the issue, but since neither of these are necessary attributes of std.datetime, they shouldn't be considered as such. I think it's entirely reasonable for the unittest stuff to be made private and std.unittests to be created later, or for some code movement from Phobos to Druntime to occur later as well.
A valid point, though the bug that makes all templates public would make it really annoying in my own code, since then my unittests module would clash with std.datetime every time that I included both in anything that I did. And if we did either add std.unittests temporarily without adding documentation to the site or the distributed zip (so, it's there, but it isn't - kind of like the current std.datetime) or if we make the functions private in std.datetime, we'll still have to make the decision at some point whether we want to make it an actual std.unittests. I'd also point out that it would probably be a bad idea to have your current core.time around just to be replaced by mine shortly thereafter. The change in duration type would break all of the code that uses it. Though if Thread.sleep() maintains its current API (in addition to the new duration version), then that wouldn't be as big a deal (and the old version should probably stay around in deprecated form for a while anyway - or at least it should be deprecated once the new version of Thread.sleep() is finalized). So, we do have options, but my version of core.time is critical to std.datetime working, and as you pointed out, it's better if we don't end up with multiple, incompatible duration types. And while we can put off deciding what exactly to do about std.unittests, we're going to have to have a temporary solution if we don't make a final (or at least pseudo-final) decision at this point, and we'd just be putting off making a final decision (though that's not necessarily a bad idea). Assuming that std.datetime is put into Phobos, I'd suggest just replacing your core.time with mine - particularly since yours is so new, and it doesn't provide any functionality that mine doesn't. I'd expect the changes to the rest of druntime would be quite minimal at this point. And unless we really think that my unittests module isn't likely to become std.unittests in any form, I'd suggest adding it as std.unittests without putting it in the documentation. That way, it's there, and we don't have to make muck with std.datetime to make it work without a separate unittests module, but we still have some leeway as to whether we keep it around. Other modules have been added in a similar manner before. - Jonathan M Davis
Dec 09 2010
prev sibling next sibling parent Seth Hoenig <seth.a.hoenig gmail.com> writes:
+1 for inclusion, including the unittests just the way they are.

Why? Because I've been waiting for a decent datetime module for a while and
this looks like one. There's no good reason not to include the unittests.
Yes, there is an abundance of them. But there's _huge_ potential for small,
off-by-one bugs in something like this, and I think maximum coverage, even
if some of it overlaps, can only be a good thing.




On Thu, Dec 9, 2010 at 8:40 PM, Jonathan M Davis <jmdavisProg gmx.com>wrote:

 On Thursday 09 December 2010 16:26:13 Andrei Alexandrescu wrote:
 Jonathan M. Davis has diligently worked on his std.datetime proposal,
 and it has been through a few review cycles in this newsgroup.

 It's time to vote. Please vote for or against inclusion of datetime into
 Phobos, along with your reasons.
Well, I'm obviously voting for inclusion. ;) I wrote it. I'm not about to claim that it's perfect, but overall I like it and think that it's quite good. Unfortunately, either most everyone likes it and has said nothing, or they (understandably) didn't want to read it. I would point out though, that as it stands, including std.datetime would require including my time module as core.time (which has been discussed to some extent with Sean, since it was pretty much his idea in the first place that some level of integration should occur there) as well as including my unittests module as something like std.unittests (which was reviewed here on some level, and has definitely been improved from its initial version, but hasn't exactly had overwhelming support). The unittest functions could be integrated privately into std.datetime, but I think that that would be a disservice to the community at large. Regardless, I'm obviously for including it. - Jonathan M Davis P.S. The most recent code is here: http://is.gd/hYwOV
Dec 09 2010
prev sibling next sibling parent reply "Yao G." <yao.gomez spam.gmail.com> writes:
On Thu, 09 Dec 2010 18:26:13 -0600, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Jonathan M. Davis has diligently worked on his std.datetime proposal,  
 and it has been through a few review cycles in this newsgroup.

 It's time to vote. Please vote for or against inclusion of datetime into  
 Phobos, along with your reasons.


 Thank you,

 Andrei
I hate the SysDate name (ugly). And I hate that I must link to advapi32.lib. And honestly, It gives me a strong kitchen-sinky vibe (there's too much functionality). But I vote yes. Solid library. -- Yao G.
Dec 09 2010
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday 09 December 2010 19:04:54 Yao G. wrote:
 On Thu, 09 Dec 2010 18:26:13 -0600, Andrei Alexandrescu
 
 <SeeWebsiteForEmail erdani.org> wrote:
 Jonathan M. Davis has diligently worked on his std.datetime proposal,
 and it has been through a few review cycles in this newsgroup.
 
 It's time to vote. Please vote for or against inclusion of datetime into
 Phobos, along with your reasons.
 
 
 Thank you,
 
 Andrei
I hate the SysDate name (ugly). And I hate that I must link to advapi32.lib. And honestly, It gives me a strong kitchen-sinky vibe (there's too much functionality). But I vote yes. Solid library.
SysTime stands for System Time. I figured that SysTime was better than having to type out SystemTime. The reason that advapi32.lib is necessary is because of the functions which are used to access the registry, which is necessary for WindowsTimeZone. Presumably, that would be added to the default dmd.conf file on Windows so that you wouldn't have to worry about it. I'd have preferred not to need it, but there's nothing I can do about it without losing functionality. - Jonathan M Davis
Dec 09 2010
parent reply Rainer Schuetze <r.sagitario gmx.de> writes:
Isn't

pragma(lib, "advapi32.lib");

supposed to take care of these implicite link dependencies?

Rainer

Jonathan M Davis wrote:
 On Thursday 09 December 2010 19:04:54 Yao G. wrote:
 On Thu, 09 Dec 2010 18:26:13 -0600, Andrei Alexandrescu

 <SeeWebsiteForEmail erdani.org> wrote:
 Jonathan M. Davis has diligently worked on his std.datetime proposal,
 and it has been through a few review cycles in this newsgroup.

 It's time to vote. Please vote for or against inclusion of datetime into
 Phobos, along with your reasons.


 Thank you,

 Andrei
I hate the SysDate name (ugly). And I hate that I must link to advapi32.lib. And honestly, It gives me a strong kitchen-sinky vibe (there's too much functionality). But I vote yes. Solid library.
SysTime stands for System Time. I figured that SysTime was better than having to type out SystemTime. The reason that advapi32.lib is necessary is because of the functions which are used to access the registry, which is necessary for WindowsTimeZone. Presumably, that would be added to the default dmd.conf file on Windows so that you wouldn't have to worry about it. I'd have preferred not to need it, but there's nothing I can do about it without losing functionality. - Jonathan M Davis
Dec 10 2010
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday 10 December 2010 01:21:46 Rainer Schuetze wrote:
 Isn't
 
 pragma(lib, "advapi32.lib");
 
 supposed to take care of these implicite link dependencies?
Quite possibly. I don't really know anything about pragmas in D. If nothing else, while I don't use anything other than dmd for D, I generally shy from pragmas in all languages because they're not portable between compilers. But if that's the correct way to handle it for std.datetime, then perhaps that's what I should do. I'd have to know more about it though before I did it. - Jonathan M Davis
Dec 10 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday 09 December 2010 18:53:24 Seth Hoenig wrote:
 +1 for inclusion, including the unittests just the way they are.
:)
 Why? Because I've been waiting for a decent datetime module for a while and
 this looks like one. There's no good reason not to include the unittests.
 Yes, there is an abundance of them. But there's _huge_ potential for small,
 off-by-one bugs in something like this, and I think maximum coverage, even
 if some of it overlaps, can only be a good thing.
Well, yes, the unit tests need to be included. What I meant was the unit test helper functions that I have. I have several functions - such as assertEqual() and assertExThrown() - which really improve the unit tests that I have. There is a unittests module in my code which contains these functions, and ideally, I'd like that module added as std.unittests. If it's not added, then those functions need to be added as private functions in std.datetime, or you lose the unit tests (or have to do _lot_ of work to change them, which would be a net loss in quality). I don't think that anyone is really suggesting that the unittest blocks be removed. The question with regards to unit tests is whether the unittests module should become std.unittests (which is why I created a separate thread semi-recently to review that code separately rather than as part of std.datetime). - Jonathan M Davis
Dec 09 2010
prev sibling next sibling parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
Andrei Alexandrescu Wrote:

 Jonathan M. Davis has diligently worked on his std.datetime proposal, 
 and it has been through a few review cycles in this newsgroup.
 
 It's time to vote. Please vote for or against inclusion of datetime into 
 Phobos, along with your reasons.
 
 
 Thank you,
 
 Andrei
Well I haven't looked at it so I don't want to claim a strong opinion, but others are probably in the same boat thinking that std.date needs replaced and std.datetime sounds good. I also have no issue with a unittest module.
Dec 09 2010
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/9/10 8:11 PM, Jesse Phillips wrote:
 Andrei Alexandrescu Wrote:

 Jonathan M. Davis has diligently worked on his std.datetime proposal,
 and it has been through a few review cycles in this newsgroup.

 It's time to vote. Please vote for or against inclusion of datetime into
 Phobos, along with your reasons.


 Thank you,

 Andrei
Well I haven't looked at it so I don't want to claim a strong opinion, but others are probably in the same boat thinking that std.date needs replaced and std.datetime sounds good. I also have no issue with a unittest module.
I suggest to at least skim through the documentation and/or the code. If you use D in any capacity, you'll need at some time or another to use std.datetime, so this is a better time than any other to take a look at it and voice opinions. Andrei
Dec 09 2010
parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
I don't usually see a library with that many unittests. It looks
pretty big, and if all these unittests pass that's great!

I like this little convenient function:
assert(DateTime.fromSimpleString("1998-Dec-25 02:15:00") ==
DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)));

If my vote counts, I vote yes.

On 12/10/10, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 On 12/9/10 8:11 PM, Jesse Phillips wrote:
 Andrei Alexandrescu Wrote:

 Jonathan M. Davis has diligently worked on his std.datetime proposal,
 and it has been through a few review cycles in this newsgroup.

 It's time to vote. Please vote for or against inclusion of datetime into
 Phobos, along with your reasons.


 Thank you,

 Andrei
Well I haven't looked at it so I don't want to claim a strong opinion, but others are probably in the same boat thinking that std.date needs replaced and std.datetime sounds good. I also have no issue with a unittest module.
I suggest to at least skim through the documentation and/or the code. If you use D in any capacity, you'll need at some time or another to use std.datetime, so this is a better time than any other to take a look at it and voice opinions. Andrei
Dec 09 2010
prev sibling next sibling parent reply Bernard Helyer <b.helyer gmail.com> writes:
I vote yes.

Why? Because Phobos has needed a solid module for working with dates and 
time for a long time, and neither std.date or std.gregorian filled that 
need -- std.date is buggy beyond repair, and std.gregorian's API doesn't 
make my normal tasks easy. std.datetime's API is fairly intuitive, and 
what I would expect out of a fairly modern date/time library. There are 
some bugs over here the need attending to, but I believe that the API 
itself is solid, and well designed, and that it can be a solid, good 
quality module in Phobos. 
Dec 09 2010
next sibling parent dolive <dolive89 sina.com> writes:
Bernard Helyer Wrote:

 I vote yes.
 
 Why? Because Phobos has needed a solid module for working with dates and 
 time for a long time, and neither std.date or std.gregorian filled that 
 need -- std.date is buggy beyond repair, and std.gregorian's API doesn't 
 make my normal tasks easy. std.datetime's API is fairly intuitive, and 
 what I would expect out of a fairly modern date/time library. There are 
 some bugs over here the need attending to, but I believe that the API 
 itself is solid, and well designed, and that it can be a solid, good 
 quality module in Phobos. 
I vote yes. too
Dec 09 2010
prev sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday 09 December 2010 20:13:49 Bernard Helyer wrote:
 I vote yes.
 
 Why? Because Phobos has needed a solid module for working with dates and
 time for a long time, and neither std.date or std.gregorian filled that
 need -- std.date is buggy beyond repair, and std.gregorian's API doesn't
 make my normal tasks easy. std.datetime's API is fairly intuitive, and
 what I would expect out of a fairly modern date/time library. There are
 some bugs over here the need attending to, but I believe that the API
 itself is solid, and well designed, and that it can be a solid, good
 quality module in Phobos.
You've found bugs in my proposed std.datetime? If you have, please point them out so that I can fix them. I'm unaware of any bugs. The only questions that I'm aware of are whether it fully works on Mac OS X and FreeBSD. It had problems on Mac OS X, but I think that they're fixed with the svn version of druntime. I have no idea what FreeBSD's status is though. It _should_ work, but unless someone tries it out, there's no way to know. In any case, you've found bugs, please point them out. I can't fix it if I don't know that it's broken. - Jonathan M Davis
Dec 09 2010
next sibling parent reply duckett <quack pond.net> writes:
Why does std.unittests.getExcMsg use Exc? assertExThrown,
assertExNotThrown and std.exception.enforceEx use Ex.
Dec 09 2010
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday 09 December 2010 21:27:14 duckett wrote:
 Why does std.unittests.getExcMsg use Exc? assertExThrown,
 assertExNotThrown and std.exception.enforceEx use Ex.
That would be an error on my part. It should be getExMsg(). They were all Exc before, and I changed them when it was pointed out that other functions in Phobos which abbreviate Exception use Ex. I missed that one. Here's a version with that fixed: http://is.gd/itAvD - Jonathan M Davis
Dec 09 2010
prev sibling parent reply Bernard Helyer <b.helyer gmail.com> writes:
On Thu, 09 Dec 2010 20:54:14 -0800, Jonathan M Davis wrote:
 In any case, you've found bugs, please point them out. I can't fix it if
 I don't know that it's broken.
The localtime it retrieves is incorrect, over here. It is always one and a half hours slow. I am retrieving it using Clock.currTime, and the result is the same if I force the TZ ("Pacific/Auckland"). (Linux 64, NZST, BIOS set to local time not UTC as I dual boot with Windows).
Dec 11 2010
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday 11 December 2010 04:41:55 Bernard Helyer wrote:
 On Thu, 09 Dec 2010 20:54:14 -0800, Jonathan M Davis wrote:
 In any case, you've found bugs, please point them out. I can't fix it if
 I don't know that it's broken.
The localtime it retrieves is incorrect, over here. It is always one and a half hours slow. I am retrieving it using Clock.currTime, and the result is the same if I force the TZ ("Pacific/Auckland"). (Linux 64, NZST, BIOS set to local time not UTC as I dual boot with Windows).
Since std.datetime is about to go into Phobos, open up a bug report on it on the bug tracker, so that it doesn't get lost. And I'll look into it. - Jonathan M Davis
Dec 11 2010
prev sibling next sibling parent Lutger Blijdestijn <lutger.blijdestijn gmail.com> writes:
Andrei Alexandrescu wrote:

 Jonathan M. Davis has diligently worked on his std.datetime proposal,
 and it has been through a few review cycles in this newsgroup.
 
 It's time to vote. Please vote for or against inclusion of datetime into
 Phobos, along with your reasons.
 
 
 Thank you,
 
 Andrei
Vote yes. - code seems well written and tested, although I admit having looked only briefly at it - api is clear and comprehensive - good documentation - the functionality it covers is required by many applications
Dec 09 2010
prev sibling next sibling parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Thu, 09 Dec 2010 16:26:13 -0800, Andrei Alexandrescu wrote:

 Jonathan M. Davis has diligently worked on his std.datetime proposal,
 and it has been through a few review cycles in this newsgroup.
 
 It's time to vote. Please vote for or against inclusion of datetime into
 Phobos, along with your reasons.
 
 
 Thank you,
 
 Andrei
I vote yes. The API looks clear and intuitive, and as you point out it has already been through some review cycles. Also, this will be the best documented module in Phobos. ;) Good work, Jonathan! (And kudos to SHOO as well. I've been using StopWatch for a while already, and it is far better than the old std.perf.PerformanceCounter.) -Lars
Dec 10 2010
prev sibling next sibling parent Fawzi Mohamed <fawzi gmx.ch> writes:
On 10-dic-10, at 01:26, Andrei Alexandrescu wrote:

 Jonathan M. Davis has diligently worked on his std.datetime  
 proposal, and it has been through a few review cycles in this  
 newsgroup.

 It's time to vote. Please vote for or against inclusion of datetime  
 into Phobos, along with your reasons.


 Thank you,

 Andrei
I think it is quite complete and usable, lot of work obviously went into this,... an clearly after the praise comes a "but"... so here are my comments on it, some are just personal preferences - I would split the unittests to a separate test module, I like having unittests, but having many of them make the code more difficult for me to skim through, and grasp, one test (example) can be useful, but lots of the hide the code structure. Maybe it is just my personal preference, but I like compact code, code that can be read, and so many unittests stop the flow of my reading. - I would split this into several modules (Timezone,SysTime,TimeDate,Clock), and if you want a "helper" module that make a public export. Modules should be used to define modules/namespaces, using classes seems a misuse to me (I am looking a Clock for example, which is a separated functionality imho). - I find that there is a loss of orthogonality between SysTime and DateTime. For me there are a calendar dates, and absolute points in time. To interconvert between the two one needs a timezone. I would associate the timezone with the calendar date and *not* with the absolute time. I find that SysTime makes too much effort to be a calendar date instead of a "point in time". Also if one wants to use a point in time at low level it should be "lean and mean", what is the timezone doing there? Last thing, well is something I would have done differently (as I said already in the past), is using doubles expressing number of seconds to represent point in time, durations, and TimeOfDay. I know other differs about this, but I really think that it is a very simple and versatile type. Fawzi
Dec 10 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 09 Dec 2010 19:26:13 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Jonathan M. Davis has diligently worked on his std.datetime proposal,  
 and it has been through a few review cycles in this newsgroup.

 It's time to vote. Please vote for or against inclusion of datetime into  
 Phobos, along with your reasons.


 Thank you,
I vote yes. The API is good, it's well tested (obviously), and most importantly, it gives us a champion for date/time that the current std.time is severely lacking. The point being, bugs can be fixed and APIs can be tweaked, but only if there's someone to do it. That being said, I like the API, and I think this module is a huge step towards completing Phobos. Great work Jonathan! -Steve
Dec 10 2010
prev sibling next sibling parent Johann MacDonagh <johann.macdonagh..no spam..gmail.com> writes:
Jonathan M Davis Wrote:

 P.S. The most recent code is here: http://is.gd/hYwOV
As a lurker I'm sure my vote doesn't count but I vote yes. Very clean and elegant. However I noticed a typo while quickly scanning the docs. std.unittests: "But since the functions in this module are intended to help write better unit tests, that would be make sense." Should probably be: "... that would make sense." (or "... this makes sense.")
Dec 10 2010
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Andrei Alexandrescu wrote:
 Jonathan M. Davis has diligently worked on his std.datetime
 proposal, and it has been through a few review cycles in this
 newsgroup.
 
 It's time to vote. Please vote for or against inclusion of datetime
 into Phobos, along with your reasons.
I cannot say anything regarding the datetime module but I'd like to say something about the unittest module. First it is really great having these asserts with improved output. I do not understand why one needs assertOpCmp!"=="(). According to TDPL there should be <, <=, >=, and >. == will be rewritten using opEquals. So I think <= and >= are missing and I do not know why there is assertOpCmp!"==". Further I'll find the following implementation of assertOpCmp better. immutable result = mixin("lhs" ~ op ~ "rhs"); if(!result) { if(msg.empty) throw new AssertError(format("[%s] %s [%s] failed", lhs, op, rhs), file, line); else throw new AssertError(format("[%s] %s [%s] failed: %s", %lhs, op, rhs, msg), %file, line); } It is shorter and gives the similar diagnostics than the current version. But I haven't tested the code above. The actual version is hard coded to lhs.opCmp(rhs). Better leave the decision lhs.opCmp(rhs) vs rhs.opCmp(lhs) to the compiler. Not sure about the following but maybe having something spelled out like this assertLessThan, assertLessEqual, etc. is also nice. For assertEqual I'd like it to mirror opEqual similar to as I did it above for opCmp. So have something like assertOpEquals() and then maybe also the name assertEquals as a synonym. I have to admit I do not know how to integrate !=. Why the binary predicate? With the current version I can write something like assertEqual!"a != b"(1, 2) which I find strange. Why not only do the check for equality. I.e. if(!(mixin("actual" ~ op ~ "expected")) { if(msg.empty) throw new AssertError(format("assertEquals() failed: actual [%s], expected [%s].", actual, expected), file, line); else throw new AssertError(format("assertEquals() failed: actual [%s], expected [%s]: %s", actual, expected, msg), file, line); } What's the benefit of the binary predicate? Clearly it makes it more flexible but I dislike allowing something like assertEqual!"a != b"(1, 2). In summary: I really like the unittest module. It's a great step forward for writing test. The assertions feel much like in google-test. A great module. I hope that I managed to explain my minor annoyance. I'll do my very best. Jonathan, thanks for this great module. +1 for std.unittest. Jens
Dec 10 2010
prev sibling next sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 10.12.2010 3:26, Andrei Alexandrescu wrote:
 Jonathan M. Davis has diligently worked on his std.datetime proposal, 
 and it has been through a few review cycles in this newsgroup.

 It's time to vote. Please vote for or against inclusion of datetime 
 into Phobos, along with your reasons.


 Thank you,

 Andrei
First, let me state my concerns. I'm very disappointed with how the range interface introduced in std.datetime, let me pick an example from ddoc: auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27)); auto func = IRange.everyDayOfWeek!(Date, >>>Direction.bwd <<<)(DayOfWeek.fri); auto range = interval.>>>bwdRange<<<(func); *(emphasis mine) Note the verbosity caused by conflating two concepts - the flexible way of getting a range of time points by consequently applying the delegate to a given start time point, and traversing an interval of time in a certain direction. Time ago I pointlessly argued with Jonathon to just drop the flexible way of iterating intervals, replacing it by simplistic "stride by a adding given duration to the begining of interval until you hit end". In the end I observed it was very limited view as it can't effectively solve the "give me the next five Easters" problem, and hastily retreated :) So I to come up with an alternative, see the attached sketch of it. The main idea - provide and infinite range based on aforementioned flexible principle, simple example is (for ints): auto r = powersOf((int x){ return x*2; }, 1); // 2,4,8,... given the fact that delegate already contains information about direction of traversing (if any), the user the free to use it as is: take(r,10); // 2,4... 1024 in case with dates that is: auto inf = powersOf(IRange.everyDayOfWeek!(Date)(DayOfWeek.monday), Date(2010,Month.dec,11)); take(inf,5);//next 5 mondays, forward is default in everyDayOfWeek Then comes the second concept of confining ranges in intervals, here it goes: auto interval = Interval!Date(Date(2010,Month.dec,1),Date(2010,Month.dec,20)); auto conf = confine(inf,interval);//Mondays in the interval iterated from the beginning And the simplistic approach of fixed duration striding: fwdRange(interval, dur!"days"(2)); //yup, traverse by two days same goes for bwdRange To summarize it: 1) remove fwdRange, bwdRange from each of Interval types (all it does is to require to retype them all over again) and make them free functions with above simple functionality 2) drop IRange, and let those delegates not handled by simple case to just float around (they are very unlikely to conflict with anything IMHO) 3) speaking of which - separate the notion of applying delegate (that could even be generalized in std.algorithm someday) to obtain range, and confinement of produced range to interval. A fitting finale would be to say... that _yes_, I would like to see this library in Phobos! Though with just proposed change if gets any traction... Overall it's a fantastic work, thanks Jonathon. -- Dmitry Olshansky
Dec 10 2010
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday 10 December 2010 08:15:09 Dmitry Olshansky wrote:
 On 10.12.2010 3:26, Andrei Alexandrescu wrote:
 Jonathan M. Davis has diligently worked on his std.datetime proposal,
 and it has been through a few review cycles in this newsgroup.
 
 It's time to vote. Please vote for or against inclusion of datetime
 into Phobos, along with your reasons.
 
 
 Thank you,
 
 Andrei
First, let me state my concerns. I'm very disappointed with how the range interface introduced in std.datetime, let me pick an example from ddoc: auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27)); auto func = IRange.everyDayOfWeek!(Date, >>>Direction.bwd <<<)(DayOfWeek.fri); auto range = interval.>>>bwdRange<<<(func); *(emphasis mine) Note the verbosity caused by conflating two concepts - the flexible way of getting a range of time points by consequently applying the delegate to a given start time point, and traversing an interval of time in a certain direction. Time ago I pointlessly argued with Jonathon to just drop the flexible way of iterating intervals, replacing it by simplistic "stride by a adding given duration to the begining of interval until you hit end". In the end I observed it was very limited view as it can't effectively solve the "give me the next five Easters" problem, and hastily retreated :) So I to come up with an alternative, see the attached sketch of it. The main idea - provide and infinite range based on aforementioned flexible principle, simple example is (for ints): auto r = powersOf((int x){ return x*2; }, 1); // 2,4,8,... given the fact that delegate already contains information about direction of traversing (if any), the user the free to use it as is: take(r,10); // 2,4... 1024 in case with dates that is: auto inf = powersOf(IRange.everyDayOfWeek!(Date)(DayOfWeek.monday), Date(2010,Month.dec,11)); take(inf,5);//next 5 mondays, forward is default in everyDayOfWeek Then comes the second concept of confining ranges in intervals, here it goes: auto interval = Interval!Date(Date(2010,Month.dec,1),Date(2010,Month.dec,20)); auto conf = confine(inf,interval);//Mondays in the interval iterated from the beginning And the simplistic approach of fixed duration striding: fwdRange(interval, dur!"days"(2)); //yup, traverse by two days same goes for bwdRange To summarize it: 1) remove fwdRange, bwdRange from each of Interval types (all it does is to require to retype them all over again) and make them free functions with above simple functionality 2) drop IRange, and let those delegates not handled by simple case to just float around (they are very unlikely to conflict with anything IMHO) 3) speaking of which - separate the notion of applying delegate (that could even be generalized in std.algorithm someday) to obtain range, and confinement of produced range to interval. A fitting finale would be to say... that _yes_, I would like to see this library in Phobos! Though with just proposed change if gets any traction... Overall it's a fantastic work, thanks Jonathon.
Overall, I don't really see the benefit of your proposal. The main advantage of fwdRange and bwdRange in the interval types instead of just a single function is that they allow you to verify that you're iterating in the correct direction. Otherwise, you risk an infinite loop. If we were willing to forgoe that, then you could make it so that you only had one function, but I think that that would be a definite loss. It _is_ annoying to have to give Direction.fwd or Direction.bwd to the functions in IRange when you're feeding it to fwdRange or bwdRange since it does seem redundant, but those functions need to know what direction you want them to iterate in, and both fwdRange and bwdRange are designed for general delegates - not necessarily just those generated by IRange - so they assume the direction. But since the functions in IRange default to Direction.fwd and that's almost always what you'd want, I don't think that it's ultimately that big an issue. Conceptually, I think that it makes perfect sense that the interval would have the range functions on them - that's certainly what happens with containers. I don't see the benefit in splitting them out. Your solution makes it so that a range is infinite separately from whether the interval is infinite. I don't think that that makes sense. A range is only infinite because it's iterating over something infinite. By making the range infinite separately, it's then possible to try and iterate infinitely over a non- infinite interval, which would be a problem. For the most part, it looks like all you've done is try to make it so that the ranges are unrelated to the intervals that they iterate over. That seems like a bad idea to me, and I fail to see the benefit. What does your solution do that mine can't? My solution is completely generalized. You can use take() and all of those std.range and std.algorithm functions on the ranges in std.datetime. You can give it a delegate defined as you like as long is it takes a time point and returns a time point of the same type. If you got your range via fwdRange(), then the time point returned must be after the one given, and if you got your range via bwdRange(0, then the time point must be after the one given. It's fairly straightforward and not error-prone. I agree that the IRange functions are a bit ugly, but they're an attempt to make it easier to create common delegates to pass to fwdRange() and bwdRange() rather than you having to create your own. You don't have to use them. They're for convenience. And they include a function which generates a delegate which causes the range it iterate by a given duration every iteration: IRange.everyDuration! (). I'm certainly open to suggestions, but I don't understand what's broken about my solution that yours fixes. My seems fairly straightword. 1. You have an interval - be it infinite or finite. 2. You want a range, you pass a delegate (which determines how to iterate over the interval) to fwdRange() if you want to iterate forwards and bwdRange() if you want to iterate backwards. fwdRange() and bwdRange() verify that the delegates that you give the return time points which are valid for iterating over the interval (so, not duplicating the previous time point or iterating in the wrong direction). 3. If you don't want to create your own delegate, then you use one of the functions in IRange to generate one for you. 4. Once you have your range, you can do whatever you normally do with input and forward ranges. - Jonathan M Davis
Dec 10 2010
parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 10.12.2010 23:00, Jonathan M Davis wrote:
 [snip]
 Overall, I don't really see the benefit of your proposal. The main advantage of
 fwdRange and bwdRange in the interval types instead of just a single function
is
 that they allow you to verify that you're iterating in the correct direction.
In my proposal it still checks this, what I meant is - there is no need to define them inside range, in fact it's quite easy to define generic fwdRange, that works on any interval, which is what I did (it still lacks PopFirst.yes customabilty and such, but that can be easily fixed).
 Otherwise, you risk an infinite loop. If we were willing to forgoe that, then
you
 could make it so that you only had one function, but I think that that would be
 a definite loss.
 It _is_ annoying to have to give Direction.fwd or Direction.bwd to the
functions
 in IRange when you're feeding it to fwdRange or bwdRange since it does seem
 redundant, but those functions need to know what direction you want them to
 iterate in, and both fwdRange and bwdRange are designed for general delegates -
 not necessarily just those generated by IRange - so they assume the direction.
 But since the functions in IRange default to Direction.fwd and that's almost
 always what you'd want, I don't think that it's ultimately that big an issue.
Agreed, It's not a big issue. But I thought delegate can go back and forth as it's internal logic suggests, it's when it hits the end of interval that's important (and I assumed that would be the end of iteration).
 Conceptually, I think that it makes perfect sense that the interval would have
 the range functions on them - that's certainly what happens with containers. I
 don't see the benefit in splitting them out.
It's where we are disagreeing it seems. For me, the less monolithic the interval struct, the better. After the interval provided begin and end (ether one), it's trivial to implement generic fwdRange and bwdRange outside, and they also provide 'contains' function.
 Your solution makes it so that a range is infinite separately from whether the
 interval is infinite. I don't think that that makes sense. A range is only
 infinite because it's iterating over something infinite. By making the range
 infinite separately, it's then possible to try and iterate infinitely over a
non-
 infinite interval, which would be a problem.
For me the problem would be to iterate over infinite range assuming it's finite.
 For the most part, it looks like all you've done is try to make it so that the
 ranges are unrelated to the intervals that they iterate over. That seems like a
 bad idea to me, and I fail to see the benefit. What does your solution do that
 mine can't?
Delegate can generate range of seemingly unrelated time points, or for which you may not know the interval or it's pointless or hard to calculate. Consider you need date of next 5 blue dragon years (that's that Chinese calendar thingy) ? That's solvable,with a dummy infinite interval. My point is that when you need custom delegate, it's only for specific tasks, for which interval may not be interesting at all.
 My solution is completely generalized. You can use take() and all of those
 std.range and std.algorithm functions on the ranges in std.datetime. You can
 give it a delegate defined as you like as long is it takes a time point and
 returns a time point of the same type. If you got your range via fwdRange(),
 then the time point returned must be after the one given, and if you got your
 range via bwdRange(0, then the time point must be after the one given. It's
 fairly straightforward and not error-prone.
I can't take if I don't know the interval beforehand, or need to create a dummy infinite one. Or even worse delegate could produce time points in non-directed way, like consider +1 day, -2day, +3day (no, it's not common but... you are the one to talk about generalizations).
 I agree that the IRange functions are a bit ugly, but they're an attempt to
make
 it easier to create common delegates to pass to fwdRange() and bwdRange()
rather
 than you having to create your own. You don't have to use them. They're for
 convenience. And they include a function which generates a delegate which
causes
 the range it iterate by a given duration every iteration: IRange.everyDuration!
 ().
Yes, there I suggest to introduce a shortcut, like auto byDay = fwdRange(interval, dur!"days"(1)); auto byYear = fwdRange(interval, 1); //months = 0, duration = dur!"days"(0) I fear It's just a matter of taste.
 I'm certainly open to suggestions, but I don't understand what's broken about
my
 solution that yours fixes. My seems fairly straightword.

 1. You have an interval - be it infinite or finite.
There I thought is a problem in generalization , you may not know the interval.
 2. You want a range, you pass a delegate (which determines how to iterate over
 the interval) to fwdRange() if you want to iterate forwards and bwdRange() if
 you want to iterate backwards. fwdRange() and bwdRange() verify that the
 delegates that you give the return time points which are valid for iterating
 over the interval (so, not duplicating the previous time point or iterating in
 the wrong direction).
Yes, that's check could be a good thing. In my proposal you'd get an empty range or infinite, still can be added, of course.
 3. If you don't want to create your own delegate, then you use one of the
 functions in IRange to generate one for you.
 4. Once you have your range, you can do whatever you normally do with input and
 forward ranges.
In fact, that's where the user need to get, and the easier the better.
 - Jonathan M Davis
-- Dmitry Olshansky
Dec 10 2010
prev sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday 10 December 2010 12:00:39 Jonathan M Davis wrote:
 On Friday 10 December 2010 08:15:09 Dmitry Olshansky wrote:
 On 10.12.2010 3:26, Andrei Alexandrescu wrote:
 Jonathan M. Davis has diligently worked on his std.datetime proposal,
 and it has been through a few review cycles in this newsgroup.
 
 It's time to vote. Please vote for or against inclusion of datetime
 into Phobos, along with your reasons.
 
 
 Thank you,
 
 Andrei
First, let me state my concerns. I'm very disappointed with how the range interface introduced in std.datetime, let me pick an example from ddoc: auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27)); auto func = IRange.everyDayOfWeek!(Date, >>>Direction.bwd <<<)(DayOfWeek.fri); auto range = interval.>>>bwdRange<<<(func); *(emphasis mine) Note the verbosity caused by conflating two concepts - the flexible way of getting a range of time points by consequently applying the delegate to a given start time point, and traversing an interval of time in a certain direction. Time ago I pointlessly argued with Jonathon to just drop the flexible way of iterating intervals, replacing it by simplistic "stride by a adding given duration to the begining of interval until you hit end". In the end I observed it was very limited view as it can't effectively solve the "give me the next five Easters" problem, and hastily retreated :) So I to come up with an alternative, see the attached sketch of it. The main idea - provide and infinite range based on aforementioned flexible principle, simple example is (for ints): auto r = powersOf((int x){ return x*2; }, 1); // 2,4,8,... given the fact that delegate already contains information about direction of traversing (if any), the user the free to use it as is: take(r,10); // 2,4... 1024 in case with dates that is: auto inf = powersOf(IRange.everyDayOfWeek!(Date)(DayOfWeek.monday), Date(2010,Month.dec,11)); take(inf,5);//next 5 mondays, forward is default in everyDayOfWeek Then comes the second concept of confining ranges in intervals, here it goes: auto interval = Interval!Date(Date(2010,Month.dec,1),Date(2010,Month.dec,20)); auto conf = confine(inf,interval);//Mondays in the interval iterated from the beginning And the simplistic approach of fixed duration striding: fwdRange(interval, dur!"days"(2)); //yup, traverse by two days same goes for bwdRange To summarize it: 1) remove fwdRange, bwdRange from each of Interval types (all it does is to require to retype them all over again) and make them free functions with above simple functionality 2) drop IRange, and let those delegates not handled by simple case to just float around (they are very unlikely to conflict with anything IMHO) 3) speaking of which - separate the notion of applying delegate (that could even be generalized in std.algorithm someday) to obtain range, and confinement of produced range to interval. A fitting finale would be to say... that _yes_, I would like to see this library in Phobos! Though with just proposed change if gets any traction... Overall it's a fantastic work, thanks Jonathon.
Overall, I don't really see the benefit of your proposal. The main advantage of fwdRange and bwdRange in the interval types instead of just a single function is that they allow you to verify that you're iterating in the correct direction. Otherwise, you risk an infinite loop. If we were willing to forgoe that, then you could make it so that you only had one function, but I think that that would be a definite loss. It _is_ annoying to have to give Direction.fwd or Direction.bwd to the functions in IRange when you're feeding it to fwdRange or bwdRange since it does seem redundant, but those functions need to know what direction you want them to iterate in, and both fwdRange and bwdRange are designed for general delegates - not necessarily just those generated by IRange - so they assume the direction. But since the functions in IRange default to Direction.fwd and that's almost always what you'd want, I don't think that it's ultimately that big an issue. Conceptually, I think that it makes perfect sense that the interval would have the range functions on them - that's certainly what happens with containers. I don't see the benefit in splitting them out. Your solution makes it so that a range is infinite separately from whether the interval is infinite. I don't think that that makes sense. A range is only infinite because it's iterating over something infinite. By making the range infinite separately, it's then possible to try and iterate infinitely over a non- infinite interval, which would be a problem. For the most part, it looks like all you've done is try to make it so that the ranges are unrelated to the intervals that they iterate over. That seems like a bad idea to me, and I fail to see the benefit. What does your solution do that mine can't? My solution is completely generalized. You can use take() and all of those std.range and std.algorithm functions on the ranges in std.datetime. You can give it a delegate defined as you like as long is it takes a time point and returns a time point of the same type. If you got your range via fwdRange(), then the time point returned must be after the one given, and if you got your range via bwdRange(0, then the time point must be after the one given. It's fairly straightforward and not error-prone. I agree that the IRange functions are a bit ugly, but they're an attempt to make it easier to create common delegates to pass to fwdRange() and bwdRange() rather than you having to create your own. You don't have to use them. They're for convenience. And they include a function which generates a delegate which causes the range it iterate by a given duration every iteration: IRange.everyDuration! (). I'm certainly open to suggestions, but I don't understand what's broken about my solution that yours fixes. My seems fairly straightword. 1. You have an interval - be it infinite or finite. 2. You want a range, you pass a delegate (which determines how to iterate over the interval) to fwdRange() if you want to iterate forwards and bwdRange() if you want to iterate backwards. fwdRange() and bwdRange() verify that the delegates that you give the return time points which are valid for iterating over the interval (so, not duplicating the previous time point or iterating in the wrong direction). 3. If you don't want to create your own delegate, then you use one of the functions in IRange to generate one for you. 4. Once you have your range, you can do whatever you normally do with input and forward ranges.
Would it be better if I changed the IRange functions so that rather than returning a delegate, they took an interval and returned the range? So, rather than auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27)); auto func = IRange.everyDayOfWeek!Date(DayOfWeek.fri); auto range = interval.fwdRange(func); you'd get something like auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27)); auto range = IRange.everyDayOfWeek!Date(interval, DayOfWeek.fri); Then you wouldn't have to give the IRange function Direction.fwd or Direction.bwd (well, just Direction.bwd, since fwd is the default) then pass that it to fwdRange() or bwdRange() and have to worry about whether you screwed up and mismatched the directions. It would then be caught at compile time rather than runtime. fwdRange() and bwdRange() would stay the same, but you wouldn't have to call the directly unless you were writing your own delegate. Does that seem like a big improvement to you? After thinking of about the problem further and coming up with that change, I'm definitely considering making it. - Jonathan M Davis
Dec 10 2010
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 10 Dec 2010 15:21:38 -0500, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 Would it be better if I changed the IRange functions so that rather than
 returning a delegate, they took an interval and returned the range? So,  
 rather
 than

 auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27));
 auto func = IRange.everyDayOfWeek!Date(DayOfWeek.fri);
 auto range = interval.fwdRange(func);


 you'd get something like

 auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27));
 auto range = IRange.everyDayOfWeek!Date(interval, DayOfWeek.fri);

 Then you wouldn't have to give the IRange function Direction.fwd or
 Direction.bwd (well, just Direction.bwd, since fwd is the default) then  
 pass
 that it to fwdRange() or bwdRange() and have to worry about whether you  
 screwed
 up and mismatched the directions. It would then be caught at compile  
 time rather
 than runtime.

 fwdRange() and bwdRange() would stay the same, but you wouldn't have to  
 call the
 directly unless you were writing your own delegate.

 Does that seem like a big improvement to you? After thinking of about the
 problem further and coming up with that change, I'm definitely  
 considering making
 it.
When I looked at the code, I didn't pay much attention to the range stuff. But you really need to incorporate IFTI here. It would be much nicer if you did: auto ival = interval(Date(2010, 9, 2), Date(2010, 9, 27); auto range = everyDayOfWeek(ival, DayOfWeek.fri); At least that's a start, we should be able to build more wrappers to reduce the verbosity:. auto range = everyDayOfWeek(Date(2010, 9, 2), Date(2010, 9, 27), DayOfWeek.fri); Some way to use slice syntax might be nice. perhaps: auto range = Date["9/2/2010".."9/27/2010"].every(DayOfWeek.fri); maybe that last one is just a pipe dream ;) -Steve
Dec 10 2010
parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 10.12.2010 23:42, Steven Schveighoffer wrote:
 On Fri, 10 Dec 2010 15:21:38 -0500, Jonathan M Davis 
 <jmdavisProg gmx.com> wrote:

 Would it be better if I changed the IRange functions so that rather than
 returning a delegate, they took an interval and returned the range? 
 So, rather
 than

 auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27));
 auto func = IRange.everyDayOfWeek!Date(DayOfWeek.fri);
 auto range = interval.fwdRange(func);


 you'd get something like

 auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27));
 auto range = IRange.everyDayOfWeek!Date(interval, DayOfWeek.fri);

 Then you wouldn't have to give the IRange function Direction.fwd or
 Direction.bwd (well, just Direction.bwd, since fwd is the default) 
 then pass
 that it to fwdRange() or bwdRange() and have to worry about whether 
 you screwed
 up and mismatched the directions. It would then be caught at compile 
 time rather
 than runtime.

 fwdRange() and bwdRange() would stay the same, but you wouldn't have 
 to call the
 directly unless you were writing your own delegate.

 Does that seem like a big improvement to you? After thinking of about 
 the
 problem further and coming up with that change, I'm definitely 
 considering making
 it.
As potential user, of course, I would like this improvement, I sure others will too.
 When I looked at the code, I didn't pay much attention to the range 
 stuff.
I have an impression many readers didn't managed to get there with a fresh mind :)
 But you really need to incorporate IFTI here.  It would be much nicer 
 if you did:

 auto ival = interval(Date(2010, 9, 2), Date(2010, 9, 27);
 auto range = everyDayOfWeek(ival, DayOfWeek.fri);
Yes, that's even better, and, in fact, simple.
 At least that's a start, we should be able to build more wrappers to 
 reduce the verbosity:.

 auto range = everyDayOfWeek(Date(2010, 9, 2), Date(2010, 9, 27), 
 DayOfWeek.fri);

 Some way to use slice syntax might be nice.  perhaps:

 auto range = Date["9/2/2010".."9/27/2010"].every(DayOfWeek.fri);

 maybe that last one is just a pipe dream ;)
I like that dream, maybe start sort of contest on the most convenient and terse notations ?
 -Steve
-- Dmitry Olshansky
Dec 10 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday 10 December 2010 06:29:40 Jens Mueller wrote:
 Andrei Alexandrescu wrote:
 Jonathan M. Davis has diligently worked on his std.datetime
 proposal, and it has been through a few review cycles in this
 newsgroup.
 
 It's time to vote. Please vote for or against inclusion of datetime
 into Phobos, along with your reasons.
I cannot say anything regarding the datetime module but I'd like to say something about the unittest module. First it is really great having these asserts with improved output. I do not understand why one needs assertOpCmp!"=="(). According to TDPL there should be <, <=, >=, and >. == will be rewritten using opEquals. So I think <= and >= are missing and I do not know why there is assertOpCmp!"==". Further I'll find the following implementation of assertOpCmp better. immutable result = mixin("lhs" ~ op ~ "rhs"); if(!result) { if(msg.empty) throw new AssertError(format("[%s] %s [%s] failed", lhs, op, rhs),
file,
 line); else
 		throw new AssertError(format("[%s] %s [%s] failed: %s", %lhs, op, rhs,
 msg), %file, line); }
 
 It is shorter and gives the similar diagnostics than the current
 version. But I haven't tested the code above.
 The actual version is hard coded to lhs.opCmp(rhs). Better leave the
 decision lhs.opCmp(rhs) vs rhs.opCmp(lhs) to the compiler.
 
 Not sure about the following but maybe having something spelled out like
 this assertLessThan, assertLessEqual, etc. is also nice.
 For assertEqual I'd like it to mirror opEqual similar to as I did it
 above for opCmp. So have something like assertOpEquals() and then maybe
 also the name assertEquals as a synonym. I have to admit I do not know
 how to integrate !=.
assertOpCmp!"<=" and assertOpCmp!">=" could certainly be added (I didn't think of adding them). <, >, and == are included because those are the three results that opCmp() can have. The othor comparison operators are built from that, but the point is to test opComp(). And in that vein, your changes would defeat that purpose. opCmp() needs to be specifically called here (especially because == does convert to opEquals(); opCmp() == 0 needs to be specificall testable). assertOpCmp() isn't so much intended to test that a value is less than or greater than but that the opCmp() function works correctly (which would then translate to less than and greater than and the like working correctly.). On the other hand, assertEqual() is _not_ specifically testing opEqual(). It is simply testing for equality. So, it doesn't call opEquals() directly. If it did, it wouldn't work with primitive types and would probably run into problems due to the fact that == translates to the version of opEquals() which takes two parameters rather than the overridable one which takes one.
 Why the binary predicate?
 With the current version I can write something like
 assertEqual!"a != b"(1, 2)
 which I find strange. Why not only do the check for equality.
 I.e.
 if(!(mixin("actual" ~ op ~ "expected"))
 {
 	if(msg.empty)
 		throw new AssertError(format("assertEquals() failed: actual [%s],
 expected [%s].", actual, expected), file, line); else
 		throw new AssertError(format("assertEquals() failed: actual [%s],
 expected [%s]: %s", actual, expected, msg), file, line); }
 
 What's the benefit of the binary predicate? Clearly it makes it more
 flexible but I dislike allowing something like assertEqual!"a != b"(1,
 2).
The predicate was suggested in review. std.algorithm.equal() has a predicate. This mirrors that. Since assertEqual() is intended to test for general equality rather than to specifically test opEquals(), it seemed to make good sense to me. - Jonathan M Davis
Dec 10 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday 10 December 2010 03:18:29 Fawzi Mohamed wrote:
 On 10-dic-10, at 01:26, Andrei Alexandrescu wrote:
 Jonathan M. Davis has diligently worked on his std.datetime
 proposal, and it has been through a few review cycles in this
 newsgroup.
 
 It's time to vote. Please vote for or against inclusion of datetime
 into Phobos, along with your reasons.
 
 
 Thank you,
 
 Andrei
I think it is quite complete and usable, lot of work obviously went into this,... an clearly after the praise comes a "but"... so here are my comments on it, some are just personal preferences - I would split the unittests to a separate test module, I like having unittests, but having many of them make the code more difficult for me to skim through, and grasp, one test (example) can be useful, but lots of the hide the code structure. Maybe it is just my personal preference, but I like compact code, code that can be read, and so many unittests stop the flow of my reading.
This has been discussed a time or two. D really isn't set up to work that way. Yoo can't just move them over because then those that need private access won't work. The lack of named unittest blocks really hurts that as well. You _could_ turn them into mixins of some kind, but that could get quite messy. But honestly, I find it _way_ easier to maintain the code with each unittest block immediately following the function that it's testing. The interval code is quite irritating precisely because I couldn't put the tests next to the code (since it's templatized it just didn't work in that case). I agree that it does harm your ability to skim through the code, but the ddoc html files let you skim the API, and I really di think think it's more maintainable this way. Besides, if we really want to, we can change that sort of thing later. Exactly how the unit tests are handled doesn't affect the public API or the general useability of the module.
 - I would split this into several modules
 (Timezone,SysTime,TimeDate,Clock), and if you want a "helper" module
 that make a public export.
 Modules should be used to define modules/namespaces, using classes
 seems a misuse to me (I am looking a Clock for example, which is a
 separated functionality imho).
It was already discussed that it would be better as one module. We don't have any kind of hard limit on the size of modules or anything like that, and it's just simpler to have it in one module. Clock is used as a namespace of sorts specifically to make the code clearer. You can think of it as a sort of singleton which has the functions which give you the time from the system clock. I think that it improves useability. Similarly, IRange is there specifically to namespace the functions which generate functions used to generate ranges. It makes the code clearer to make it clear that the functions are generating range generative functions. There were other classes used to namespace code, and it was rightly pointed out that they were unneeded. However, I believe that in these two cases, it's a definite useability improvement to have them. It makes code clearer and easier to read.
 - I find that there is a loss of orthogonality between SysTime and
 DateTime. For me there are a calendar dates, and absolute points in
 time. To interconvert between the two one needs a timezone. I would
 associate the timezone with the calendar date and *not* with the
 absolute time.
 I find that SysTime makes too much effort to be a calendar date
 instead of a "point in time".
 Also if one wants to use a point in time at low level it should be
 "lean and mean", what is the timezone doing there?
I don't really get this. Date and DateTime (and thus TimeOfDay) is intended for calendar use. There is no time zone because you're not dealing with exact times which care about the time zone that they're in. They don't necessarily have any relation to UTC or local time. A lot of calendar stuff isn't going to care one whit about time zones. SysTime is specifically supposed to handle the "system time." The system definitely cares about the time zone. You have a local time zone that your system is in. You potentially have to convert between time zones when playing around with time stamps and the like. It's when dealing with the system time that you're really going to care about time zones. So, SysTime includes a time zone, and it is the type to use when you care about the time zone. If you really want dealing with the system time to work correctly in the general case, you need it to have a time zone. I've run into a number of bugs at work precisely because time_t was passed around naked and constantly converted (which, on top of being bug-prone, _cannot_ work correctly due to DST). By having the time in UTC internally at all times and converting it as necessary to the time zone that you want, you avoid a _lot_ of problems with time.
 Last thing, well is something I would have done differently (as I said
 already in the past), is using doubles expressing number of seconds to
 represent point in time, durations, and TimeOfDay. I know other
 differs about this, but I really think that it is a very simple and
 versatile type.
doubles aren't precise. And having the units associated with a duration rather than having a naked number really helps to avoid bugs due to programmers assuming the wrong units for times. - Jonathan M Davis
Dec 10 2010
prev sibling next sibling parent Fawzi Mohamed <fawzi gmx.ch> writes:
On 10-dic-10, at 18:02, Jonathan M Davis wrote:

thanks for the answers

 On Friday 10 December 2010 03:18:29 Fawzi Mohamed wrote:
 On 10-dic-10, at 01:26, Andrei Alexandrescu wrote:
 Jonathan M. Davis has diligently worked on his std.datetime
 proposal, and it has been through a few review cycles in this
 newsgroup.

 It's time to vote. Please vote for or against inclusion of datetime
 into Phobos, along with your reasons.


 Thank you,

 Andrei
I think it is quite complete and usable, lot of work obviously went into this,... an clearly after the praise comes a "but"... so here are my comments on it, some are just personal preferences - I would split the unittests to a separate test module, I like having unittests, but having many of them make the code more difficult for me to skim through, and grasp, one test (example) can be useful, but lots of the hide the code structure. Maybe it is just my personal preference, but I like compact code, code that can be read, and so many unittests stop the flow of my reading.
This has been discussed a time or two. D really isn't set up to work that way. Yoo can't just move them over because then those that need private access won't work. The lack of named unittest blocks really hurts that as well. You _could_ turn them into mixins of some kind, but that could get quite messy. But honestly, I find it _way_ easier to maintain the code with each unittest block immediately following the function that it's testing. The interval code is quite irritating precisely because I couldn't put the tests next to the code (since it's templatized it just didn't work in that case). I agree that it does harm your ability to skim through the code, but the ddoc html files let you skim the API, and I really di think think it's more maintainable this way. Besides, if we really want to, we can change that sort of thing later. Exactly how the unit tests are handled doesn't affect the public API or the general useability of the module.
ok, sorry I hadn't followed the discussion, as I said that is just my personal perference.
 - I would split this into several modules
 (Timezone,SysTime,TimeDate,Clock), and if you want a "helper" module
 that make a public export.
 Modules should be used to define modules/namespaces, using classes
 seems a misuse to me (I am looking a Clock for example, which is a
 separated functionality imho).
It was already discussed that it would be better as one module. We don't have any kind of hard limit on the size of modules or anything like that, and it's just simpler to have it in one module.
well but with public export you can easily have an exported module, by separate compilation you might spare something, but again it is a matter of style, I find that in d the main way to partition code are modules.
 Clock is used as a namespace of sorts specifically to make the code  
 clearer. You
 can think of it as a sort of singleton which has the functions which  
 give you
 the time from the system clock. I think that it improves useability.
having a separate module for it would give a similar effect
 Similarly, IRange is there specifically to namespace the functions  
 which generate
 functions used to generate ranges. It makes the code clearer to make  
 it clear
 that the functions are generating range generative functions.

 There were other classes used to namespace code, and it was rightly  
 pointed out
 that they were unneeded. However, I believe that in these two cases,  
 it's a
 definite useability improvement to have them. It makes code clearer  
 and easier to
 read.
if I alone on this I will not argue, but I definitely have a different style.
 - I find that there is a loss of orthogonality between SysTime and
 DateTime. For me there are a calendar dates, and absolute points in
 time. To interconvert between the two one needs a timezone. I would
 associate the timezone with the calendar date and *not* with the
 absolute time.
 I find that SysTime makes too much effort to be a calendar date
 instead of a "point in time".
 Also if one wants to use a point in time at low level it should be
 "lean and mean", what is the timezone doing there?
I don't really get this. Date and DateTime (and thus TimeOfDay) is intended for calendar use. There is no time zone because you're not dealing with exact times which care about the time zone that they're in. They don't necessarily have any relation to UTC or local time. A lot of calendar stuff isn't going to care one whit about time zones. SysTime is specifically supposed to handle the "system time." The system definitely cares about the time zone. You have a local time zone that your system is in. You potentially have to convert between time zones when playing around with time stamps and the like. It's when dealing with the system time that you're really going to care about time zones. So, SysTime includes a time zone, and it is the type to use when you care about the time zone. If you really want dealing with the system time to work correctly in the general case, you need it to have a time zone. I've run into a number of bugs at work precisely because time_t was passed around naked and constantly converted (which, on top of being bug-prone, _cannot_ work correctly due to DST). By having the time in UTC internally at all times and converting it as necessary to the time zone that you want, you avoid a _lot_ of problems with time.
I see two uses of time, one is calender the other a point in time. A point in time needs only to know if other events are before or after it, or how far they are. It should definitely use a unique reference point (for example NSDate uses 1 january 2001). Using UTC is correct, I never argued for something else. the thing is that a point in tame doesn't *need* a timezone, it needs just a reference point. A timezone is needed to convert between calender (TimeDate) and a point in time. So if one wants to store a timezone somewhere (and not use it just when converting between point in time and calender date), then I would store it in calender date, because without it I cannot know to which absolute time it refers, and a calendar date is already larger, and the extra storage is probably not something one would care in typical use of the calendar.
 Last thing, well is something I would have done differently (as I  
 said
 already in the past), is using doubles expressing number of seconds  
 to
 represent point in time, durations, and TimeOfDay. I know other
 differs about this, but I really think that it is a very simple and
 versatile type.
doubles aren't precise. And having the units associated with a duration rather than having a naked number really helps to avoid bugs due to programmers assuming the wrong units for times.
ms accuracy over more than 100'000 years, and much higher for smaller ranges doesn't seems to imprecise to me, and having *only* seconds with them should not confuse people. I don't argue against having functions using ints, but I think that having also a double based interface and using it internally for point in time, and timeofday, and at least having it as option (i.e. function returning the value) for normal durations would be good. I agree that for calender and calender differences it is not the best choice, but a calendar is not what is used at a low level (to set an alarm for example), one should not force the calendar issues on the more basic point in time. Fawzi
Dec 10 2010
prev sibling next sibling parent klickverbot <see klickverbot.at> writes:
On 12/10/10 1:26 AM, Andrei Alexandrescu wrote:
 It's time to vote. Please vote for or against inclusion of datetime into
 Phobos, along with your reasons.
Yes, it'd totally like to see this library in Phobos, but I think that we need to be aware of a few issues, mainly caused by the sheer amount of source code in a single file/module. The first one is maintainability – if datetime.d was added to Phobos in its current form, about _a quarter of all std.* code_ (LOC-wise) would be concentrated _in a single source file_. I know that this has been discussed before, and that there is no hard limit on file/module size, but in my eyes, 32k lines in a single file are prone to get tedious. This probably isn't really a big problem though, since the code is relatively low in complexity and furthermore probably does not require an exceptionally high amount of maintenance. In my eyes, a much more important issue is that DDoc is hardly up to the task currently. Just open the HTML page from Jonathan's archive and imagine being pointed to datetime.html#toLocalTime, and try finding out to which entity (class, struct or the module itself) this function belongs, then try getting a quick picture of what other functions are offered in the same scope, or jumping to the start or end of the docs on it. A complete discussion would probably belong to a separate DDoc improvements thread, but for example, the »jump to« list at the top is unnecessarily cluttered by a lot of enum itmes, and what's really missing are some aids for navigating on the page, probably also internal references like in Doxygen/Javadoc and a way to divide the page into several sections (though splitting the module instead would be a better choice here, arguably). Oh, I am not at all trying to argue against the inclusion of datetime into Phobos by the way, I just want to point out that it raises a few issues we should probably better be aware of.
Dec 10 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, December 10, 2010 09:55:02 Fawzi Mohamed wrote:
 On 10-dic-10, at 18:02, Jonathan M Davis wrote:
 
 thanks for the answers
 
 On Friday 10 December 2010 03:18:29 Fawzi Mohamed wrote:
 Clock is used as a namespace of sorts specifically to make the code
 clearer. You
 can think of it as a sort of singleton which has the functions which
 give you
 the time from the system clock. I think that it improves useability.
having a separate module for it would give a similar effect
Having a separate module would defeat the point at least in part. The idea is that you call Clock.currTime() rather than currTime(). You call IRange.everyDayOfWeek!() instead of everyDayOfWeek!(). The benefit is in having the extra name to make it clear what the function is associated with, what it's doing. For instance, conceptually, you're getting the current time from the system clock. This makes it explicit. If it were a separate module, then it would normally just be imported and you'd call currTime() and everyDayOfWeek!() and all the benefit of putting them in that separate namespace is lost.
 - I find that there is a loss of orthogonality between SysTime and
 DateTime. For me there are a calendar dates, and absolute points in
 time. To interconvert between the two one needs a timezone. I would
 associate the timezone with the calendar date and *not* with the
 absolute time.
 I find that SysTime makes too much effort to be a calendar date
 instead of a "point in time".
 Also if one wants to use a point in time at low level it should be
 "lean and mean", what is the timezone doing there?
I don't really get this. Date and DateTime (and thus TimeOfDay) is intended for calendar use. There is no time zone because you're not dealing with exact times which care about the time zone that they're in. They don't necessarily have any relation to UTC or local time. A lot of calendar stuff isn't going to care one whit about time zones. SysTime is specifically supposed to handle the "system time." The system definitely cares about the time zone. You have a local time zone that your system is in. You potentially have to convert between time zones when playing around with time stamps and the like. It's when dealing with the system time that you're really going to care about time zones. So, SysTime includes a time zone, and it is the type to use when you care about the time zone. If you really want dealing with the system time to work correctly in the general case, you need it to have a time zone. I've run into a number of bugs at work precisely because time_t was passed around naked and constantly converted (which, on top of being bug-prone, _cannot_ work correctly due to DST). By having the time in UTC internally at all times and converting it as necessary to the time zone that you want, you avoid a _lot_ of problems with time.
I see two uses of time, one is calender the other a point in time. A point in time needs only to know if other events are before or after it, or how far they are. It should definitely use a unique reference point (for example NSDate uses 1 january 2001). Using UTC is correct, I never argued for something else. the thing is that a point in tame doesn't *need* a timezone, it needs just a reference point. A timezone is needed to convert between calender (TimeDate) and a point in time. So if one wants to store a timezone somewhere (and not use it just when converting between point in time and calender date), then I would store it in calender date, because without it I cannot know to which absolute time it refers, and a calendar date is already larger, and the extra storage is probably not something one would care in typical use of the calendar.
We're obviously thinking of very different use cases here. A SysTime is a specific point in time. It's exact. You can't possibly mistake it for any other point in time ever. It can effectively be displayed and manipulated in a particular time zone, but it is an exact point in time with no ambiguity. DateTime, on the other hand, could represent over 24 different points in time (and that's assuming that it doesn't hit a DST transition). It is not at all exact. It's exact enough for manipulating general dates and times, but it's not exact enough for doing anything that is concerned with being an unambiguous point in time. Sure, it _could_ be made to have a time zone, but that would complicate it further, and many uses wouldn't care at all. It's not associated with machine/system time at all. It's a conceptual point in time but is not an actual, exact point in time in the manner that SysTime is. SysTime is intended for anything that cares about machine/system time and/or dealing with exact, unambiguous points in time. Date/TimeOfDay/DateTime are intended for calendar-based operations and aren't intended to need to care about exact, unambiguous times in the same manner. True, some calendar applications may care about time zone, but they can keep track of that and convert them to SysTimes if necessary. By having SysTime, the default time type deals with time zones and DST correctly without the programmer having to worry about it. That is _not_ true if the time zone is not part of the equation. - Jonathan M Davis
Dec 10 2010
prev sibling next sibling parent reply Kagamin <spam here.lot> writes:
Bernard Helyer Wrote:

 std.gregorian's API doesn't 
 make my normal tasks easy
What tasks do you mean?
Dec 10 2010
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/10/10 11:55 AM, Kagamin wrote:
 Bernard Helyer Wrote:

 std.gregorian's API doesn't
 make my normal tasks easy
What tasks do you mean?
Probably not even worth discussing. std.gregorian was a stub aimed at raising awareness of the necessity of a champion for a date and time framework. Apparently one indeed rose to the challenge :o). std.gregorian will be eliminated by std.datetime. I am confident there was no significant usage of it. I'll close the vote today around 16:00 PST so Walter can prepare a release soon (it is about time with this major addition and 70+ bug fixes). If no seismic counter-argument comes about (but please do voice it if you know of one!) I see it likely that std.datetime will be accepted, modulo a few concerns that can be addressed via the normal maintenance and enhancement process. Contingent to the acceptance of std.datetime, I think it's fit to extend an invitation to Jonathan to join the ranks of Phobos committers. After all he will have written 25% of it, and in a single file no less :o). (klickeverbot: I agree the large file size can become a burden in more than one way going forward, but we can defer the many possible solutions to the time when such problems manifest themselves.) In my opinion Jonathan has earned the Phobos invite by displaying reliability, persistence, maturity (danger of drunken commits at 3AM on Saturday is seemingly low), and of course great skill and understanding of D and its environment. If you have any concerns about this, please either post here or write me email in confidence. Thanks, Andrei
Dec 10 2010
next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 10 Dec 2010 15:49:24 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 In my opinion Jonathan has earned the Phobos invite by displaying  
 reliability, persistence, maturity (danger of drunken commits at 3AM on  
 Saturday is seemingly low)
Nobody mentioned this rule to me! Can't we add a checkin trigger for this? -Steve
Dec 10 2010
prev sibling parent David Nadlinger <see klickverbot.at> writes:
On 12/10/10 9:49 PM, Andrei Alexandrescu wrote:
 (klickeverbot: I agree the large file size can become a burden in more
 than one way going forward, but we can defer the many possible solutions
 to the time when such problems manifest themselves.)
That's the only reasonable choice right now anyway, since only time can tell which issues will actually pop up, if any. By the way, are there any compiler performance issues one should be aware of when dealing with modules containing several megabytes worth of code (just 1.5 MB in this case, but I can think of more extreme cases with generated code). (I figured I should start posting directly under my real name, its spelling is probably easier to remember for non-German speakers than my IRC moinker.)
Dec 10 2010
prev sibling next sibling parent reply Kagamin <spam here.lot> writes:
Fawzi Mohamed Wrote:

 Last thing, well is something I would have done differently (as I said  
 already in the past), is using doubles expressing number of seconds to  
 represent point in time, durations, and TimeOfDay. I know other  
 differs about this, but I really think that it is a very simple and  
 versatile type.
I actually have a problem with this format. I have an application that works with messages. The message has send date. The application was written in delphi so it uses double to represent DateTime. The message can be signed, the date can be included to the data to be signed, so the application uses the double format for sign buffer. Then I have .net application that should interoperate with delphi application, but you can't compute double value from string representation of DateTime in an interoperable way, the last bit depends on the order of computations, and if you miscompute it, the signatures will be incompatible. I think, the point in time should be long, and millisecond precision is enough. Any higher precision is a very special case.
Dec 10 2010
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 10 Dec 2010 15:14:11 -0500, Kagamin <spam here.lot> wrote:

 Fawzi Mohamed Wrote:

 Last thing, well is something I would have done differently (as I said
 already in the past), is using doubles expressing number of seconds to
 represent point in time, durations, and TimeOfDay. I know other
 differs about this, but I really think that it is a very simple and
 versatile type.
I actually have a problem with this format. I have an application that works with messages. The message has send date. The application was written in delphi so it uses double to represent DateTime. The message can be signed, the date can be included to the data to be signed, so the application uses the double format for sign buffer. Then I have .net application that should interoperate with delphi application, but you can't compute double value from string representation of DateTime in an interoperable way, the last bit depends on the order of computations, and if you miscompute it, the signatures will be incompatible. I think, the point in time should be long, and millisecond precision is enough. Any higher precision is a very special case.
longs as milliseconds = a range of +/- 300 million years. I'd call that the special case. The hnsecs as the base (100 nano-seconds) gives a range of +/- 30000 years. nanosecond ticks would yield +/- 300 years. 10 nanosecond ticks would yield +/- 3000 which is doable, but leaves our decendants to deal with the year 3000 problem (highly unlikely that anything like D will be still in use at that time, but still...). I think 100-nsecs is a good choice for tick resolution. It gives a very generous range for working with, plus is fine-grained enough to deal with many years of speed increases in processors. Noteworthy is that Microsoft uses the same resolution (as does Tango), so there's at least anecdotal evidence that it's a natural choice for tick resolution. -Steve
Dec 10 2010
parent Kagamin <spam here.lot> writes:
Steven Schveighoffer Wrote:

 I think 100-nsecs is a good choice for tick resolution.
My concern is millisecond is a SI unit, but hectonanosecond isn't, so I don't think, it's a good choice: it's hardly comprehensible.
 It gives a very generous range for working  
 with, plus is fine-grained enough to deal with many years of speed  
 increases in processors.
Clock and stopwatch have different usages. I think, it's no problem to design stopwatch with tunable precision (as a template parameter).
Dec 12 2010
prev sibling parent Fawzi Mohamed <fawzi gmx.ch> writes:
On 10-dic-10, at 21:14, Kagamin wrote:

 Fawzi Mohamed Wrote:

 Last thing, well is something I would have done differently (as I  
 said
 already in the past), is using doubles expressing number of seconds  
 to
 represent point in time, durations, and TimeOfDay. I know other
 differs about this, but I really think that it is a very simple and
 versatile type.
I actually have a problem with this format. I have an application that works with messages. The message has send date. The application was written in delphi so it uses double to represent DateTime. The message can be signed, the date can be included to the data to be signed, so the application uses the double format for sign buffer. Then I have .net application that should interoperate with delphi application, but you can't compute double value from string representation of DateTime in an interoperable way, the last bit depends on the order of computations, and if you miscompute it, the signatures will be incompatible.
When signing normally one sends also the original message (with date), so I guess I don't understand your example, sorry... And again I am *not* arguing to use double exclusively, just for absolute times, and as option for durations, and for the TimeOfDay
 I think, the point in time should be long, and millisecond precision  
 is enough. Any higher precision is a very special case.
but what is the problem if you do have it? that it is more difficult to guess the exact value you will read? why would any sane setting need that?
Dec 10 2010
prev sibling next sibling parent Fawzi Mohamed <fawzi gmx.ch> writes:
On 10-dic-10, at 20:07, Jonathan M Davis wrote:

 On Friday, December 10, 2010 09:55:02 Fawzi Mohamed wrote:
 On 10-dic-10, at 18:02, Jonathan M Davis wrote:

 thanks for the answers

 On Friday 10 December 2010 03:18:29 Fawzi Mohamed wrote:
 Clock is used as a namespace of sorts specifically to make the code
 clearer. You
 can think of it as a sort of singleton which has the functions which
 give you
 the time from the system clock. I think that it improves useability.
having a separate module for it would give a similar effect
Having a separate module would defeat the point at least in part. The idea is that you call Clock.currTime() rather than currTime(). You call IRange.everyDayOfWeek!() instead of everyDayOfWeek!(). The benefit is in having the extra name to make it clear what the function is associated with, what it's doing. For instance, conceptually, you're getting the current time from the system clock. This makes it explicit. If it were a separate module, then it would normally just be imported and you'd call currTime() and everyDayOfWeek!() and all the benefit of putting them in that separate namespace is lost.
import Clock=std.time.Clock; Clock.currTime();
 - I find that there is a loss of orthogonality between SysTime and
 DateTime. For me there are a calendar dates, and absolute points in
 time. To interconvert between the two one needs a timezone. I would
 associate the timezone with the calendar date and *not* with the
 absolute time.
 I find that SysTime makes too much effort to be a calendar date
 instead of a "point in time".
 Also if one wants to use a point in time at low level it should be
 "lean and mean", what is the timezone doing there?
I don't really get this. Date and DateTime (and thus TimeOfDay) is intended for calendar use. There is no time zone because you're not dealing with exact times which care about the time zone that they're in. They don't necessarily have any relation to UTC or local time. A lot of calendar stuff isn't going to care one whit about time zones. SysTime is specifically supposed to handle the "system time." The system definitely cares about the time zone. You have a local time zone that your system is in. You potentially have to convert between time zones when playing around with time stamps and the like. It's when dealing with the system time that you're really going to care about time zones. So, SysTime includes a time zone, and it is the type to use when you care about the time zone. If you really want dealing with the system time to work correctly in the general case, you need it to have a time zone. I've run into a number of bugs at work precisely because time_t was passed around naked and constantly converted (which, on top of being bug-prone, _cannot_ work correctly due to DST). By having the time in UTC internally at all times and converting it as necessary to the time zone that you want, you avoid a _lot_ of problems with time.
I see two uses of time, one is calender the other a point in time. A point in time needs only to know if other events are before or after it, or how far they are. It should definitely use a unique reference point (for example NSDate uses 1 january 2001). Using UTC is correct, I never argued for something else. the thing is that a point in tame doesn't *need* a timezone, it needs just a reference point. A timezone is needed to convert between calender (TimeDate) and a point in time. So if one wants to store a timezone somewhere (and not use it just when converting between point in time and calender date), then I would store it in calender date, because without it I cannot know to which absolute time it refers, and a calendar date is already larger, and the extra storage is probably not something one would care in typical use of the calendar.
We're obviously thinking of very different use cases here. A SysTime is a specific point in time. It's exact. You can't possibly mistake it for any other point in time ever. It can effectively be displayed and manipulated in a particular time zone, but it is an exact point in time with no ambiguity.
That is *exactly* my point SysTime is a point in time *not* a calender, the current apy tries too hard to make it behave like a calender, and the presence of a timezone in there reflects this
 DateTime, on the other hand, could represent over 24 different  
 points in time
 (and that's assuming that it doesn't hit a DST transition). It is  
 not at all
 exact. It's exact enough for manipulating general dates and times,  
 but it's not
 exact enough for doing anything that is concerned with being an  
 unambiguous
 point in time. Sure, it _could_ be made to have a time zone, but  
 that would
 complicate it further, and many uses wouldn't care at all. It's not  
 associated
 with machine/system time at all. It's a conceptual point in time but  
 is not an
 actual, exact point in time in the manner that SysTime is.
Then timezone should be only in the conversion routines between SysTime and DateTime.
 SysTime is intended for anything that cares about machine/system  
 time and/or
 dealing with exact, unambiguous points in time. Date/TimeOfDay/ 
 DateTime are
 intended for calendar-based operations and aren't intended to need  
 to care about
 exact, unambiguous times in the same manner. True, some calendar  
 applications
 may care about time zone, but they can keep track of that and  
 convert them to
 SysTimes if necessary.
Again there is no reason to have a timezone in SysTime, probably it should be just in the conversion routines, and if one really wants to have it somewhere then I argue that it is better to put them in DateTime (makeing it behave like a point in time) rather than in SysTime (as now, making it behave like a calendar).
 By having SysTime, the default time type deals with time zones and  
 DST correctly
 without the programmer having to worry about it. That is _not_ true  
 if the time
 zone is not part of the equation.
what do you mean either one has to pass the timezone (and thus worry about it) or use the default one, how is that different from passing the timezone or not to a conversion routine?
 - Jonathan M Davis
Dec 10 2010
prev sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, December 10, 2010 15:29:40 Fawzi Mohamed wrote:
 On 10-dic-10, at 20:07, Jonathan M Davis wrote:
 On Friday, December 10, 2010 09:55:02 Fawzi Mohamed wrote:
 On 10-dic-10, at 18:02, Jonathan M Davis wrote:
 
 thanks for the answers
 
 On Friday 10 December 2010 03:18:29 Fawzi Mohamed wrote:
 Clock is used as a namespace of sorts specifically to make the code
 clearer. You
 can think of it as a sort of singleton which has the functions which
 give you
 the time from the system clock. I think that it improves useability.
having a separate module for it would give a similar effect
Having a separate module would defeat the point at least in part. The idea is that you call Clock.currTime() rather than currTime(). You call IRange.everyDayOfWeek!() instead of everyDayOfWeek!(). The benefit is in having the extra name to make it clear what the function is associated with, what it's doing. For instance, conceptually, you're getting the current time from the system clock. This makes it explicit. If it were a separate module, then it would normally just be imported and you'd call currTime() and everyDayOfWeek!() and all the benefit of putting them in that separate namespace is lost.
import Clock=std.time.Clock; Clock.currTime();
Except then you have to go out of your way to do that. It's no longer the default.
 - I find that there is a loss of orthogonality between SysTime and
 DateTime. For me there are a calendar dates, and absolute points in
 time. To interconvert between the two one needs a timezone. I would
 associate the timezone with the calendar date and *not* with the
 absolute time.
 I find that SysTime makes too much effort to be a calendar date
 instead of a "point in time".
 Also if one wants to use a point in time at low level it should be
 "lean and mean", what is the timezone doing there?
I don't really get this. Date and DateTime (and thus TimeOfDay) is intended for calendar use. There is no time zone because you're not dealing with exact times which care about the time zone that they're in. They don't necessarily have any relation to UTC or local time. A lot of calendar stuff isn't going to care one whit about time zones. SysTime is specifically supposed to handle the "system time." The system definitely cares about the time zone. You have a local time zone that your system is in. You potentially have to convert between time zones when playing around with time stamps and the like. It's when dealing with the system time that you're really going to care about time zones. So, SysTime includes a time zone, and it is the type to use when you care about the time zone. If you really want dealing with the system time to work correctly in the general case, you need it to have a time zone. I've run into a number of bugs at work precisely because time_t was passed around naked and constantly converted (which, on top of being bug-prone, _cannot_ work correctly due to DST). By having the time in UTC internally at all times and converting it as necessary to the time zone that you want, you avoid a _lot_ of problems with time.
I see two uses of time, one is calender the other a point in time. A point in time needs only to know if other events are before or after it, or how far they are. It should definitely use a unique reference point (for example NSDate uses 1 january 2001). Using UTC is correct, I never argued for something else. the thing is that a point in tame doesn't *need* a timezone, it needs just a reference point. A timezone is needed to convert between calender (TimeDate) and a point in time. So if one wants to store a timezone somewhere (and not use it just when converting between point in time and calender date), then I would store it in calender date, because without it I cannot know to which absolute time it refers, and a calendar date is already larger, and the extra storage is probably not something one would care in typical use of the calendar.
We're obviously thinking of very different use cases here. A SysTime is a specific point in time. It's exact. You can't possibly mistake it for any other point in time ever. It can effectively be displayed and manipulated in a particular time zone, but it is an exact point in time with no ambiguity.
That is *exactly* my point SysTime is a point in time *not* a calender, the current apy tries too hard to make it behave like a calender, and the presence of a timezone in there reflects this
 DateTime, on the other hand, could represent over 24 different
 points in time
 (and that's assuming that it doesn't hit a DST transition). It is
 not at all
 exact. It's exact enough for manipulating general dates and times,
 but it's not
 exact enough for doing anything that is concerned with being an
 unambiguous
 point in time. Sure, it _could_ be made to have a time zone, but
 that would
 complicate it further, and many uses wouldn't care at all. It's not
 associated
 with machine/system time at all. It's a conceptual point in time but
 is not an
 actual, exact point in time in the manner that SysTime is.
Then timezone should be only in the conversion routines between SysTime and DateTime.
 SysTime is intended for anything that cares about machine/system
 time and/or
 dealing with exact, unambiguous points in time. Date/TimeOfDay/
 DateTime are
 intended for calendar-based operations and aren't intended to need
 to care about
 exact, unambiguous times in the same manner. True, some calendar
 applications
 may care about time zone, but they can keep track of that and
 convert them to
 SysTimes if necessary.
Again there is no reason to have a timezone in SysTime, probably it should be just in the conversion routines, and if one really wants to have it somewhere then I argue that it is better to put them in DateTime (makeing it behave like a point in time) rather than in SysTime (as now, making it behave like a calendar).
 By having SysTime, the default time type deals with time zones and
 DST correctly
 without the programmer having to worry about it. That is _not_ true
 if the time
 zone is not part of the equation.
what do you mean either one has to pass the timezone (and thus worry about it) or use the default one, how is that different from passing the timezone or not to a conversion routine?
Converting time back and forth is _bad_, _really_ bad. It does _not_ work in the face of DST (some times exist twice while others don't exist at all). By specifically having a type which holds the time in UTC at _all_ times but which allows you to operate on it assuming a particular time zone, you are able to have the time be correct and yet still operate in your local time zone (or whatever other time zone that you wish to operate in). It fixes time conversion problems. If you're constantly converting back and forth between DateTime and SysTime, you _will_ have conversion problems. SysTime is intended to hold an exact time with a time zone, so that you have an unambiguous time which is actually able to be used in your local time without doing any conversions. Date/TimeOfDay/DateTime are intended for calendar operations which do not care about time zone. All of the operations on DateTime can be done on SysTime (and most of the operations on SysTime can be done on DateTime) if you want a time zone - they're just considerably less efficient. DateTime gives you a type which allows for calendar operations to be efficient (like getting the current day or adding a month to a date), unlike SysTime where its operations are optimized for dealing with the OS. If you want to do calender operations efficiently and yet still have a time zone, then you're going to have to keep track of what time zone you're dealing with for when you convert it to a SysTime. Unfortunately, because DateTime is _not_ in UTC but is a generic time, there can be conversion problems when converting to a SysTime for a time which is during a DST switch. But if it were in UTC, then it wouldn't be a generic date or time any longer, and the calendar operations would no longer be as efficient because conversions would have to be done everywhere. SysTime is pretty much the entire reason that I wanted to write std.datetime. By having both the time in UTC and the time zone in a single type, it is possible to correctly handle time in the face of time zone and DST changes. I'm sick of having to fix bugs relating to converting time. I want D to do it right. Date exists because I originally based std.datetime on the Boost API (which has a date class), and because I thought that it would be worthwhile to have a date type which was efficient for date/calendar operations. Having that, it seemed useful to have one which included the time and was efficient for calendar operations. So, I created TimeOfDay and DateTime. The entire purpose of Date/TimeOfDay/DateTime is to have types which are efficient for calendar operations and which don't care about time zones. You're dealing with a date and/or time which is generic and is not an absolute point in time - it has a time zone or insists on being in UTC (which would make pretty much all of their operations less efficient). SysTime is the type you use for getting the system time. It is the type that I expect to be used the most. It's the type that functions like std.file.lastModified() will use. Date, TimeOfDay, and DateTime exist for cases where people are interested in efficient calendar operations, don't care about the connection between that date/time and the system time, and don't care about the time zone. You can convert between the two but the risk the run of conversion problems whenever DST changes. I believe that you're the first to complain about how SysTime has a TimeZone and DateTime doesn't, so I don't get the impression that folks in general have a problem with that (though it could just be that not enough people have read the code). But the use case for SysTime calls for a time zone whereas the use case for Date/TimeOfDay/DateTime doesn't. I think that the problem is that you're just thinking about calendars and what calendar time indicates differently than I am. - Jonathan M Davis
Dec 10 2010
next sibling parent reply David Nadlinger <see klickverbot.at> writes:
On 12/11/10 1:17 AM, Jonathan M Davis wrote:
 Except then you have to go out of your way to do that. It's no longer the
 default.
Well, as the user would explicitly import that module anyway, it's just a few extra characters. You could always team up with bearophile to push only importing the module name into scope by default though, I guess. ;) I personally have one major problem with classes used to fake namespaces in datetime – that it's going to be part of the standard library. I mean, if you personally prefer classes to the »canonical« approach of using modules for grouping related code, that's fine with me, but now this is part of Phobos, and I'm pretty sure that some people will ask (at least themselves): Hey, so there are these neat things called modules in D which are supposed to be used for organizing your code, but still they have mixed different concepts together in that datetime part of the standard library, using classes as pseudo namespaces so things don't get mixed up too much – why that?
Dec 10 2010
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday 10 December 2010 17:10:05 David Nadlinger wrote:
 On 12/11/10 1:17 AM, Jonathan M Davis wrote:
 Except then you have to go out of your way to do that. It's no longer t=
he
 default.
=20 Well, as the user would explicitly import that module anyway, it's just a few extra characters. You could always team up with bearophile to push only importing the module name into scope by default though, I guess. ;) =20 I personally have one major problem with classes used to fake namespaces in datetime =E2=80=93 that it's going to be part of the standard library.=
I
 mean, if you personally prefer classes to the =C2=BBcanonical=C2=AB appro=
ach of
 using modules for grouping related code, that's fine with me, but now
 this is part of Phobos, and I'm pretty sure that some people will ask
 (at least themselves):
=20
 Hey, so there are these neat things called modules in D which are
 supposed to be used for organizing your code, but still they have mixed
 different concepts together in that datetime part of the standard
 library, using classes as pseudo namespaces so things don't get mixed up
 too much =E2=80=93 why that?
Well, I'm not the only one to have done it. IIRC, the new std.process will = have=20 a class that acts as a namespace in it. What I'm trying to create here are some very specific namespaces which are = always=20 used. Creating a separate module would make no sense and would make it so t= hat=20 you wouldn't actually use the namespace name to access the functions, which= =20 would defeat the purpose of the namespace in the first place. Other languag= es=20 allow for namespaces within files or modules. D doesn't have such a mechani= sm, so=20 some of us have chosen to use uninstantiatable classes for that in limited= =20 circumstances. I am by no means arguing that it should be done frequently (= quite=20 the opposite, really), but I think that the cases that use them in std.date= time=20 definitely benefit from it. =2D Jonathan M Davis
Dec 10 2010
prev sibling parent Christopher Nicholson-Sauls <ibisbasenji gmail.com> writes:
On 12/10/10 18:17, Jonathan M Davis wrote:
 On Friday, December 10, 2010 15:29:40 Fawzi Mohamed wrote:
 On 10-dic-10, at 20:07, Jonathan M Davis wrote:
 On Friday, December 10, 2010 09:55:02 Fawzi Mohamed wrote:
 On 10-dic-10, at 18:02, Jonathan M Davis wrote:

 thanks for the answers

 On Friday 10 December 2010 03:18:29 Fawzi Mohamed wrote:
 Clock is used as a namespace of sorts specifically to make the code
 clearer. You
 can think of it as a sort of singleton which has the functions which
 give you
 the time from the system clock. I think that it improves useability.
having a separate module for it would give a similar effect
Having a separate module would defeat the point at least in part. The idea is that you call Clock.currTime() rather than currTime(). You call IRange.everyDayOfWeek!() instead of everyDayOfWeek!(). The benefit is in having the extra name to make it clear what the function is associated with, what it's doing. For instance, conceptually, you're getting the current time from the system clock. This makes it explicit. If it were a separate module, then it would normally just be imported and you'd call currTime() and everyDayOfWeek!() and all the benefit of putting them in that separate namespace is lost.
import Clock=std.time.Clock; Clock.currTime();
Except then you have to go out of your way to do that. It's no longer the default.
Reminds me of an enhancement request I made ages ago to allow a 'static module' statement which would make 'static import' required. Here we are wishing for it, or something like it, once again. http://d.puremagic.com/issues/show_bug.cgi?id=1297 -- Chris N-S
Dec 10 2010