prePEP: Decimal data type

John Roth newsgroups at jhrothjr.com
Sat Nov 1 14:10:15 EST 2003


"Alex Martelli" <aleax at aleax.it> wrote in message
news:MTSob.78975$e5.2933818 at news1.tin.it...

Alex, I think we've lost context, so I'm going to state,
up front, the context I see for the discussion. More
detail is at the back of this post.

I'm quite happy with the notion of all the messy accounting
and regulatory details being handled by a money type that
is designed to keep the accountants and regulators happy,
at the expense of programming simplicity. I spent quite a
few years doing that type of programming; I think I know
a bit about it.

Given that, I don't see any real advantage in having a separate
decimal type that duplicates the functionality needed for
money. The decimal type should be directed more toward the
intuitive, ease of use angle that Python is famous for.

I also don't see a case for a floating decimal type. If you
have the money type, then there isn't a whole lot that
you can do with floating decimal that you can't do with
regualar binary floats.

I can see some justification for a simple, straightforward,
fixed decimal type that makes reasonable assumptions in
corner cases, while still allowing the programmer a good
deal of control if she wants to exercise it.

That's the context of my remarks.


> John Roth wrote:



>    ...
> > Alex, where did I suggest that I wanted a rational data type? Please
> > tell me one place in my response where I said that. Please?
>
> You fought against limited precision, and said NOTHING against
> the requirement that the new type support division (point 12 in
> the specs).  This implies the implementation must use rationals
> (by any other name).

The alternative explanation is that I simply hadn't thought that
part of the issue through when I made the response. It's a
much simpler explanation, isn't it?

> Of course, if you now change your responses
> (and in particular change the lack of objection to / into a
> request that it be abrogated, as you do below) then (at least
> some of) the objections to your proposals change (the one against
> the crazy idea of having number+string implicitly convert the
> string "just as if" it had been explicitly converted stands, of
> course -- "if you want Perl, you know where to find it").

That's discussable, of course.

>
> > The only place where you can get into trouble is with division
> > and equivalent operations. That's the one place where you actually
>
> If one accepts that an arbitrary float is somehow (perhaps a bit
> arbitrarily) coerced into a decimal-fraction before operating
> (e.g. by multiplication) -- or forbids such mixed-type operations,
> against your expressed wishes -- yes.

If we're going to have to specify additional information
when we explicitly construct a decimal from a float, as
one variety of proposal suggests, then I see no difficulty
with prohibiting implicit conversions. In fact, I seem to
remember a note that implicit type coercion may vanish
sometime in the misty future (3.0 time frame.)

> The resulting decimal type, however, may not be highly usable
> for some kinds of monetary computations.

I think that was the justification for a separate money
data type.

> It's an unfortunate
> but undisputable fact of life that laws and regulations exist
> that specify some monetary computations in detailed ways that
> differ from each other.

Understood, in detail.

[...]

> Note that the operation that gives trouble here is not a
> division -- it's a multiplication.  The problem is with carrying
> around "unbounded precision" _when laws and regulations
> tell you otherwise_.  Forcing the user to remember to round
> again (by calling the appropriate rounding function) after every
> multiplication is dangerous, because subtly wrong but plausible
> results will come if the user forgets one of those calls.  The
> sensible approach would seem to be to imbue every Decimal instance
> with the rounding rules that instance is supposed to follow (in
> most programs the rules will be the same for every instance, but
> _allowing_, albeit with some trouble if need be, particularly
> complicated programs to carry on computations with several
> different sets of rules, would be good -- as long as no accidental
> and incorrect "mix" of them can happen by mistake).

That is, in fact, the way money needs to be handled. However,
I was under the impression that the separate money type was
still in play, for the reasons stated in the pre-pep.

[...]

> I have no issue with that, but I definitely think that, to actually
> be USEFUL in practice, Decimal instances should be able to carry
> around their own precision and rounding-rules.  Then you can use
> explicit div and mul (functions or methods) when you want to
> explicitly specify something different -- probably add and sub too,
> when you want to produce a Decimal that may have different rules
> as a result, or explicitly "mix" (operate betweem) instances that
> might have different and possibly conflicting rules.  But you can
> also use the ordinary operators in ordinary circumstances when you
> are operating between instances that have the same rules.  In
> this case, I think that add(a,b) , mul(a,b) , etc, without specific
> parameters for precision, rounding, nor other rules, might be
> totally equivalent to a+b , a*b , etc.  It costs nothing and it
> might endear us a little bit to the "migrating from Cobol" crowd
> (OK, not as much as "add a to b" would, but we can't have that:-).

The base problem with this is that COBOL doesn't do it that
way, and COBOL was deliberately designed to do things the
way the accounting profession wanted, or at least make it
possible to do them without the language getting in your way.

Part of the reason why COBOL has the separate operators
is that the *destination* of the operation specifies how the
result is computed. You can't do that with intermediate
results if you use expression notation.

The only way you can do anything similar in a language like
Python is to avoid the operators and use functions or methods
that allow you to explicitly specify the exact form of the result,
together with the rounding rules, if any, used to get there.

Another thing that hasn't been brought up, though: COBOL
also allows you to specify a maximum for a value: you can't
exceed it without causing an overflow exception (which can
be caught with an ON OVERFLOW clause, of course.)

John Roth


>
>
> Alex
>






More information about the Python-list mailing list