mat-hek
Hey,
there’s already an awesome Ratio library by @Qqwy, but it has several problems that, I believe, can’t be solved in the current state of the language:
Comparison
Ratio provides support for overloading standard operators to handle addition, multiplication, etc and also comparison. The problem is, when someone forgets to do use Ratio, the comparison won’t fail, but it will return invalid results… from time to time. That’s because comparing any Elixir terms is valid (btw this problem made me wonder if it should be). I experienced that a couple of times already and believe me, it’s extremely hard to debug.
Performance
Ratio operations are more resource-consuming than build-in numbers because we have to extract two integers from a struct each time. What’s more, we often have to find the GCD of these integers to avoid them growing indefinitely. Having that implemented natively surely would speed it up. However, maybe a bigger problem is that since Ratio overloads operators, it adds overhead in all the places when they’re used, even those not involving any rationals. Disclaimer: didn’t make any benchmarks yet, will do shortly. However, it’s rather a matter of the scale of the slowdown, not its existence.
Code reuse
Of course, whatever operates on rationals provided by Ratio has to be aware of them and rely on Ratio. That makes it impossible to reuse existing code that doesn’t have that dependency if they do any operations on numbers.
Supporting rationals can also be seen as a natural expansion of having big integers to floats - big integers prevent integer overflows, while rationals prevent error accumulation. And since rationals consist of integers, we get the benefits of both
It would be a game-changer for the ones who use rationals all over the place - as we do in Membrane ![]()
Trending in Discussions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 6- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
stefanchrobot
Got a little confused since Ratio 3.x no longer supports
use Ratio. In general, I don’t like operator overloading neither in this case, nor in my times with C++. I think this should be approached the same as comparingDateTimes.I think I’d like the addition of rationals into the VM if we had some sort of static typing. Knowing types at compile time allows the VM to squeeze out more performance. Supposedly it would be also visible to the developer that a particular “a + b” may be more time consuming then adding two integers.
mat-hek
Yup, we didn’t yet update to Ratio 3.0, because we use it in many places and we’d have to do it all at once, so it’s not just a matter of bumping the version
I generally agree that operator overloading is confusing when applied to things like dates, but when it comes to numbers, well, these operators were created for handling numbers. Not using operators makes things twice as less readable and adds the risk that someone accidentally uses
And the compiler still has to check for integers and floats upon each operation.
>instead ofRatio.gt. Regarding performance, I don’t think that the difference between integers and rationals would be that crucial to make it always visible for developers. They are not tensors after allLostKobrakai
I feel like the decision against operator overloading has been made a long time ago. Otherwise I expect us to have operator overloading for the
Decimallibrary, which has been around since around elixir 0.13. I’d be curious if an approach like Nx took withdefnwould be more fruitful, where the mathematical operations can be defined in a context separate to core elixir, but using the same syntax.al2o3cr
Even with operator overloading like
Numbersdoes, you still can’t just naively reuse code that was expectingnumber()values, since comparisons in guards aren’t overloaded:Qqwy
Nice to hear that you are using
Ratio!Unfortunately, Elixir’s hands are a bit tied in this regard: It is impossible to add support for a rational type in a way that would work as expected in guards without changing the Erlang VM itself.
Personally I would be very happy if support for decimals and rationals would be added as builtins to Erlang, because I also think that their usage is common enough to warrant this. However, I expect that such a change is highly unlikely because it would be a large undertaking to add support to them. (This besides the fact that not everyone agrees that they should be added in the first place.)
To respond to your separate points in detail:
Nxor a NIF.mat-hek
Thanks for the answer and the library
Concerning guards, maybe it would be possible to support them? Now it’s possible to extract values from the struct and I think it wouldn’t be necessary to reduce the fractions there
I’m afraid I agree. I’ll ask at the Erlang forum though, maybe they have some useful thoughts.
We don’t do any big math in Elixir, though small operations done frequently in different places contribute to the load. Since they’re small, I don’t expect delegating to the native code to help. But I’ll come back when I have benchmarks
Good to hear that Numbers are welcome