The Type System and Gradual Typing

20.1 The Type Hierarchy

Mu                     (root of everything)
├── Junction
└── Any                (default for variables and parameters)
    ├── Cool           ("Convenient OO Loop": types that coerce freely: Str, Numeric, List...)
    │   ├── Str, Int, Rat, Num, Complex, Bool (enum), List, Array, Hash, Range, Seq, Map...
    ├── Pair, Set, Bag, Mix, Capture, Signature, Block, Routine, Sub, Method, Regex, Match, Grammar...
    ├── Exception (X::*), Failure, Promise, Supply, Channel, IO::Path, IO::Handle, Date, DateTime...

20.2 Type Objects, Definedness and Smileys

say Int;                    # (Int) (a type object: undefined)
say Int.defined;            # False
say 42.WHAT, ' ', 42.^name; # (Int) Int
say 42 ~~ Int, ' ', 42 ~~ Numeric, ' ', 42 ~~ Cool;   # True True True
sub f(Int:D $x) { }         # :D only defined values
sub g(Int:U $x) { }         # :U only type objects
sub h(Int:_ $x) { }         # either (default)
my Int:D $must-be-defined = 0;
say Str.new ~~ Str:D;       # True ('' is defined)
use variables :D;           # pragma: make variables :D by default in this scope

20.3 Gradual Typing

my $anything = 42;          # untyped (Any)
$anything = 'now a string';
my Int $typed = 42;
# $typed = 'x';             # X::TypeCheck::Assignment
my Numeric @nums = 1, 2.5, 3e0;
my Str %names;
sub typed-sub(Str $s, Int :$n = 1 --> Str) { $s x $n }
# Type checks happen at compile time when possible ("Calling typed-sub(Int) will never work...")
# and at run time otherwise.

20.4 Coercion and Allomorphs

say '42'.Int + 1, ' ', 42.Str.chars, ' ', 3.7.Int, ' ', '1/4'.Rat;
say <42>.WHAT;              # (IntStr): an allomorph (both Int and Str)
say <42> + 1, ' ', <42> ~ 'x';   # 43 42x
say val('3.14').WHAT;       # (RatStr)
sub takes-int(Int() $n) { $n.WHAT }    # coercive parameter: coerces from Any
say takes-int('42');                   # (Int)
sub from-str(Int(Str) $n) { $n }       # coerce only from Str
my Int() $coerced = '7';
say $coerced.WHAT;                     # (Int)