🔬57. Examining the Real role of Perl 6, part 1

🔬57. Examining the Real role of Raku, part 1

N. B. Perl 6 has been renamed to Raku. Click to read more.


During the last few days, we talked a lot about the Real role. Lets us then look at it more precisely. The code is located in the src/core/Real.pm file.

It contains the role itself and a few subroutines implementing different infixes. The Real role in its turn implements the Numeric role:

my role Real does Numeric {
    . . .
}

It is interesting that the class definition also needs some knowledge about the Complex class, that’s why there is a forward class declaration in the first line of the file:

my class Complex { ... }

The Real role defines many trigonometrical functions as methods, and as we already saw, they are using the Bridge method:

method sqrt() { self.Bridge.sqrt }
method rand() { self.Bridge.rand }
method sin() { self.Bridge.sin }
method asin() { self.Bridge.asin }
method cos() { self.Bridge.cos }
method acos() { self.Bridge.acos }
method tan() { self.Bridge.tan }
method atan() { self.Bridge.atan }

Another set of methods include generic methods that manipulate the value directly:

method abs() { self < 0 ?? -self !! self }
proto method round(|) {*}
multi method round(Real:D:) {
    (self + 1/2).floor; # Rat NYI here, so no .5
}
multi method round(Real:D: Real() $scale) {
    (self / $scale + 1/2).floor * $scale;
}
method truncate(Real:D:) {
    self == 0 ?? 0 !! self < 0 ?? self.ceiling !! self.floor
}

There’s a really interesting and useful variant of the round method, which allows you to align the number to the grid you need:

> 11.5.round(3)
12
> 10.1.round(3)
9

Another set of methods are used to convert a number to different data types:

method Rat(Real:D: Real $epsilon = 1.0e-6) { self.Bridge.Rat($epsilon) }
method Complex() { Complex.new(self.Num, 0e0) }
multi method Real(Real:D:) { self }
multi method Real(Real:U:) {
    self.Mu::Real; # issue a warning;
    self.new
}
method Bridge(Real:D:) { self.Num }
method Int(Real:D:) { self.Bridge.Int }
method Num(Real:D:) { self.Bridge.Num }
multi method Str(Real:D:) { self.Bridge.Str }

And here we have a problem in the matrix. The Bridge method is defined in such a way that it calls the Num method. In its turn, Num is calling Bridge, which calls Num.

Run one of the following lines of code, and Rakudo will hang:

Real.new.say;
Real.new.Str;

 

3 thoughts on “🔬57. Examining the Real role of Perl 6, part 1”

Leave a Reply

Your email address will not be published. Required fields are marked *

Retype the CAPTCHA code from the image
Change the CAPTCHA codeSpeak the CAPTCHA code