Newer versions of Rakudo allow you to tune this behaviour dynamically through the $*RAT-OVERFLOW dynamic variable (which defaults to Num for the described behaviour).
I disagree that graceful degradation from Rat to Num (ie double) when Real numbers over- or under-flow is a misfeature.
We could (and have) debate whether FatRat should be the default, but imo the right expectation for an untyped language should be that very large or small numbers are represented with a floating point representation that (i) uses the FPU that's right there and (ii) sacrifices precision in the mantissa for accuracy.
Since Raku has (gradual) types, you can easily specify what you want and throw an error.
AFAIU, it's not only very large or small numbers that are affected, but any rational number with a denominator larger than 2*64. For most applications it's completely unpredictable when the switch to Num happens.
Nearly, the docs say "To prevent the numerator and denominator from becoming pathologically large, the denominator is limited to 64 bit storage." (https://docs.raku.org/type/Rat)
Please bear in mind that in raku (like perl and other untyped scripting languages) it is normal to say:
my $x = 1;
say 1 + $x; #2
say 'a' ~ $x; #'a1'
My point is that when the type is automatically inferred/coerced like this, is is very natural that small/whole Numerics are Int, that medium/fractional/decimal Numerics are Rat and that large/exponential Numerics are Num (ie double). And that you can freely perform maths operations mixing the various Numeric types at will.
my $y = 1;
say 1 + $y; #2 Int
say 1.1 + $y; #2.1 Rat
say 1e27 + $y; #1e27 Num
And, in raku, if you want to control the type, then just use the type system like this.
my FatRat $r;
I also think from a 2nd order point of view that a denominator of 2*64 means you are dealing with quite a small number 5e-20 ish), although admittedly that is a matter of taste and machine performance. It makes most sense in my view to go with Rat (which is stored as an Int (uint64) for the numerator and an Int for the numerator.
That way (i) you get to use all those transistors that you bought for your FPU and (ii) you do not get a surprise as Rat operations perform slowly without warning.
---
And yes - @lizmat has pointed out the various pragmas to let you control the behaviour you want if you disagree.
Rational numbers do not overflow or underflow. The only reason for having a type with this degenerate behaviour is to screw over the unsuspecting user who expects the language to protect them because they saw it using rational number representations in some contexts.
Ha, it's like best-effort typing. The interpreter gives you a precise rational if it can, and it throws you a float if it can't. I suppose that, in a language as dynamic as Raku, the idea is that you should never need to keep track of types anyhow, but this might be nicer if this value ends up being your user-facing output, depending on the application.
There is no reason why it could not continue to use the exact representation and operations if it wished (and that's what FatRat does). It's just an ill-conceived concession to performance.
and yet, raku is the first serious attempt to unify Int-Rat-Num-Complex types into a cooperative Numeric space --- which I think is a good design given its untyped default approach
ok - but raku has a reinvention of Numeric that is less esoteric, and more practical ... what you mention is that an Int isa Rat isa Real isa Complex isa Numeric ... and thus in Scheme or Lisp, then the Number Tower class model is one of subsetting features as you go down to an Int which is counter to the reality in your computer than an Int is just a 64-bit register
in raku, for example, an Int is not an isa (grand)child of Complex (and so doesn't carry that overload) ... but yes it is a Real
so raku separates Real from Complex and Int from Rat and you can go eg. my $x = 1 ~~ Rat; #False and this is aligned with literals - 1 vs 1.1