Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type coercion in Perl6

Tags:

coercion

raku

If I have an an object of type Str, and I want to coerce it into an Int, it is my understanding that I can do this by calling the method Int on the Str-object, like so:

"100".Int

I (think I) know I can do this because the Str-type documentation at https://docs.perl6.org/type/Str lists the Int-method. Now, to coerce this newly created Int into an object of type Complex, I tried the following coercion:

"100".Int.Complex

which works :-) So no problem. Except that I can't figure out why it works. The Int-type documentation at https://docs.perl6.org/type/Int does not list a method Complex. I did find a method with this name for the class ComplexStr, but I have no clue if this is somehow relevant to my Int, or not.

So the question is: how does the above coercion work? Where does the method Complex come from? And how could I have known I can actually call it on an Int-object before trying?

like image 952
ozzy Avatar asked Jun 17 '18 20:06

ozzy


2 Answers

This is merely a case of incomplete documentation.

You can always find out what methods an object supports by calling .^methods on it:

perl6 -e '$_>>.name.join(", ").say for 123.^methods.sort(*.name).rotor(5 => 0, :partial)'
ACCEPTS, Bool, Bridge, Capture, Complex
DUMP, FatRat, Int, Num, Numeric
Range, Rat, Real, Str, WHICH
abs, acos, acosec, acosech, acosh
acotan, acotanh, asec, asech, asin
asinh, atan, atan2, atanh, base
ceiling, chr, cis, conj, cos
cosec, cosech, cosh, cotan, cotanh
exp, expmod, floor, gist, is-prime
isNaN, log, log10, lsb, msb
narrow, new, perl, polymod, pred
rand, roots, round, sec, sech
sign, sin, sinh, sqrt, succ

In the mean time, I pushed a commit to the docs repo that adds the missing method. The website is already regenerated with the change: https://docs.perl6.org/type/Int#(Real)_method_Complex

like image 151
timotimo Avatar answered Nov 11 '22 20:11

timotimo


(This is more an extended comment than an answer. I know only Perl 5.)

From https://docs.perl6.org/type/Cool:

Methods in Cool coerce the invocant to a more specific type, and then call the same method on that type. For example both Int and Str inherit from Cool, and calling method substr on an Int converts the integer to Str first.

123.substr(1, 1);   # '2', same as 123.Str.substr(1, 1)

So it seems that 123.substr(1, 1) is like Cool(123).substr(1, 1) in a more traditional notation, which is then rewritten to Str(123).substr(1, 1) because Str inherits from Cool (like the classical OOP done backward).

In a similar way, it seems that "100".Int.Complex is like Cool("100").Int.Complex -> Int("100").Complex -> 100.Complex -> Cool(100).Complex -> Complex(100).

like image 22
Kirill Bulygin Avatar answered Nov 11 '22 20:11

Kirill Bulygin