Please vote on std.datetime

Jonathan M Davis jmdavisProg at gmx.com
Fri Dec 10 12:21:38 PST 2010


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


More information about the Digitalmars-d mailing list