Friday, June 20, 2014

JSR 363 Unit of Measurement API - a FIrst Glance

JSR 363 Unit of Measurement API - a First Glance

During the last Hackergarten in Zurich I had the chance to look at the current GitHub Repository of JAR 363. Hereby I focused on the API only. This JSR is quite young, nevertheless there is already a code base available, which was originally forked from https://code.google.com/p/unitsofmeasure/ . My objective hereby was relatively simple: look at the main abstractions and get a gut feeling on it, so here it is:

Main Concepts

One main artifact is the Quantity interface, which is defined as follows:

public interface Quantity<Q extends Quantity<Q>> 
extends Measurement<Q, Number> {
  Quantity<?> divide(Quantity<?> that);
}
The according JavaDoc describes this interface withRepresents a quantitative properties or attributes of thing. Mass, time, distance, heat, and angular separation are among the familiar examples of quantitative properties.

As we have seen this interface hereby extends Measurement:

public interface Measurement<Q extends Quantity<Q>, V>
extends UnitSupplier<Q>,
        ValueSupplier<V>,
        ConversionOperator<Measurement<Q, V>, Unit<Q>> {

  Measurement<Q, V> add(Measurement<Q, V> that);
  Measurement<Q, V> substract(Measurement<Q, V> that);
  Measurement<?, V> multiply(Measurement<?, V> that); 
  Measurement<Q, V> multiply(V that); 
  Measurement<Q, V> divide(V that);
  Measurement<Q, V> inverse(); 
}
Whereas Supplier are common concepts also known from other APIs, Additionally ConversionOperator, Measurement and Unit:must be explained:
// equivalent to @FunctionalInterface
public interface ConversionOperator
<T, U> {
  T to(U unit);
}
public interface Unit<Q extends Quantity<Q>>
extends UnitTransformer<Q>, Nameable {
  String getSymbol(); 
  Dimension getDimension();
  Unit<Q> getSystemUnit(); 
  Map<? extends Unit<?>, Integer> getProductUnits();
  boolean isCompatible(Unit<?> that);
  <T extends Quantity<T>> Unit<T> asType(Class<T> type)
    throws ClassCastException;
  UnitConverter getConverterTo(Unit<Q> that)    
    throws UnconvertibleException;
  UnitConverter getConverterToAny(Unit<?> that)
    throws IncommensurableException, UnconvertibleException;
  Unit<Q> alternate(String symbol);
  Unit<Q> shift(double offset);
  Unit<Q> multiply(double factor);
  Unit<?> multiply(Unit<?> that);
  Unit<Q> divide(double divisor);
  Unit<?> divide(Unit<?> that);
  Unit<?> inverse(); Unit<?> root(int n); 
  Unit<?> pow(int n); 
}
 
But we still have not everything covered, there is also a Dimension, modelling the algorithmic relations between units:

public interface Dimension {
  Dimension multiply(Dimension that);
  Dimension divide(Dimension that);
  Dimension pow(int n);
  Dimension root(int n);
  Map<? extends Dimension, Integer> getProductDimensions();
}
Summarizing we have the following main artifacts involved:
  • A Quantity, which describes the flavor or type of measurement, e.g. Length, Weight or Volume.
  • A Unit, which defines a concrete unit of a specific measurement, e.g. Nanometer, Tons, Gallons..
  • A concrete Measurement, which can be seen as a concrete value measured of a Unit, e.g. 10 Meters, 3 tons or 4 Gallons. Measurements also provide simple arithmetics for adding, subtracting, division and multiplication with other measures of compatible units.
  • Dimension defines the numeric relationships between a set of related units.

My Feedback

