[chrono/date] Unit specifiers arithmetic
Hi, Moving from checked dates to unchecked ones by default and forcing to user the Unit specifiers year/month/day in any date constructor (even the unchecked ones) has some ugly consequences. Note that I was able to build an unchecked date as date d(2013,5,6, no_check); Given year y; month m; day d; the following will not compile now as the constructors expects a year but y+1 is an int. date d(y+1, m, d); The user needs to type date d(year(y+1), m, d); Is this what we want to provide to the user or should we add basic arithmetic on these unit specifiers? Best, Vicente
On May 6, 2013, at 6:31 AM, "Vicente J. Botet Escriba"
Hi,
Moving from checked dates to unchecked ones by default and forcing to user the Unit specifiers year/month/day in any date constructor (even the unchecked ones) has some ugly consequences. Note that I was able to build an unchecked date as
date d(2013,5,6, no_check);
Given
year y; month m; day d;
the following will not compile now as the constructors expects a year but y+1 is an int.
date d(y+1, m, d);
The user needs to type
date d(year(y+1), m, d);
Is this what we want to provide to the user or should we add basic arithmetic on these unit specifiers?
This is an example of where flexible ordering and implicit last unit starts to shine. Examples from my 2011 paper: start = mon <= jan4/(d.year()-1); date next_start = mon <= jan4/(start.year()+1); Or translated to your example and syntax: date d(d, m, y+1); // works because last unit can be int If we start adding arithmetic to the unit specifier day, it becomes indistinguishable from a duration. Now it is possible that we could use durations as unit specifiers. But that seems messy to me, especially for months and days. However it would align us more closely with struct tm, which specifies many (but not all) of its fields in terms of durations: int tm_mday; // day of the month — [1, 31] -- a day specifier, // but could be reinterpreted as days since last day of previous month int tm_mon; // months since January — [0, 11] -- a months duration Howard
Le 06/05/13 15:34, Howard Hinnant a écrit :
On May 6, 2013, at 6:31 AM, "Vicente J. Botet Escriba"
wrote: Hi,
Moving from checked dates to unchecked ones by default and forcing to user the Unit specifiers year/month/day in any date constructor (even the unchecked ones) has some ugly consequences. Note that I was able to build an unchecked date as
date d(2013,5,6, no_check);
Given
year y; month m; day d;
the following will not compile now as the constructors expects a year but y+1 is an int.
date d(y+1, m, d);
The user needs to type
date d(year(y+1), m, d);
Is this what we want to provide to the user or should we add basic arithmetic on these unit specifiers? This is an example of where flexible ordering and implicit last unit starts to shine. Examples from my 2011 paper:
start = mon <= jan4/(d.year()-1);
date next_start = mon <= jan4/(start.year()+1);
Or translated to your example and syntax:
date d(d, m, y+1); // works because last unit can be int Last unit or any unit but only one?
If we start adding arithmetic to the unit specifier day, it becomes indistinguishable from a duration. Now it is possible that we could use durations as unit specifiers. -1
Vicente
On May 6, 2013, at 9:55 AM, "Vicente J. Botet Escriba"
Le 06/05/13 15:34, Howard Hinnant a écrit :
On May 6, 2013, at 6:31 AM, "Vicente J. Botet Escriba"
wrote: Hi,
Moving from checked dates to unchecked ones by default and forcing to user the Unit specifiers year/month/day in any date constructor (even the unchecked ones) has some ugly consequences. Note that I was able to build an unchecked date as
date d(2013,5,6, no_check);
Given
year y; month m; day d;
the following will not compile now as the constructors expects a year but y+1 is an int.
date d(y+1, m, d);
The user needs to type
date d(year(y+1), m, d);
Is this what we want to provide to the user or should we add basic arithmetic on these unit specifiers? This is an example of where flexible ordering and implicit last unit starts to shine. Examples from my 2011 paper:
start = mon <= jan4/(d.year()-1);
date next_start = mon <= jan4/(start.year()+1);
Or translated to your example and syntax:
date d(d, m, y+1); // works because last unit can be int
Last unit or any unit but only one?
Any two explicit units should disambiguate. We could even take it more lax than that and still avoid ambiguity if desired. A warning though: We want to make the checked syntax more attractive than the unchecked syntax, else all dates will be unnecessarily unchecked in practice.
If we start adding arithmetic to the unit specifier day, it becomes indistinguishable from a duration. Now it is possible that we could use durations as unit specifiers.
-1
Agreed. Howard
Le 06/05/13 16:10, Howard Hinnant a écrit :
On May 6, 2013, at 9:55 AM, "Vicente J. Botet Escriba"
wrote: Le 06/05/13 15:34, Howard Hinnant a écrit :
On May 6, 2013, at 6:31 AM, "Vicente J. Botet Escriba"
wrote: Hi,
Moving from checked dates to unchecked ones by default and forcing to user the Unit specifiers year/month/day in any date constructor (even the unchecked ones) has some ugly consequences. Note that I was able to build an unchecked date as
date d(2013,5,6, no_check);
Given
year y; month m; day d;
the following will not compile now as the constructors expects a year but y+1 is an int.
date d(y+1, m, d);
The user needs to type
date d(year(y+1), m, d);
Is this what we want to provide to the user or should we add basic arithmetic on these unit specifiers? This is an example of where flexible ordering and implicit last unit starts to shine. Examples from my 2011 paper:
start = mon <= jan4/(d.year()-1);
date next_start = mon <= jan4/(start.year()+1);
Or translated to your example and syntax:
date d(d, m, y+1); // works because last unit can be int Last unit or any unit but only one? Any two explicit units should disambiguate. We could even take it more lax than that and still avoid ambiguity if desired.
A warning though: We want to make the checked syntax more attractive than the unchecked syntax, else all dates will be unnecessarily unchecked in practice.
Agreed. But some (in particular N3344) are requesting this prototype :( date(int,int,int); I suspect they would not adhere to the named parameters. Vicente
On May 6, 2013, at 10:42 AM, "Vicente J. Botet Escriba"
Le 06/05/13 16:10, Howard Hinnant a écrit :
On May 6, 2013, at 9:55 AM, "Vicente J. Botet Escriba"
wrote: Le 06/05/13 15:34, Howard Hinnant a écrit :
On May 6, 2013, at 6:31 AM, "Vicente J. Botet Escriba"
wrote: Hi,
Moving from checked dates to unchecked ones by default and forcing to user the Unit specifiers year/month/day in any date constructor (even the unchecked ones) has some ugly consequences. Note that I was able to build an unchecked date as
date d(2013,5,6, no_check);
Given
year y; month m; day d;
the following will not compile now as the constructors expects a year but y+1 is an int.
date d(y+1, m, d);
The user needs to type
date d(year(y+1), m, d);
Is this what we want to provide to the user or should we add basic arithmetic on these unit specifiers? This is an example of where flexible ordering and implicit last unit starts to shine. Examples from my 2011 paper:
start = mon <= jan4/(d.year()-1);
date next_start = mon <= jan4/(start.year()+1);
Or translated to your example and syntax:
date d(d, m, y+1); // works because last unit can be int Last unit or any unit but only one? Any two explicit units should disambiguate. We could even take it more lax than that and still avoid ambiguity if desired.
A warning though: We want to make the checked syntax more attractive than the unchecked syntax, else all dates will be unnecessarily unchecked in practice.
Agreed. But some (in particular N3344) are requesting this prototype :(
date(int,int,int);
I suspect they would not adhere to the named parameters.
A poor reason to create a poor design. A design that would be in direct conflict with the std::chrono library: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm#duration
Is it possible for the user to pass a duration to a function with the units being ambiguous?
Howard
On May 6, 2013, at 10:10 AM, Howard Hinnant
On May 6, 2013, at 9:55 AM, "Vicente J. Botet Escriba"
wrote: Le 06/05/13 15:34, Howard Hinnant a écrit :
This is an example of where flexible ordering and implicit last unit starts to shine. Examples from my 2011 paper:
start = mon <= jan4/(d.year()-1);
date next_start = mon <= jan4/(start.year()+1);
Or translated to your example and syntax:
date d(d, m, y+1); // works because last unit can be int
Last unit or any unit but only one?
Any two explicit units should disambiguate. We could even take it more lax than that and still avoid ambiguity if desired.
+1
A warning though: We want to make the checked syntax more attractive than the unchecked syntax, else all dates will be unnecessarily unchecked in practice.
Separate types can handle the checked/unchecked difference, and both can be equally easy to use.
If we start adding arithmetic to the unit specifier day, it becomes indistinguishable from a duration. Now it is possible that we could use durations as unit specifiers. -1
Agreed.
I agree, so long as the unit types convert to int, thereby allowing arithmetic operations. (I think that is implied above, but I wanted to be certain.) ___ Rob (Sent from my portable computation engine)
2013/5/6 Vicente J. Botet Escriba
Hi,
Moving from checked dates to unchecked ones by default and forcing to user the Unit specifiers year/month/day in any date constructor (even the unchecked ones) has some ugly consequences. Note that I was able to build an unchecked date as
date d(2013,5,6, no_check);
Given
year y; month m; day d;
the following will not compile now as the constructors expects a year but y+1 is an int.
date d(y+1, m, d);
The user needs to type
date d(year(y+1), m, d);
Is this what we want to provide to the user or should we add basic arithmetic on these unit specifiers?
Best, Vicente
I suggest pointer-like arithmetic on the types. I.e. for year: year +- int -> year int + year -> year year - year -> int year + year -- not allowed The above seems intuitive to me. And to avoid unexpected situations I suggest disabling the implicit conversions: year <-> int I think any built-in integer makes sense instead of int here. Regards, Kris
participants (4)
-
Howard Hinnant
-
Krzysztof Czainski
-
Rob Stewart
-
Vicente J. Botet Escriba