Skip to content

Commit e3edec2

Browse files
committed
Small rephrasing about coercion.
Also define the example class Bar at the beginning of the example, there is no point here to leave it abstract.
1 parent fed435e commit e3edec2

File tree

1 file changed

+27
-13
lines changed

1 file changed

+27
-13
lines changed

doc/Language/functions.pod6

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -906,43 +906,51 @@ say LoggedVersion.new('1.0.2');
906906
907907
=head1 Coercion Types
908908
909-
Coercion types can help you to have a specific type inside a routine, but
910-
accept wider input. When the routine is called, the argument is automatically
911-
converted to the narrower type.
909+
Coercion types force a specific type for routine arguments while allowing
910+
the routine itself to accept a wider input. When invoked, the arguments are
911+
narrowed automatically to the stricter type, and therefore within the routine
912+
the arguments have always the desired type.
913+
914+
In the case the arguments cannot be converted to the stricter type, a I<Type Check> error
915+
is thrown.
912916
913917
=begin code
914918
sub double(Int(Cool) $x) {
915919
2 * $x
916920
}
917921
918922
say double '21'; # OUTPUT: «42␤»
923+
say double 21; # OUTPUT: «42␤»
919924
say double Any; # Type check failed in binding $x; expected 'Cool' but got 'Any'
920925
=end code
921926
922-
Here, the C<Int> is the target type to which the argument will be coerced, and
923-
C<Cool> is the type that the routine accepts as input.
927+
In the above example, the L<Int|/type/Int> is the target type to which the argument C<$x> will be coerced, and
928+
L<Cool|/type/Cool> is the type that the routine accepts as wider input.
924929
925-
If the accepted input type is L<Any|/type/Any>, you can abbreviate C<Int(Any)>
926-
to C<Int()>.
930+
If the accepted wider input type is L<Any|/type/Any>, it is possible to abbreviate the coercion C<Int(Any)>
931+
omitting the C<Any> type, thus resulting in C<Int()>.
927932
928933
The coercion works by looking for a method with the same name
929-
as the target type. You can define coercions for your own types like so:
934+
as the target type: if such method is found on the argument, it is invoked to
935+
convert the latter to the expected narrow type.
936+
From the above, it is clear that it is possible to provide coercion among user types
937+
just providing the required methods:
930938
931939
=begin code
932-
class Bar {...}
940+
class Bar {
941+
has $.msg;
942+
}
933943
934944
class Foo {
935945
has $.msg = "I'm a foo!";
936946
947+
# allows coercion from Foo to Bar
937948
method Bar {
938949
Bar.new(:msg($.msg ~ ' But I am now Bar.'));
939950
}
940951
}
941952
942-
class Bar {
943-
has $.msg;
944-
}
945-
953+
# wants a Bar, but accepts Any
946954
sub print-bar(Bar() $bar) {
947955
say $bar.^name; # OUTPUT: «Bar␤»
948956
say $bar.msg; # OUTPUT: «I'm a foo! But I am now Bar.␤»
@@ -951,9 +959,15 @@ sub print-bar(Bar() $bar) {
951959
print-bar Foo.new;
952960
=end code
953961
962+
In the above code, once a C<Foo> instance is passed as argument to C<print-bar>, the C<Foo.Bar>
963+
method is called and the result is placed into C<$bar>.
964+
954965
Coercion types are supposed to work wherever types work, but Rakudo currently
955966
(2017.05) only implements them in signatures, for both parameters and return types.
956967
968+
=comment is the above referencing rakudo 2017.05 still valid?
969+
=comment is it worth placing an example about return types?
970+
957971
=head1 sub MAIN
958972
959973
X<|MAIN>X<|command line arguments>

0 commit comments

Comments
 (0)