I wanted to make a method that took an integer or a string that looked like an integer. I thought a coercion type would work nicely for that. The Int is the target type and Str is the type it will accept then coerce:

sub something ( Int:D(Str:D) $n ) { ... } something( 37 ); something( "137" ); something( "Hello" ); # I want this to fail something( 1.5 ); # I want this to fail too

That didn’t quite work out. If I pass it a Str it calls .Int . A string like "1.5" converts just fine because the .Int not only changes types but can change the data. We are used to int() as a way to make floating point numbers into whole numbers. So, .Int has two jobs: managing types and managing values. I don’t like that and don’t think that 3.14 is 3. I asked about it on StackOverflow and got some interesting answers. Brad Gilbert shows the long hard way which is close to what I was already doing but there’s no need for the coercion type then. I was a little disappointed.

Then I wondered what would happen if a .Int method did not return the right sort of type. I didn’t expect this to run without an error (I originally typed “expect this to work”!) but it does. I made an .Int that returned a Str . That’s silly but I can imagine myself making stupid error like this and typing should show my stupidity:

class Foo { method Int ( --> Str:D ) { 'Hello' } } put try-it( Foo.new ); sub try-it ( Int:D() $n ) { "Got 「$n」 of type 「{$n.^name}」" }

Although the subroutine signature demanded an Int it accepted something that claimed to be able to convert but actually didn’t. The .Int method is the right thing to call but there was nothing to check that it did the right thing:

Got 「Hello」 of type 「Str」

I would have expected the runtime constraint to check the ultimate value against the type and this would have failed. But it doesn’t check that the value ends up the correct type. Assigning to a value with a type limitation works though:

class Foo { method Int { "Hello" } } my Str $m = Foo.Int; # works my Int $n = Foo.Int; # this fails as expected

I filed RT 132980 which led to some clarifications in the documentation but also a note that it’s on the back burner for a fix because the proper type check leads to a slowdown (even if you don’t use it, I take it). The motto of Rakudo had been “make it work right then make it work fast”, but sometimes there are other trade-offs that are more important.