Basically defining an API for all measures and units available is a tough thing. Also there was already a lot of work done, and I am looking forward how this JSR will evolve. Nevertheless my first impression is that the API mixes up a few concerns that I think should be separated:
  • I would expect to have such general and defining concepts like quantities and units being separated from more concrete aspects like measurements and dimensions. 
  • Another element that was present on the former measurement API was the SystemOfUnits concept. or some kind of accessor, which acts as an entry point. I think the API requires some entry point, e.g. in form of a singleton to make it complete. Basically a programmer should be able to program against the API without having to know any details on the implementations.
  • I would like the quantity to be modeled as the more general but basically independent concept and let Unit refer to its corresponding Quantity. This would resolve the circular dependency between Quantity and Unit.
  • Furthermore I would really ensure that the Quantity and Unit types are always evaluable at runtime (be aware of type erasure). 
  • For me it is also arguable if we really have enough benefits of Nameable. If the idea was to provide functional support for getName(), maybe it makes sense, but I would try to reduce the number of artifacts needed to the minimum. Just start small and if you really have to add something add it later. 
  • I do not like the idea of adding arithmetic operations on units, since I concern units as well as quantities as the metadata level, similar to currencies in the money world. I would expect them to be on measurements, which for me would be the same concept as monetary amount.
  • FInally I think the naming of system unit and product units is confusing. I would prefer more something like a main or leading unit, and derived units.(or somebody can tell me, that the semantics is different here, I am not sure, if I understood these concepts fully here...).
So I would come up with something like:
  public interface Quantity {
   String getName();
   boolean isCompatible(Unit<?> that); // needed here ?
  }
  public Unit<Q extends Quantity>{
   Class<Q> getQuantity();
   Unit<Q> getLeadingUnit();
   Collection<Unit<Q>> getDerivedUnits();
   boolean isCompatible(Unit<Q> that);
  }
The management of quantities and units, including the mappings of units, quantities I would handle as a separate concern, e.g. something similar like

 public final class Quantities {
   public static Collection<Quantity> getQuantities();
   public static Collection<String> getQuantityNames();
   public static Quantitiy getQuantity(String name);
   public static <Q extends Quantity> Q getQuantity(
                                            Class<Q> type);
   public static boolean isCompatible(Quantity quantity,
                                      Unit<?> that);
 }
 public final class Units{
   public static <Q extends Quantity> 
      Collection<Unit<Q>> getUnits(Quantity);
   public static <Q extends Quantity>
      Collection<Unit<Q>> getLeadingUnits(Q quantity);
   public static <Q extends Quantity> 
      Collection<Unit<Q>> getDerivedUnits(Unit<Q> unit);
   public static boolean isCompatible(Quantity quantity,
                                      Unit<?> that);
   public static <Q extends Quantity>
      boolean isDerived(Unit<Q> mainUnit, Unit<Q> derivedUnit);
   public static <Q extends Quantity>
      boolean isLeadingUnit(Unit<Q> unit);
   public static <Q extends Quantity>
      boolean isLeadingUnit(Unit<Q> unit);
   public static SystemOfUnits getSystemOfUnits(String name);
   public static SystemOfUnits getSystemOfUnits(Locale country);
   public static Collection<SystemOfUnits> getSystemOfUnits(
                                              Unit<?> unit);   public static Collection<SystemOfUnits> getSystemOfUnits(
                                              Unit<?> unit);
   public static Collection<String> getSystemOfUnitNames();
   public static SystemOfUnits getDefaultSystemOfUnits();
 }
public final class Dimensions{ ... }
Compared to what we have above this is much more simpler and comprehensive. Additionally there are also more advantages:
  • All these singleton can be backed up by spis. With this it should be easily possible to support partial implementations and overrides. E.g. when an additional unit type is defined, e.g. for measuring black materia in super-light speed mode (e.g. "WARPS") it would be possible to implement the parts required to support this additional unit.
  • Basically such a structure could allow also additional functionality such as contextual behaviour in a multi-tenancy/ee context.
Given an artifact SystemOfUnits it probably would be possible to support accessing units by their literal symbols, e.g.
 public interface SystemOfUnits{
   <Q extends Quantity> 
     Collection<Unit<Q>> getLeadingUnits(Quantity quantity);   <Q extends Quantity> Unit<Q> getUnit(String symbol);
   ...
 }
 
