proposal-decimal icon indicating copy to clipboard operation
proposal-decimal copied to clipboard

TypeError on mixed operands

Open littledan opened this issue 4 years ago • 13 comments

This proposal follows BigInt in TypeErrors on mixed operands, e.g., BigInt + BigDecimal -> TypeError. Although it is possible to losslessly convert any Number or BigInt to a BigDecimal, the strictness here is intended to be part of a consistent mental model that developers should keep track of their numerical types and ensure uniformity. (The exception is comparison operators, which allow mixed types.) If people have concerns about this model, let's talk them through in this thread.

littledan avatar Nov 13 '19 14:11 littledan

It would be really confusing if mixed Number and BigDecimal expression will not throw. This can lead to hard to debug errors. Mixed BigInt and BigDecimal expressions make more sense, though it probably will be safer to cast to BigDecimal explicitly.

chicoxyzzy avatar Nov 13 '19 20:11 chicoxyzzy

What makes the errors hard to debug?

littledan avatar Nov 13 '19 22:11 littledan

Sorry, "mistake" is a better word. I mean that if developer will mix Number and BigDecimal by mistake, it will be hard to find out if and why the number of decimal places was changed. In financial web apps it's a very common group of bugs (MPI, pips and a lot of other things may have different number of decimal places and that number is very important and shouldn't be changed accidentally)

chicoxyzzy avatar Nov 14 '19 03:11 chicoxyzzy

Note, if you have a bunch of BigDecimal values with different numbers of decimal places, it would be fine to mix them in calculations--they are all the same type.

littledan avatar Nov 14 '19 09:11 littledan

I guess @chicoxyzzy mean mixed Number (binary 64-bits floats) with BigDecimal (decimal floats with arbitrary precision). This definitely shouldn't be possible implicitly.

MaxGraey avatar Nov 14 '19 10:11 MaxGraey

Would it solve this problem if you could use the BigDecimal constructor to explicitly cast the Number to a BigDecimal before performing the operation?

littledan avatar Nov 14 '19 12:11 littledan

If it’ll be possible to set a number of decimal places via constructor parameter or at least round by some BigDecimal instance method after the cast, then yes

chicoxyzzy avatar Nov 14 '19 12:11 chicoxyzzy

Exactly. The same way as we do this for mixing BigInt with Number nowadays.

MaxGraey avatar Nov 14 '19 12:11 MaxGraey

I imagine the constructor will give the exact value (to keep things simple), and then you could use a round method on the result. If you could document requirements for a round method in #14 (or should we break it out into a separate issue?), that would be great

littledan avatar Nov 14 '19 12:11 littledan

I'm not sure I'm happy with the combination of * always returning exact results and BigDecimal having arbitrary precision. It's too easy for the precision to run away from you if you're not careful, and I suspect most users won't be careful. You can do simple things like squaring 1.0000001m 30 times and running out of memory despite the result being fairly small. This is not an issue with IEEE decimal because it does round.

waldemarhorwat avatar Nov 23 '19 01:11 waldemarhorwat

@waldemarhorwat Do you think we should limit to IEEE decimal size, as suggested in #8 ? Maybe that would be a helpful place to follow up.

littledan avatar Nov 23 '19 02:11 littledan

It's a fairly broad question. I think that IEEE decimal (without distinguishing cohorts) has more predictable behavior and applicability — you can do math, trigonometric functions, etc., and they behave just as in IEEE double without worries about falling off a cliff because precision is exploding somewhere inside your algorithm. Unlimited precision decimal is much harder to use safely. Similarly, I'd much rather get an infinity than an exception if I try to compute the tangent of 90°.

waldemarhorwat avatar Nov 23 '19 02:11 waldemarhorwat

@waldemarhorwat Perhaps one way to allay the concern about trigonometric functions and other elementary functions would be to indicate that those operations need to have a precision attached to them? In other words, only the "easy" stuff like addition, subtraction, multiplication, and division (and, possibly, a couple more operations) work in an unlimited way (though one may optionally specify a precision there, too), but logarithms, sine, cosine, etc., require a precision.

jessealama avatar Nov 10 '22 14:11 jessealama