Jonathan M Davis napisał: > On Wednesday, November 10, 2010 15:03:11 Tomek Sowiński wrote: >> Jonathan M Davis napisał: >> > Latest: http://is.gd/gSwDv >> >> My 2 cents: >> >> Units of time are represented more naturally by an integer enum (could be >> anonymous) than a string. >> >> A problem recurring in many methods: >> >> /+ref+/ Date opOpAssign(string op, D)(in D duration) nothrow >> if((op == "+" || op == "-") && >> (is(Unqual!D == Duration) || >> is(Unqual!D == TickDuration))) >> { >> static if(op == "+") >> { >> static if(is(Unqual!D == Duration)) >> return addDays(convert!("hnsecs", >> "days")(duration.total!"hnsecs")); else static if(is(Unqual!D == >> TickDuration)) >> return addDays(convert!("hnsecs", >> "days")(duration.hnsecs)); } >> else >> { >> static if(is(Unqual!D == Duration)) >> return addDays(convert!("hnsecs", >> "days")(-duration.total!"hnsecs")); else static if(is(Unqual!D == >> TickDuration)) >> return addDays(convert!("hnsecs", >> "days")(-duration.hnsecs)); } >> } >> >> If you're static if'ing each statement, it's a good sign the method >> should be broken up into two overloads. BTW, what was the problem with >> returning by ref? > > I don't see any real benefit in splitting a function into two overloads > rather than using static ifs in this manner. The resulting source code is > likely nearly identical. You only end up with one function to document > this way, and in this case the user doesn't necessarily care about what > type of duration they're dealing with. If, they want to add or subtract a > duration, here's the function to do it. If anything, I think that I tend > to favor using static ifs over duplicate functions with different template > constraints if there's no real difference in the from the users > perspective.
Fair enough, although it's no excuse for copy-paste programming. It can be easily wrung out of duplication with no loss in readability: /+ref+/ Date opOpAssign(string op)(in Duration duration) nothrow if((op == "+" || op == "-") && (is(Unqual!D == Duration) || is(Unqual!D == TickDuration))) { static if (is(Unqual!D == Duration)) auto hnecs = duration.total!"hnsecs"; else auto hnecs = duration.hnsecs; return addDays(convert!("hnsecs", "days")(unaryFun!(op~"a")(hnsecs))); } The user may not care, but the maintainer does. Not even convinced about the former, when writing I often seek introspection in Phobos source. Besides, this is the Standard Library, it should hold code of exemplary quality. BTW, I still think units of time should be an enum, not a string. > As for the ref, there are several bugs relating to that. One I remember > right off the top of my head is that you can't have a template function > return by ref for some reason. I think that there's at least one related > to invariants too, though the one about invariants not being able to be > pure has been fixed which has reduced some of the invariant-related > problems. A number of bugs relating to const-correctness, purity, and > invariants have caused me a lot of headaches when working on datetime. Oh yeah, I know how that hurts ;) >> Finally, bordering on bikeshed, weekdays' names are long and months' are >> short. Having both short and long names for weekdays and months would >> solve the inconsistency and satisfy everyone. > > I hadn't thought about that. I'll think about it. I'm not sure that it > really matters much though. I tend to prefer full names over short names, > but that can become tedious when you use them a lot. 3-letter shorts, e.g. January-Jan, February-Feb, Monday-Mon, Tuesday-Tue are recognized by just about everyone. It makes sense to include both. >> Are there any plans for a Calendar interface to allow user >> implementations that distinguish business days and holidays? > > I'm afraid that I have no clue what you're talking about. I mean, I know > what a business day is and what a holiday is, but I'm not sure what you > mean by a calendar interface in this context. Sorry, was talking QuantLib, I meant something like this: http://dsource.org/projects/quantlibd/browser/ql/time/calendars.d (copy-pasting sucks, I know;)) > Are you looking for a way to > query whether a particular day is a business day, weekend day, or holiday? > That strikes me as being a function rather than an interface An interface (or abstract class) makes sense. E.g. I may want to get the number of working days between this and this date. It may be implemented faster than walking the interval and pecking day by day. > and it would > be locale-dependent enough that I can't see it making into the standard > library. Designing the interface and, more importantly, solving how to store the holiday information to allow fast interval querying is not locale-specific. Plus, it is in common need for business, and it is not trivial -- ideal candidate for the standard library. Then everyone can write an implementation for their favorite country or stock exchange on their own. >> Maybe I'm late on the 'pure' changes, but how come all the setters are >> pure? I mean it modifies the (hidden) argument of the function, so it >> shouldn't be, no? > > They'd be weakly pure rather than strongly pure. Ultimately, I believe > that the only functions in std.datetime which should be non-pure are the > ones which access global variables or make a call whose potentially result > changes every call (like getting the time) or functions who indirectly > call such functions. Some of those will be strongly pure and some won't, > but it's a royal pain get much in the way of strongly pure functions > without weakly pure ones. That suggestion of Don's was fantastic and will > quite possibly make pure useable. > > Weakly pure functions are functions which don't access globals or return a > different result with each call but which can't be optimized out, whereas > strongly pure functions are the same except that all of their parameters > are immutable or can be implicitly converted to immutable, and they _can_ > be optimized out in some cases. So, the getters in many cases would be > strongly pure, whereas the setters would be weakly pure. So it's in? Excellent! -- Tomek