I wanted to suggest a direction that solves many of our current issues while also leaving the door open for more flexibility in the future.
Along with the Decimal proposal, we introduce one new type: Decimal.Amount. Key features:
- Is immutable
- Always holds a Decimal as the numeric type (not polymorphic)
- Supports a precision, designed such that implementations may store the precision in the bits of the Decimal
- i.e., precision is defined according to the Decimal128 cohorts. The distinction between withFractionDigits and withSignificantDigits is flattened when setting the precision on a Decimal.Amount.
(2.5m).withFractionalDigits(2).equals((2.5m).withSignificantDigits(3)) === true
- The unit or currency is optional and is held in its own slot
- This proposal is independent of how we express currency vs unit, whether we allow custom units, etc. We have separate issues to debate those concerns.
- Can be created via
from functions, a constructor, and/or convenience methods on Decimal
Some prototype functions would be:
Decimal.prototype.withUnit returns a Decimal.Amount with the specified unit (and no trailing zeros)
Decimal.prototype.withFractionalDigits returns a Decimal.Amount with a null unit and the specified number of digits after the decimal separator, which may involve adding trailing zeros
Decimal.prototype.withSignificantDigits behaves similarly but counts from the most significant digit
Decimal.Amount.prototype.withUnit and Decimal.Prototype.withFractionalDigits that allow for the precision and unit to be set in an immutable way
Decimal.Amount.prototype.equals which performs "full" equality (decimal numeric value, precision, and unit)
Problems this solves right now:
- Ergonomic, immutable data type for currency and measurement amounts
- Intl formatting and plural selection with units and trailing zeros, including MessageFormat
- Ability to represent and round-trip Full Decimal128 in JavaScript
What this direction allows us to do in the future:
- Have additional types that support other numeric types like numbers, BitInts, or Rationals
- Use as a basis for some type of unit conversion API
I wanted to suggest a direction that solves many of our current issues while also leaving the door open for more flexibility in the future.
Along with the Decimal proposal, we introduce one new type:
Decimal.Amount. Key features:(2.5m).withFractionalDigits(2).equals((2.5m).withSignificantDigits(3)) === truefromfunctions, a constructor, and/or convenience methods on DecimalSome prototype functions would be:
Decimal.prototype.withUnitreturns aDecimal.Amountwith the specified unit (and no trailing zeros)Decimal.prototype.withFractionalDigitsreturns aDecimal.Amountwith a null unit and the specified number of digits after the decimal separator, which may involve adding trailing zerosDecimal.prototype.withSignificantDigitsbehaves similarly but counts from the most significant digitDecimal.Amount.prototype.withUnitandDecimal.Prototype.withFractionalDigitsthat allow for the precision and unit to be set in an immutable wayDecimal.Amount.prototype.equalswhich performs "full" equality (decimal numeric value, precision, and unit)Problems this solves right now:
What this direction allows us to do in the future: