On 11 March 2014 20:51, Oscar Benjamin email@example.com wrote:
On 11 March 2014 07:24, Antoine Pitrou firstname.lastname@example.org wrote:
On Tue, 11 Mar 2014 09:02:31 +1000 Nick Coghlan email@example.com wrote: >
My take is that we're down to two main options:
Stefan: use the existing decimal type, change default context to Decimal64, round all decimal literals to current context
Oscar: new fixed width decimal64 builtin type, always uses Decimal64 context (allowing constant folding), interoperates with variable context decimal.Decimal values (producing a decimal.Decimal result)
I lean towards Oscar's proposal, as it removes the hidden context dependent behaviour and makes the builtin decimals true constant values.
Yuck. Is this some kind of joke? We've gone through the trouble of unifying long and int in Python 3 and now people are proposing two different Decimal types, one with fixed precision and one with arbitrary precision?
I'm completely -1 on this.
I understand your objection Antoine. There is a big difference though between integer and non-integer types in this respect though. For integers is is not hard to define a single integer type that satisfies the vast majority of use-cases (focusing purely on semantics rather than detailed implementation aspects and performance). The only contentious issue is how to handle inexact division. int and long were not really "unified" in Python 3. The long type replaced the int type as it has those universal integer semantics that are really wanted.
When it comes to non-integer types there's just no single good way of doing it. So just in the stdlib we already have float, Fraction and Decimal. The additional libraries that I use have many more numeric types than that. The idea here is that for most users decimal128 just is the decimal type. The decimal.Decimal type is IMO overly complex and should really be for niche use-cases like other non-stdlib multi-precision numeric types.
Right. I believe the appropriate comparison here should be with builtin floats (which are essentially 64 bit C doubles, with all the limitations that implies), rather than with the historical int/long situation.
The reason I see Oscar's proposal as arguably different from the int/long case is that we wouldn't be trying to pretend that builtin decimals are the same type as the existing variable context decimals. While they would implicitly interoperate under addition, etc (as numbers generally do, with variable precision decimals being treated as the resulting type for mixed arithmetic), there would be no way to implicitly turn two fixed precision decimals into variable precision ones.
That is, don't think "int vs long", think "float16 vs float32 vs float64 vs float128", with Oscar's proposal being that picking just one decimal floating point precision as the floating point precision, just as Python already does for binary floating point, makes more sense than trying to provide variable precision support in a builtin type.
That approach buys us a couple of key benefits:
The guidance to new users would then be don't use the decimal module, use decimal literals instead. If you need more configurable behaviour, then reach for the decimal module. However, the explicit methods on decimal context objects should probably still be updated to accept both fixed and variable precision decimals under this model.
-- Nick Coghlan | firstname.lastname@example.org | Brisbane, Australia