Now let us focus again on the next artifact: Measurement. Here
  • I would reduce the arithmetic methods to the absolute minimum. Instead of having operations on it like shift, alternate I would prefer an extension mechanism, similar to MonetaryQuery or MonetaryOperator in JSR 354.
  • I would heavily recommend to separate the concern of conversion. Basically this might also be doable based on the extension mechanism above, or it can be modeled as a separate API, but also provided by a separate accessor singleton.
  • Finally I would like to see, if we really need alternate values than decimal numbers to represent the values of measurements. Even if there are rare cases, where measures are not modeled as decimal numbers, I would see, if it is possible to map them nevertheless somehow to decimal numbers in a feasible way. If, I hope so, most of the measurements can be modeled in a unified way, I would tend to take this as the leading use case. For speciayou can still have an additional complex measurement model. This would IMO make the API simpler for the majority of use cases, which I think is better than trying to include also edge cases that pollute the API at the end (making more difficult to use).
So summarizing I would propose something like the following:

public interface Measurement<Q extends Quantity, 
                             U extends Unit<Q>>
extends UnitSupplier<U>, ValueSupplier<Number>{
  Measurement<Q, U> add(Measurement<Q, ?> that);
  Measurement<Q, U> subtract(Measurement<Q, ?> that);
  Measurement<Q, U> multiply(Measurement<Q, ?> that);
  Measurement<Q, U> multiply(double that);
  Measurement<Q, U> multiply(long that);
  Measurement<Q, U> multiply(Number that);
  Measurement<Q, U> divide(double that);
  Measurement<Q, U> divide(long that);
  Measurement<Q, U> divide(Number that);
  Measurement<Q, U> inverse();
  Measurement<Q, U> pow(int n);
  Measurement<Q, U> with(MeasurementOperator op);
  <T> T query(MeasurementQuery<T, Q> query);
}
, whereas
  public interface MeasurementOperator<Q extends Quantity, 
                                       U extends Unit<Q>>{
      <T extends Measurement<Q, U>> T apply(T unit);
  }
  public interface MeasurementQuery<Q extends Quantity,
                                       U extends Unit<Q>, R>{
      R query(U unit);
  }
Also I would definitively recommend handling formatting and conversion as separate concerns, but I will stop here for now. I think the JSR's Expert Group has enough input for discussion and I hope, they will catch up at least some of my concerns, so we get a simple, comprehensive, easy to use, but nevertheless powerful measurement API.
Of course, as always, any comments are welcome!

Monday, April 22, 2013

Overview JSR 354 (Money and Currency) Core API

What is JSR 354?

JSR 354 is the upcoming standard, how money and currencies should be modelled and handled in Java. You can find more details here:

Why this blog?

Within JSR 354 we had a lot of discussions. I wanted to show with some examples how this API feels. And finally, if someone has input or ideas, we want to be aware of, so we finally build the right API !


Dealing with Currencies

Basic Design Decisions

The JSR basically models many of the key artifacts using interfaces. Nevertheless we provide concrete value types implementing the interfaces which in concrete code are referenced. The interfaces typically are for interoperability:
  • CurrencyUnit and MonetaryAmout are modelled by interfaces for interoperability.
  • The classes MoneyCurrency and Money implement these interfaces.
  • In the case of MoneyCurrency, also an according MoneyCurrency.Builder is defined.
This will be shown in more detail within the following sections.

Interface javax.money.CurrencyUnit

Basically the interface directly models the same aspects as available on the existing java.util.Currency class, but adds some additional methods to support additional aspects not covered by java.util.Currency. Some of the considerations are:
  • not renaming existing methods of java.util.Currency enables maximal backward compatibility and makes it more easy to let implement java.util.Currency the new interface for interoperability. This would also allow existing code to remain as is, if none of the extended features are required.
  • the other methods added should be the minimum required and be basically easily implementable, If feasible, also undefined values should be possible as method results. 
  • In the area of currencies there are a couple of complexities that were not obvious at a first glance, but can not be neglected, if currency should model the reality at least to some extent. For example think on the following aspects:
    • currencies come and go during human history. Even during the last years there were quite important changes that requires that historic and current currencies can be distinguished.
    • ISO-4217 currency codes also have some imminent aspects to be considered:
      • ISO codes (the identifiers!) are not guaranteed over time, the can be reused after some defined time.
      • Rounding modes and fraction digits can change during time, even when the currency is still the same.
      • Historic currencies are not mapped by ISO at all.
      • ISO also maps things that are not effectively currencies, like precious metals (e.g. AUG), no currency (XXX) or testing codes.
      • ISO also is ambiguous  e.g. CFA is a code that basically is backed up by two different bank notes.
  • the biggest change is that we introduced an additional namespace on top of the currency code, because:
    • namespaces can be used to separate concerns. This makes sense since ISO currencies are real currencies, whereas Social or Video Game Currencies are completely virtual. BitCoin even is more special, since it started as a virtual currency but lately is accepted more and more as real currency.
    • namespaces also allow to manage legacy currency schemes as they are in use by all financial organizations that must deal with money in a time range and scope that is longer than 10 years.
    • One might argue, that we could simply extend the existing currency code. But this also has some severe drawbacks:
      • the existing currency code of the JDK class can not be adapted correspondingly  since this would break behavioral compatibility. But if the code can not be extended, we would have currencies with a namespace prefix (all non ISO), and ones without (ISO, as before).
      • Additionally the JSR should definitely not impose anything on how currency codes will be defined in the future. But when extending the existing currency code with some optional namespace, an according separation criteria must be defined. Obviously this could easily clash with future namespace or code identifiers.
So summarizing a currency must implement the following interface:

public interface public CurrencyUnit{
  public String getNamespace(); // new
  public String getCurrencyCode();
  public int getNumericCode();
  public int getDefaultFractionDigits();
  public boolean isVirtual(); // new
  public boolean isLegalTender(); // new
  public Long getValidFrom(); // new
  public Long getValidUntil(); // new
}


There are a couple of remarks:
  • the numeric code, if not defined, should be -1.
  • the timestamps are modelled as Long due to the following reasons:
    • the JSR wants to be backward compatible with SE 7 (which will also cover SE6).
    • SE 8 is not yet final.
    • Long can be null, which means not defined. This is also the correct value for current currency instances.
    • UTC timestamps are commonly understood and well supported by all kind of time and date frameworks. They can easily converted to any other kind of objects required. Note: there is quite discussion ongoing, if the new JSR 310 APIs should be used here. We require definitively here better information, if we can go for the new date and time types, without preventing usage of the new API for years.

Class javax.money.MoneyCurrency

This class is the implementation of CurrencyUnit, also including an according Builder and an internal cache for reusing instances created. It is also where, by default, in the new API ISO currencies can be accessed:

MoneyCurrency currency = MoneyCurrency.of("USD");

For ISO currencies this will work out of the box, since the ISO currencies are implicitly backed up by java.util.Currency. Also the call above does implicitly add 'ISO-4217' as namespace, so basically the call below is aequivalent:

MoneyCurrency currency = MoneyCurrency.of("ISO-4217", "USD");

Defining alternate MoneyCurrency instances and namespaces can be done using the MoneyCurrency.Builder:


MoneyCurrency.Builder builder = new MoneyCurrency.Builder();
builder.setNamespace("myNamespace");
builder.setCurrencyCode("myCode");
builder.setDefaultFractionDigits(4);
builder.setLegalTender(false);
builder.setVirtual(true);
builder.setAttribute("test-only", true);
MoneyCurrency unit = builder.build();
// however MoneyCurrency.of("myNamespace", "myCode"); 
// still returns null!
builder.build(true);
// no it is registered
unit = MoneyCurrency.of("myNamespace", "myCode");

Extended API: javax.money.ext.MonetaryCurrencies

This singleton class allow to access currencies in a more service like fashion as required for more advanced use cases, such as accessing historic currencies or mapping of currencies between or within namespaces. Also it is possible to access all currencies within a namespace. Extended functionality is not part of the JSR's platform part and therefore is designed as standalone module, usable in multiple usage contexts (SE, EE etc):


