8 ms·
In most other languages, aren’t rationals “deliberately the non default so that you the coder need to know that ais what you want to trade precision vs performa
by martinky24 2y ago
In most other languages, aren’t rationals “deliberately the non default so that you the coder need to know that ais what you want to trade precision vs performanc”?
My point being, your point doesn't actually make Raku sound like they made a good design decision, it’s just different for the sake of being different when put that way.
- amelius 2y agoI'd say the best choice is correctness over performance. So bignums win.
- AlotOfReading 2y agoBignum rationals aren't "more correct" and expressive than things like algebraic or symbolic representations, you're just picking a different set of tradeoffs than floats. That's fine, different numerical systems are fundamentally about making different sets of tradeoffs. We should just be clear what we're picking. Personally I'd argue that for most people, writing most applications, IEEE floats are a fantastic tradeoff between performance, memory, error, and stability. That's why they've stuck around as the dominant numerical representation for decades. For most of the situations where they suffer (e.g. rounding transcendental results, operands with widely varying orders of magnitude, results very near 0) don't have general solutions in other systems, so the middle ground between "safe for a naive programmer" and "requires expertise in numerical analysis" becomes very small overall.
- amelius 2y agoBignums are arbitrarily more accurate than IEEE floats which often are implemented only in single or double precision. IEEE floats are fine for most cases, but sometimes you want to tune up the accuracy and with IEEE floats that's typically not possible, and it's like you're in a dead end street. Therefore I still think bignums are a better default choice for most programming languages.
- AlotOfReading 2y ago> Bignums are arbitrarily more accurate than IEEE floats... Yes, and that's true of all arbitrary-sized types vs fixed-size types. There's a lot of costs that come with that choice, like inherent allocations, losing constant time operations, lack of hardware support, etc. You can do exactly the same thing with floating point, for example GNU MPFR and ARPREC. Doing so is broadly faster than rational representations for a lot of common types of computations, and much less prone to size explosions. Still has the issue of incorrectly terminated representations at a given size or precision, but they can also represent things like irrationals far more efficiently. That said, I've very rarely run into situations that couldn't be made to fit in a double or quad where rationals would be better. These types can represent the distances between planets down to the nanometer or micrometer scale without losing precision. If you're dealing with atomic manufacturing on an astronomical scale, it might be worth investing in a new type, but anything short of that is very likely to be a problem requiring domain expertise to evaluate. Floats are perfectly fine as a default. The other advantage of floats is that they allow/require you to think about precision and rounding because they're a core part of the representation. Some people don't like that, but going to rational bignums doesn't free you of that burden.
- amelius 2y agoYou don't need to work with atomic particles to get into problems with floating point accuracy. A badly conditioned matrix can be enough. Yes, you can use floats to build floats with more precision, but that's not the point. The point is to have correctness at your fingertips, rather than a datatype that comes with lots of caveats. I agree with you that people who work with numerical algorithms might want to use floats, but programming languages with a general audience probably should have an arbitrary-precision datatype as a default.
- AlotOfReading 2y agoMy point is that rationals aren't correct in the way you're describing. For example, try rotating that rational ill-conditioned matrix. You'll probably have to pick a precision to approximate the result and at that point you would have been better off with arbitrary precision floating point, algebraic or symbolic representations instead. None of these representations are wrong, they're simply tradeoffs for different usages. That's why IEEE floats are such a good default. They balance those tradeoffs extremely well, with fixed semantics and near-universal hardware support.
- tliltocatl 2y agoIt's not best choice, it's a choice that is appropriate in some (quite restricted) setting where you don't really care if the program runs out of memory or pauses for a minute on an unexpected input. In many other settings having a inexact (or even obviously incorrect) result is better then stalling the whole system.
- dfox 2y agoThe same design decision is in most languages that implement Common Lisp/Scheme-style numeric tower (eg. have rationals as core type). You do basic arithmetic on rationals or integers, you get rational or integer. You do transcendental function on pretty much anything, you get float. Also usually you also get stuff like complex rationals, which makes the rules somewhat convoluted, but that is no that relevant for this discussion.
- librasteve 2y agoApologies to the Raku folks if my description made it sound like a bad design decision. It is true that defaulting to Rat approach is distinctive (although not unique). Let me try again. My case is that Num (ie P754 floating point) is not well aligned to decimals that humans use in most everyday circumstances. Thus the famous (0.1+0.2==0.3) example which works with Rat and breaks with Num. The only benefit of a Num over Rat is performance and the disbenefit is that Num has limited precision and range. Unless you are talking about irrational numbers, when you have to have imprecision anyway. Therefore having Rat as the default means that Num is an option for the coder to increase execution speed, but only if they accept the implications for precision and range.