mat-hek
How about support for rational numbers in Elixir/BEAM?
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
Chat & Discussions>Discussions
Latest on Elixir Forum
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #performance
- #security










Most Liked
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.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.
Last Post!
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