Today, a small excursus into the syntax. Did you know that roles in Perl 6 can have a parameter that makes them similar to generic templates in, say, C++? Hereās a small example:

role R {
has $.value;
method add($b) {
$.value + $b.value
}
method div($b) {
$.value / $b.value
}
}

The `R` role defines an interface that has a value and two methods for arithmetical operations: `add` and `div`.

Now, create a class using the role, initialise two variables and use the methods to get the results:

class C does R {}
my C $x = C.new(value => 10);
my C $y = C.new(value => 3);
say $x.add($y); *# 13*
say $x.div($y); *# 3.333333*

Although the values here were integers, Perl did a good job and returned a rational number for the division. You can easily see it by calling theĀ `WHAT` method:

say $x.add($y).WHAT; *# (Int)*
say $x.div($y).WHAT; *# (Rat)*

If you have two integers, the result of their division is always of the Rat type. The actual operator, which is triggered in this case, is the one from src/core/Rat.pm:

multi sub infix:</>(Int \a, Int \b) {
Ā Ā DIVIDE_NUMBERS a, b, a, b
}

The `DIVIDE_NUMBERS` sub returns a `Rat` value.

## Defining a role

How to modify theĀ `C` class so that it performs integer division? One of the options is to use a parameterised role:

role R**[::T]** {
has **T** $.value;
method add($b) {
**T**.new($.value + $b.value)
}
method div($b) {
**T**.new($.value / $b.value)
}
}

TheĀ parameter in square brackets after the role name restricts both the type of theĀ `$.value` attribute and the return type of the methods, which return a new object of the typeĀ `T`. Here, in the template of the role,Ā `T` is just a name, which should later be specified when the role is used.

## Using the role

So, letās make it integer:

class N does R**[Int]** {}

Now the parts of the role that employ theĀ `T` name replace it with Int, so the class is equivalent to the following definition:

class C {
has **Int** $.value;
method add($b) {
**Int**.new($.value + $b.value)
}
method div($b) {
**Int**.new($.value / $b.value)
}
}

The new class operates with integers, and the result of the division is an exact 3:

class N does R[**Int**] {}
my N $i = N.new(value => 10);
my N $j = N.new(value => 3);
say $i.add($j); *# 13*
say $i.div($j); *# 3*

It is also possible to force floating-point values by instructing the role accordingly:

class F does R[**Num**] {}
my F $x = F.new(value => 10e0);
my F $y = F.new(value => 3e0);
say $x.add($y); *# 13*
say $x.div($y); *# 3.33333333333333*

Notice that both values, including 13, are of the Num type now, not Int or Rat as it was before:

say $x.add($y).WHAT; *# (Num)*
say $x.div($y).WHAT; *# (Num)*