The Perl6 type system
my $scalar;
our @array;
my %hash;
$scalar = “hi there”;
@array = 1, 2, “a string”;
%hash = one => 1, two => “2”;
my Any $scalar;
our Any @array;
my Any %hash;
$scalar = “hi there”;
@array = 1, 2, “a string”;
%hash = one => 1, two => “2”;
my Int $scalar;
our Int @array;
my Int %hash;
$scalar = “hi there”;
@array = 1, 2, “a string”;
%hash = one => 1, two => “2”;
my Int $scalar;
our Int @array;
my Int %hash;
$scalar = “hi there”;
@array = 1, 2, “a string”;
%hash = one => 1, two => “2”;
Type check failed in assignment to
'$scalar'; expected 'Int' but got 'Str'
in block <unit> at types.pl:4
AST
Any
Array
Associative
Backtrace
Backtrace::Frame
Bag
BagHash
Baggy
Blob
Block
Bool
Buf
Callable
Capture
Channel
Code
Complex
Cool
CurrentThreadScheduler
Cursor
Date
DateTime
Dateish
Duration
Enum
EnumMap
Exception
Failure
FatRat
Grammar
Hash
IO
IO::Handle
IO::Pipe
IO::Socket
Instant
Int
Iterable
Iterator
Junction
Label
List
Lock
Macro
Match
Metamodel::C3MRO
Metamodel::ClassHOW
Metamodel::Finalization
Metamodel::Naming
Metamodel::Primitives
Method
Mix
MixHash
Mixy
Mu
Nil
Num
Numeric
ObjAt
Pair
PairMap
Parameter
Parcel
Pod::Block
Pod::Item
Positional
Proc
Proc::Async
Proc::Status
Promise
Proxy
QuantHash
Range
Rat
Rational
Real
Regex
Routine
Scheduler
Signature
Str
Thread
Version
Whatever
sub sum_0_to_n($n) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
sub sum_0_to_n($n) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3); 6
sub sum_0_to_n($n) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
say sum_0_to_n(“3”);
6
sub sum_0_to_n($n) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
say sum_0_to_n(“3”);
6
6
sub sum_0_to_n($n) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
say sum_0_to_n(“3”);
say sum_0_to_n(“foo”);
6
6
sub sum_0_to_n($n) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
say sum_0_to_n(“3”);
say sum_0_to_n(“foo”);
6
6
Cannot convert string to number:
base-10 number must begin with valid
digits or '.' in '⏏foo' (indicated by ⏏)
In method Numeric at m-CORE:1576
In sub infix:<-> at m-CORE:5277
In sub infix:<-> at m-CORE:5277
In sub sub_0_to_n at sum.pl:3
In block <unit> at sum.pl:7
sub sum_0_to_n(Numeric $n) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
say sum_0_to_n(“foo”);
6
sub sum_0_to_n(Numeric $n) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
say sum_0_to_n(“foo”);
6
===SORRY!=== Error while compiling
sum.pl
Calling 'sum_0_to_n' will never work
with argument types (str)
Expected: :(Numeric $n)
at summer.pl:10
------> say ⏏sum_0_to_n("foo");
sub sum_0_to_n(Numeric $n) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
my $arg = “foo”;
say sum_0_to_n($arg);
6
sub sum_0_to_n(Numeric $n) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
my $arg = “foo”;
say sum_0_to_n($arg);
6
Type check failed in binding $n;
expected 'Numeric' but got 'Str'
in sub sum_0_to_n at sum.pl:1
in block <unit> at sum.pl:8
sub sum_0_to_n(Numeric $n) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
say sum_0_to_n(3.5);
6
sub sum_0_to_n(Numeric $n) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
say sum_0_to_n(3.5);
6
Hangs… infinite loop
sub sum_0_to_n(Int $n) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
say sum_0_to_n(3.5);
6
sub sum_0_to_n(Int $n) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
say sum_0_to_n(3.5);
6
===SORRY!=== Error while compiling
sum.pl
Calling 'sum_0_to_n' will never work
with argument types (Rat)
Expected: :(Int $n)
at sum.pl:9
sub sum_0_to_n(Int $n) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
say sum_0_to_n(-3);
6
sub sum_0_to_n(Int $n) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
say sum_0_to_n(-3);
6
Hangs… Infinite loop
sub sum_0_to_n(Int $n where * >= 0) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
say sum_0_to_n(-3);
6
sub sum_0_to_n(Int $n where * >= 0) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
say sum_0_to_n(-3);
6
Constraint type check failed for
parameter '$n'
in sub sum_0_to_n at sum.pl:4
in block <unit> at sum.pl:9
subtype NonNegInt of Int where * >= 0;
sub sum_0_to_n(NonNegInt $n) {
return 0 unless $n;
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
say sum_0_to_n(-3);
6
Constraint type check failed for
parameter '$n'
in sub sum_0_to_n at sum.pl:4
in block <unit> at sum.pl:9
subtype NonNegInt of Int where * >= 0;
multi sub sum_0_to_n(0) { 0 }
multi sub sum_0_to_n(NonNegInt $n) {
return $n + sum_0_to_n($n – 1);
}
say sum_0_to_n(3);
say sum_0_to_n(-3);
6
Constraint type check failed for
parameter '$n'
in sub sum_0_to_n at sum.pl:4
in block <unit> at sum.pl:9
subtype NonNegInt of Int where * >= 0;
multi sub sum_0_to_n(0) { 0 }
multi sub sum_0_to_n(NonNegInt $n) {
return $n + sum_0_to_n($n – 1);
}
multi sub sum_0_to_n(Int $n where * < 0) {
return $n + sum_0_to_n($n + 1);
}
say sum_0_to_n(3);
say sum_0_to_n(-3);
6
-6
subtype NonNegInt of Int where * >= 0;
multi sub sum_0_to_n(0) { 0 }
multi sub sum_0_to_n(NonNegInt $n) {
return $n + sum_0_to_n($n – 1);
}
multi sub sum_0_to_n(Int $n where * < 0) {
return $n + sum_0_to_n($n + 1);
}
sub MAIN(Int :$value!) {
say sum_0_to_n($value);
}
> perl6 sum.pl
Usage:
sum.pl –value=<Int>
subtype NonNegInt of Int where * >= 0;
multi sub sum_0_to_n(0) { 0 }
multi sub sum_0_to_n(NonNegInt $n) {
return $n + sum_0_to_n($n – 1);
}
multi sub sum_0_to_n(Int $n where * < 0) {
return $n + sum_0_to_n($n + 1);
}
sub MAIN(Int :$value!) {
say sum_0_to_n($value);
}
> perl6 sum.pl
Usage:
sum.pl –value=<Int>
> perl6 sum.pl –value=foo
Usage:
sum.pl --value=<Int>
subtype NonNegInt of Int where * >= 0;
multi sub sum_0_to_n(0) { 0 }
multi sub sum_0_to_n(NonNegInt $n) {
return $n + sum_0_to_n($n – 1);
}
multi sub sum_0_to_n(Int $n where * < 0) {
return $n + sum_0_to_n($n + 1);
}
sub MAIN(Int :$value!) {
say sum_0_to_n($value);
}
> perl6 sum.pl
Usage:
sum.pl –value=<Int>
> perl6 sum.pl –value=foo
Usage:
sum.pl –value=<Int>
> perl6 sum.pl – value=4
10
subtype NonNegInt of Int where * >= 0;
multi sub sum_0_to_n(0) returns Int { 0 }
multi sub sum_0_to_n(NonNegInt $n) returns Int {
return $n + sum_0_to_n($n – 1);
}
multi sub sum_0_to_n(Int $n where * < 0) returns Int {
return $n + sum_0_to_n($n + 1);
}
sub MAIN(Int :$value!) {
say sum_0_to_n($value);
}
class Dog {
has Str $.name;
has Int $.age is rw;
}
class Dog {
has Str $.name;
has Int $.age is rw;
}
class Owner {
has Str $.name;
has Dog @.dogs;
}
class Dog {
has Str $.name;
has Int $.age is rw;
}
class Owner {
has Str $.name;
has Dog @.dogs;
}
my $dog = Dog.new(name => 'Fido',
age => 'foo');
Type check failed in assignment to '$!age'; expected 'Int' but got 'Str'
in block at src/gen/m-CORE.setting:1009
in method BUILDALL at src/gen/m-CORE.setting:992
in method bless at src/gen/m-CORE.setting:981
in method new at src/gen/m-CORE.setting:967
in block <unit> at dogs.pl:10
class Dog {
has Str $.name;
has Int $.age is rw;
}
class Owner {
has Str $.name;
has Dog @.dogs;
}
my $dog = Dog.new(name => 'Fido',
age => '2');
$dog.age = “foo”;
Type check failed in assignment to '$!age'; expected 'Int' but got 'Str'
In block <unit> at dogs.pl:11
class Dog {
has Str $.name;
has Int $.age is rw;
}
class Owner {
has Str $.name;
has Dog @.dogs;
}
my $dog = Dog.new(name => 'Fido',
age =>2);
my $owner = Owner.new(name => 'Bob',
dogs => ($dog, 'foo'));
Type check failed in assignment to '@!dogs'; expected 'Dog' but got 'Str'
in method REIFY at src/gen/m-CORE.setting:10861
in method reify at src/gen/m-CORE.setting:9471
in method gimme at src/gen/m-CORE.setting:9954
in method sink at src/gen/m-CORE.setting:10438
in method BUILDALL at src/gen/m-CORE.setting:1083
in method bless at src/gen/m-CORE.setting:981
in method new at src/gen/m-CORE.setting:967
in block <unit> at dogs.pl:11
class Dog {
has Str $.name;
has Int $.age;
}
class Owner {
has Str $.name;
has Dog @.dogs;
}
my $dog = Dog.new(name => 'Fido',
age =>2);
my $owner = Owner.new(name => 'Bob',
dogs => ($dog));
If ($owner ~~ Dog) {
say “owner is-a Dog”;
} elsif ($owner ~~ Owner) {
say “owner is-a Owner”;
} else {
say “owner is-a something else”;
}
given $thing {
when Dog { say '$thing is-a Dog' }
when 3 { say '$thing is 3' }
when "blah" { say '$thing is blah' }
when /pattern/ { say '$thing matches /pattern/' }
when (10 .. 20) { say '$thing is between 10 and 20' }
when any(1, 4, 6) { say '$thing is 1, 4 or 6' }
}
class Dog {
has Str $.name;
has Int $.age;
}
class Owner {
has Str $.name;
has Dog @.dogs;
method ACCEPTS(Dog $d) {
return $d ~~ any(@.dogs);
}
}
class Dog {
has Str $.name;
has Int $.age;
}
class Owner {
has Str $.name;
has Dog @.dogs;
method ACCEPTS(Dog $d) {
return $d ~~ any(@.dogs);
}
}
my $fido = Dog.new(name => 'Fido', age => 3)
my $bob = Owner.new(name => 'Bob', dogs => ($fido));
my $fred = Owner.new(name => 'Fred');
given $fido {
When $fred { say “owned by Fred” }
When $bob { say “owned by Bob” }
}

The Perl6 Type System

  • 1.
  • 2.
    my $scalar; our @array; my%hash; $scalar = “hi there”; @array = 1, 2, “a string”; %hash = one => 1, two => “2”;
  • 3.
    my Any $scalar; ourAny @array; my Any %hash; $scalar = “hi there”; @array = 1, 2, “a string”; %hash = one => 1, two => “2”;
  • 4.
    my Int $scalar; ourInt @array; my Int %hash; $scalar = “hi there”; @array = 1, 2, “a string”; %hash = one => 1, two => “2”;
  • 5.
    my Int $scalar; ourInt @array; my Int %hash; $scalar = “hi there”; @array = 1, 2, “a string”; %hash = one => 1, two => “2”; Type check failed in assignment to '$scalar'; expected 'Int' but got 'Str' in block <unit> at types.pl:4
  • 6.
  • 7.
    sub sum_0_to_n($n) { return0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3);
  • 8.
    sub sum_0_to_n($n) { return0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); 6
  • 9.
    sub sum_0_to_n($n) { return0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); say sum_0_to_n(“3”); 6
  • 10.
    sub sum_0_to_n($n) { return0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); say sum_0_to_n(“3”); 6 6
  • 11.
    sub sum_0_to_n($n) { return0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); say sum_0_to_n(“3”); say sum_0_to_n(“foo”); 6 6
  • 12.
    sub sum_0_to_n($n) { return0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); say sum_0_to_n(“3”); say sum_0_to_n(“foo”); 6 6 Cannot convert string to number: base-10 number must begin with valid digits or '.' in '⏏foo' (indicated by ⏏) In method Numeric at m-CORE:1576 In sub infix:<-> at m-CORE:5277 In sub infix:<-> at m-CORE:5277 In sub sub_0_to_n at sum.pl:3 In block <unit> at sum.pl:7
  • 13.
    sub sum_0_to_n(Numeric $n){ return 0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); say sum_0_to_n(“foo”); 6
  • 14.
    sub sum_0_to_n(Numeric $n){ return 0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); say sum_0_to_n(“foo”); 6 ===SORRY!=== Error while compiling sum.pl Calling 'sum_0_to_n' will never work with argument types (str) Expected: :(Numeric $n) at summer.pl:10 ------> say ⏏sum_0_to_n("foo");
  • 15.
    sub sum_0_to_n(Numeric $n){ return 0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); my $arg = “foo”; say sum_0_to_n($arg); 6
  • 16.
    sub sum_0_to_n(Numeric $n){ return 0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); my $arg = “foo”; say sum_0_to_n($arg); 6 Type check failed in binding $n; expected 'Numeric' but got 'Str' in sub sum_0_to_n at sum.pl:1 in block <unit> at sum.pl:8
  • 17.
    sub sum_0_to_n(Numeric $n){ return 0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); say sum_0_to_n(3.5); 6
  • 18.
    sub sum_0_to_n(Numeric $n){ return 0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); say sum_0_to_n(3.5); 6 Hangs… infinite loop
  • 19.
    sub sum_0_to_n(Int $n){ return 0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); say sum_0_to_n(3.5); 6
  • 20.
    sub sum_0_to_n(Int $n){ return 0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); say sum_0_to_n(3.5); 6 ===SORRY!=== Error while compiling sum.pl Calling 'sum_0_to_n' will never work with argument types (Rat) Expected: :(Int $n) at sum.pl:9
  • 21.
    sub sum_0_to_n(Int $n){ return 0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); say sum_0_to_n(-3); 6
  • 22.
    sub sum_0_to_n(Int $n){ return 0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); say sum_0_to_n(-3); 6 Hangs… Infinite loop
  • 23.
    sub sum_0_to_n(Int $nwhere * >= 0) { return 0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); say sum_0_to_n(-3); 6
  • 24.
    sub sum_0_to_n(Int $nwhere * >= 0) { return 0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); say sum_0_to_n(-3); 6 Constraint type check failed for parameter '$n' in sub sum_0_to_n at sum.pl:4 in block <unit> at sum.pl:9
  • 25.
    subtype NonNegInt ofInt where * >= 0; sub sum_0_to_n(NonNegInt $n) { return 0 unless $n; return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); say sum_0_to_n(-3); 6 Constraint type check failed for parameter '$n' in sub sum_0_to_n at sum.pl:4 in block <unit> at sum.pl:9
  • 26.
    subtype NonNegInt ofInt where * >= 0; multi sub sum_0_to_n(0) { 0 } multi sub sum_0_to_n(NonNegInt $n) { return $n + sum_0_to_n($n – 1); } say sum_0_to_n(3); say sum_0_to_n(-3); 6 Constraint type check failed for parameter '$n' in sub sum_0_to_n at sum.pl:4 in block <unit> at sum.pl:9
  • 27.
    subtype NonNegInt ofInt where * >= 0; multi sub sum_0_to_n(0) { 0 } multi sub sum_0_to_n(NonNegInt $n) { return $n + sum_0_to_n($n – 1); } multi sub sum_0_to_n(Int $n where * < 0) { return $n + sum_0_to_n($n + 1); } say sum_0_to_n(3); say sum_0_to_n(-3); 6 -6
  • 28.
    subtype NonNegInt ofInt where * >= 0; multi sub sum_0_to_n(0) { 0 } multi sub sum_0_to_n(NonNegInt $n) { return $n + sum_0_to_n($n – 1); } multi sub sum_0_to_n(Int $n where * < 0) { return $n + sum_0_to_n($n + 1); } sub MAIN(Int :$value!) { say sum_0_to_n($value); } > perl6 sum.pl Usage: sum.pl –value=<Int>
  • 29.
    subtype NonNegInt ofInt where * >= 0; multi sub sum_0_to_n(0) { 0 } multi sub sum_0_to_n(NonNegInt $n) { return $n + sum_0_to_n($n – 1); } multi sub sum_0_to_n(Int $n where * < 0) { return $n + sum_0_to_n($n + 1); } sub MAIN(Int :$value!) { say sum_0_to_n($value); } > perl6 sum.pl Usage: sum.pl –value=<Int> > perl6 sum.pl –value=foo Usage: sum.pl --value=<Int>
  • 30.
    subtype NonNegInt ofInt where * >= 0; multi sub sum_0_to_n(0) { 0 } multi sub sum_0_to_n(NonNegInt $n) { return $n + sum_0_to_n($n – 1); } multi sub sum_0_to_n(Int $n where * < 0) { return $n + sum_0_to_n($n + 1); } sub MAIN(Int :$value!) { say sum_0_to_n($value); } > perl6 sum.pl Usage: sum.pl –value=<Int> > perl6 sum.pl –value=foo Usage: sum.pl –value=<Int> > perl6 sum.pl – value=4 10
  • 31.
    subtype NonNegInt ofInt where * >= 0; multi sub sum_0_to_n(0) returns Int { 0 } multi sub sum_0_to_n(NonNegInt $n) returns Int { return $n + sum_0_to_n($n – 1); } multi sub sum_0_to_n(Int $n where * < 0) returns Int { return $n + sum_0_to_n($n + 1); } sub MAIN(Int :$value!) { say sum_0_to_n($value); }
  • 32.
    class Dog { hasStr $.name; has Int $.age is rw; }
  • 33.
    class Dog { hasStr $.name; has Int $.age is rw; } class Owner { has Str $.name; has Dog @.dogs; }
  • 34.
    class Dog { hasStr $.name; has Int $.age is rw; } class Owner { has Str $.name; has Dog @.dogs; } my $dog = Dog.new(name => 'Fido', age => 'foo'); Type check failed in assignment to '$!age'; expected 'Int' but got 'Str' in block at src/gen/m-CORE.setting:1009 in method BUILDALL at src/gen/m-CORE.setting:992 in method bless at src/gen/m-CORE.setting:981 in method new at src/gen/m-CORE.setting:967 in block <unit> at dogs.pl:10
  • 35.
    class Dog { hasStr $.name; has Int $.age is rw; } class Owner { has Str $.name; has Dog @.dogs; } my $dog = Dog.new(name => 'Fido', age => '2'); $dog.age = “foo”; Type check failed in assignment to '$!age'; expected 'Int' but got 'Str' In block <unit> at dogs.pl:11
  • 36.
    class Dog { hasStr $.name; has Int $.age is rw; } class Owner { has Str $.name; has Dog @.dogs; } my $dog = Dog.new(name => 'Fido', age =>2); my $owner = Owner.new(name => 'Bob', dogs => ($dog, 'foo')); Type check failed in assignment to '@!dogs'; expected 'Dog' but got 'Str' in method REIFY at src/gen/m-CORE.setting:10861 in method reify at src/gen/m-CORE.setting:9471 in method gimme at src/gen/m-CORE.setting:9954 in method sink at src/gen/m-CORE.setting:10438 in method BUILDALL at src/gen/m-CORE.setting:1083 in method bless at src/gen/m-CORE.setting:981 in method new at src/gen/m-CORE.setting:967 in block <unit> at dogs.pl:11
  • 37.
    class Dog { hasStr $.name; has Int $.age; } class Owner { has Str $.name; has Dog @.dogs; } my $dog = Dog.new(name => 'Fido', age =>2); my $owner = Owner.new(name => 'Bob', dogs => ($dog)); If ($owner ~~ Dog) { say “owner is-a Dog”; } elsif ($owner ~~ Owner) { say “owner is-a Owner”; } else { say “owner is-a something else”; }
  • 38.
    given $thing { whenDog { say '$thing is-a Dog' } when 3 { say '$thing is 3' } when "blah" { say '$thing is blah' } when /pattern/ { say '$thing matches /pattern/' } when (10 .. 20) { say '$thing is between 10 and 20' } when any(1, 4, 6) { say '$thing is 1, 4 or 6' } }
  • 39.
    class Dog { hasStr $.name; has Int $.age; } class Owner { has Str $.name; has Dog @.dogs; method ACCEPTS(Dog $d) { return $d ~~ any(@.dogs); } }
  • 40.
    class Dog { hasStr $.name; has Int $.age; } class Owner { has Str $.name; has Dog @.dogs; method ACCEPTS(Dog $d) { return $d ~~ any(@.dogs); } } my $fido = Dog.new(name => 'Fido', age => 3) my $bob = Owner.new(name => 'Bob', dogs => ($fido)); my $fred = Owner.new(name => 'Fred'); given $fido { When $fred { say “owned by Fred” } When $bob { say “owned by Bob” } }