[threeten-dev] [threeten-develop] TemporalAdder and TemporalSubtractor

Stephen Colebourne scolebourne at joda.org
Mon Dec 31 13:21:16 PST 2012


Ultimately, this is a question of what abstractions make sense vs what
abstractions are needed.

Everyone agrees that a TemporalPeriod abstraction over all period-like
things makes sense. I haven't included this so far as there is no
period formatting, thus no need for the interface. This also means
that there is no code to test that the interface contains the right
set of methods, something that I find concerning (unless someone is
volunteering to write a period formatter).

The Adder/Subtractor interfaces are simple concepts that extend a
pattern we know works in adjuster. It makes a simple pattern complete
- each of get/set/plus/minus has a dedicated "primitive" method and a
dedicated "functional interface" method
(Query/Adjuster/Adder/Subtractor). Breaking this simple pattern also
has risks.

Set against this is the element of duplication. The functionality of
an Adder/Subtractor can be successfully provided by an adjuster.
However, doing that results in (a) worse method names/fluency -
with(workingDaysAdded(6)) - and (b) duplicated adjuster
implementations - with(workingDaysAdded()) and
with(workingDaysSubtracted()).

Removing Adder/Subtractor in favour of adjusters also requires that we
add a TemporalPeriod interface, so as to ensure that sensible code
like date.plus(period) still works.


At this point, I am willing to consider the change, however I am
*very* concerned that we will not get the correct set of
TemporalPeriod methods. I also note that if we make this change, then
Adder/Subtractor will not be able to return in a future JDK (due to
method overloading issues), so this is a one-shot deal.

Proposals welcome on how we can prove the set of methods on TemporalPeriod.
Are we willing to prototype a period formatter?
Should the access be like Temporal (isSupported/get/getLong), or the
return of a Map object?
Are the isPositive/isNegative etc methods needed?
Is the interface intended for users (more methods) or frameworks (less methods)?

Stephen


On 31 December 2012 17:01, Roger Riggs <Roger.Riggs at oracle.com> wrote:
> The nomenclature needs to be cleaned up and the types for Duration, Period,
> and SimplePeriod would benefit from a unifying type (class or interface).
>
> The Temporal type defines methods minus and plus whose arguments should
> be relative temporal values.  But the current types and agument names are
> functional and are inconsistent with the method names plus and minus.
>
> Duration and Period are very similar, both are relative times and need to be
> to be applied to Temporal entities to be useful, they differ in the
> representation
> for times greater than 24 hours.
>
> A common (super) type defining methods would tie them together:
>  -  T addTo(T),
>  -  T subtractFrom(T),
>  -  isNegative, isPositive, isZero,
>  -  minus(n, Unit), plus(n, Unit)
>
> TemporalPeriod is a fine name, since we've established that temporal
> relates to anything about time.
>
> And perhaps to connect the operations between absolute temporal values
> and relative temporal values together better, the Temporal periodUntil(T, T)
> should return a SimplePeriod.  (Though separately, SimplePeriod could be
> subsumed into Period).
>
> The api already has the Adjuster interface to encapsulate arbitrary
> functions on TA's;
> using it for computing offsets from TAs will avoid confusing definitions of
> Duration
> or Period/SimplePeriod which are fixed values derived from other periods.
>
> Roger
>
>
>
>
>
> On 12/28/2012 12:08 AM, Xueming Shen wrote:
>>
>> On 12/27/2012 9:53 AM, Stephen Colebourne wrote:
>>>
>>> On 21 December 2012 20:27, Xueming Shen<xueming.shen at oracle.com>  wrote:
>>>>
>>>> How to define TemporalPeriod is not my point here, the methods I'm
>>>> adding in are to fit it for the minus/plus operation, as the
>>>> TemporalField/
>>>> Unit interface does. We definitely add more "general" access method
>>>> into it, as you just suggested. Consider this, if we do introduce the
>>>> TemporalPeriod later, does that make the TemporalAdder/Subtractor a
>>>> redundant? at least for all the functionality it currently trying to
>>>> provide?
>>>> then make the TemporalPeriod subclass of both Adder and Subtractor?
>>>
>>> Were there to be a TemporalPeriod (since it isn't a temporal, it
>>> should really be called something else, like Perioral), then it would
>>> not extend Adder/Subtractor. However, all *implementations* would
>>> extend TemporalPeriod, Adder and Subtractor.
>>>
>>> This is exactly the same as how LocalDate extends both Temporal and
>>> TemporalAdjuster, but Temporal and TemporalAdjuster are independent of
>>> one another. Different layers for different purposes.
>>>
>>>> Bottom line is why you need an extra Adder and Subtractor to stand
>>>> in the middle of Temporal = Temporal +/- TemporalDuration, when
>>>> we have a clear defintion of plus/minus, and we have two abstractions
>>>> clearly should/could know how to handle this well-defined operation.
>>>
>>> There are other possible classes that might wish to only implement
>>> adder/subtractor, and not be an entire period. The example in the
>>> javadoc is a method returning business/working days
>>>
>>>   date.plus(workingDays(6));
>>>
>>> The concept of "6 working days" is not a period, but it is a mechanism
>>> of addition. That is why Adder is different to the currently
>>> non-existing TemporalPeriod.
>>>
>>
>> date.plus(workingDays(6)) cat be perfectly implemented as
>> date.with(workingDaysAfter(6)), with the temporalAdjuster interface. The
>> name
>> might not be perfect, but I don't think it's a big concern.
>>
>> If you take a step back and look at these interfaces again,
>>
>> Temporal.plus(TemporalAdder) + TemporalAdder
>> Temporal.minus(TemporalSubtractor) + TemporalSubtractor
>> Temporal.with(TemporalAdjuster) + TemporalAdjuster
>>
>> are three exactly the same mechanisms, the only difference is the
>> "wording"
>> (even the wordings are similar), with the TemporalAdjuster as the most
>> "general
>> purpose" interface, by its name.
>>
>> What I'm questioning here is exactly the "different layers for different
>> purposes"
>> design on a simple abstraction. Do we really need two/three layers of
>> abstraction
>> here for "different purpose"? While to provide two more specific add &
>> minus
>> adjustment interfaces may bring some benefits, but it also adds the
>> complicity
>> to the interface, developers will have to deal with three different
>> abstractions
>> and different interfaces and have to figure out which one is "best" for
>> what,
>> while the reality is these three are exactly the same. We are talking
>> about a
>> "base" interface with 7 methods, and 3 of them are the "same thing"
>> (again,
>> they are just the "adjustment", one general, two specific).
>>
>> Let me try it again.
>>
>> time = time +/- duration   -> temporal = temporal +/-
>> temporalduratin(perioral?)
>>
>> temporal = temporal +/- tempralAddor/Subtractor(perioral)
>>
>> simply makes thing complicated with an extra layer, it'd be better leave
>> those
>> "addor/subtractor" to the adjuster.
>>
>> -Sherman
>>
>>
>>
>
> --
> Thanks, Roger
>
> Oracle Java Platform Group
>
> Green Oracle <http://www.oracle.com/commitment> Oracle is committed to
> developing practices and products that help protect the environment
>


More information about the threeten-dev mailing list