public final class MonetaryCurrencies {

public static boolean isNamespaceDefined(String namespace){..}
public static Collection<String> getNamespaces(){..}
public static CurrencyUnit get(String namespace,
                                 String code)
{..}
public static Collection<CurrencyUnit> getAll(
                                           String namespace){..}
public static boolean isDefined(String code){..}
public static boolean isDefined(String namespace, 
                                  String code){..}
public static Collection<CurrencyUnit> getAll(String namespace,
                                                String code)
{..}
public static Collection<CurrencyUnit> getAll(String code){..}

  // historic access
public static boolean isNamespaceDefined(String namespace
                                           Long timestamp){..}
public static Collection<String> getNamespaces(
                                           Long timestamp){..}
public static CurrencyUnit get(String namespace, String code,
                                 Long timestamp)
{..}
public static CurrencyUnit get(String code, Long timestamp){..}
public static Collection<CurrencyUnit> getAll(String namespace,
                                              Long timestamp)
{..}
public static boolean isDefined(String namespace, String code,
                                  Long timestamp)
{..}
public static boolean isDefined(String code, 
                                  Long timestamp){..}
public static Collection<CurrencyUnit> getAll(Locale locale, 
                                             Long timestamp){..}
  // mapping of currrencies
  public static CurrencyUnit map(CurrencyUnit unit, 
                                 String targetNamespace);
public static List<CurrencyUnit> mapAll(String targetNamespace, 
                                          CurrencyUnit... units);
public static CurrencyUnit map(CurrencyUnit unit, 
                                 String targetNamespace, 
                                 Long timestamp);
public static List CurrencyUnit> mapAll(String targetNamespace,  
                                          Long timestamp, 
                                          CurrencyUnit... units);
}

The singleton's implementation itself can be determined by registering an instance of MonetaryCurrencies.MonetaryCurrenciesSpi using java.util.ServiceLoader.

Monetary Amounts

Some Basic Design Decisions

Monetary amounts basically follow the same design as CurrencyUnit::
  • MonetaryAmout is modelled by interface for interoperability.
  • Aims look and feel from java.math.BigDecimal 
  • Money implements the MonetaryAmout interface, using java.math.BigDecimal for numeric representation.

Interface javax.money.MonetaryAmount

Basically the interface models similar aspects as java.math.BigDecimal, but targeting monetary amounts:

public interface MonetaryAmount{
  CurrencyUnit getCurrency()
  MonetaryAmount add(MonetaryAmount);
  MonetaryAmount subtract(MonetaryAmount);
  
MonetaryAmount multiply(MonetaryAmount);    
  MonetaryAmount multiply(Number);
  MonetaryAmount divide(MonetaryAmount);
  MonetaryAmount divide(Number);
  MonetaryAmount remainder(MonetaryAmount);
  MonetaryAmount remainder(Number);
  MonetaryAmount scaleByPowerOfTen(int);  
  MonetaryAmount abs();    
  MonetaryAmount negate();
  
  MonetaryAmount pow(int); 
  MonetaryAmount ulp(); // unit in the last place  
  boolean isGreater(MonetaryAmount); 
  boolean isGreaterOrEquals(MonetaryAmount);  
  boolean isLess(MonetaryAmount), 
  boolean isLessOrEquals(MonetaryAmount);
  ...
  boolean isEqualTo(MonetaryAmount);  
  boolean isNotEqualTo(MonetaryAmount);  
  boolean isNegative();  
  boolean isPositive();  
  boolean isZero();   
  byte byteValue();  
  short shortValue();  
  short shortValueExact();  
  int intValue();  
  int intValueExact();
  long longValue();  
  long longValueExact();  
  float floatValue();  
  double doubleValue();  
  <T> T asType(Class<T>);
  Class<?> getNumberType();  
  int getPrecision();  
  int getScale();
  int signum();  
  MonetaryAmount from(Number);
  MonetaryAmount from(CurrencyUnit, Number);
  MonetaryAmount with(MonetaryOperator);
}


Hereby the last method with, allows to combine amount instances with arbitrary external manipulation logic, implemented as MonetaryOperator. This is explained in more detail later.


Class javax.money.Money

This class is the implementation of MonetaryAmount, using java.math.BigDecimal for numeric representation. The method signature look similar to the interface, but return the according value object, e.g.:

public final class Money implements MonetaryAmount,...{
   [...]
   public Money add(MonetaryAmount amount);
   [...]
}

Creation of Money instance hereby is done using the of() factory methods, e.g.

Money amount1 = Money.of("USD", 12); // int
Money amount2 = Money.of("USD", 12.5); // float
Money amount3 = Money.of("USD", (byte)12); // int
Money amount4 = Money.of("USD", BigDecimal.valueOf(100.15d)); 
                                                   // BigDecimal

Hereby the above calls also include some convenience, since the ISO namespace is used implicitly. The first call basically is equivalent to:

Money amount1 = Money.of(MoneyCurrency.of("USD"), 12);

or to the full fledged version:

Money amount1 = 
    Money.of(
      MoneyCurrency.of(MoneyCurrency.ISO_NAMESPACE, "USD"), 12); 


Interface javax.money.MonetaryOperator

As seen before an instance of MonetaryAmount also has a with method taking a MonetaryOperator as a parameter. The type MonetaryOperator is modelled similarly to the UnaryOperator functional interface from Java 8, extending the corresponding base type MonetaryFunction:


//@FunctionalInterface
public interface MonetaryFunction<T, R> {
public R apply(T value);
}


//@FunctionalInterface
public interface MonetaryOperator 
extends MonetaryFunction<MonetaryAmount,MonetaryAmount> {

}

This looks not very spectacular, but when combined with functionalities like currency exchange, rounding and more complex operations the concepts renders to a powerful weapon against complexity:

CurrencyConversion convertToYen = ...;
Money m = Money.of("USD", 12345.25)
              .multiply(10.34563)
              .with(MajorPart.of())
              .with(convertToYen)
              .divide(7)
              .with(MoneyRounding.of());

This operational chain creates an amount in USD, multiplies it by 10.34563, takes the major part only,  converts it to YEN, divides by 7 and finally rounds according the default rounding rules defined for YEN. 
When dealing with monetary functions there are also some built-in functions provided by default (if you have some hints or ideas, what else would be useful please drop me a mail):

Collection<MonetaryAmount> amounts = ...;
Map<CurrencyUnit, MonetaryAmount> sepResult = 
                               SeparateCurrencies.apply(amounts);
// Get amounts > 100 in USD
Collection<MonetaryAmount> allUSDAmounts =  
                          sepResult.get(MoneyCurrency.of("USD"));
Collection<MonetaryAmount> bigAmounts = new  
  AmountFilter(allUSDAmounts ).apply(
    new MonetaryFunction<MonetaryAmount, Boolean>(){
     public Boolean apply(MonetaryAmount amount){
        return amount.intValue()>100;
     }
  });

Finally also rounding can be modelled similar as MonetaryOperator, thus being only a special case of operation not adding basic additional complexity on this API level. Hereby the class MoneyRounding provides access to rounding algorithms:

public final class MoneyRounding implements MonetaryOperator{
   public MonetaryAmount apply(MonetaryAmount amount){
     [.. ]
   }
}


Different Numeric Representations

Different implementations of MonetaryAmount can model the numeric representation using different numeric types. This allows to cover the varieties of use cases identified. Nevertheless it should be possible to mix up different implementations by applying some relatively simple rules:
  • The numeric representation is not part of the MonetaryAmount interface.
  • The target instance's class of an operation performed, determines the resulting instance type of an operation (which should be the same as the target type itself).
  • If an arithmetic operation exceeds the capabilities of the target instance, an ArithmeticException should be thrown.
  • Precision/Scale information should never be lost.
  • Automatic rounding is only valid, when required by the internal representation. By default no rounding should ever happen, despite internal rounding, implied by the numeric representation type.

As an example, refer to the example below:

Money mm = Money.of("USD", "1222222222222222222323232.23232323");
IntegralMoney im = IntegralMoney.of("USD", 2345);
mm.divide(im);  // should work
im.divide(mm);  // throws ArithmeticException

So hopefully, this creates some appetite for more. So go to our project page on java.net or check out our GitHub repository and try things out, and of course, if you have any questions, or even better feedback or improvement, feel free to contact me