Skip to content

Commit a4fb28d

Browse files
authored
reorganize "constraining return types"
1 parent 07ebaeb commit a4fb28d

File tree

1 file changed

+66
-34
lines changed

1 file changed

+66
-34
lines changed

doc/Type/Signature.pod6

Lines changed: 66 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -238,50 +238,82 @@ on their signature write the signature after the argument name.
238238
239239
=head3 X«Constraining Return Types|-->;returns»
240240
241-
The token C<-->> followed by a type will force a type check on successful
242-
execution of a routine. The return type arrow has to be placed at the end of
243-
the parameter list. The keyword C<returns> following a signature declaration
244-
has the same function. C<Nil> and its subclasses do B<not> abide by return
245-
constraints. This allows L<Failure|/type/Failure> to be returned and passed on
246-
down the call chain.
247-
248-
sub foo(--> Int) { my Int $i; $i };
249-
sub baz(--> Int:D) { 1 }
250-
sub bar() returns Int { 1 };
251-
sub does-not-work(--> Int) { "" }; # throws X::TypeCheck::Return
252-
253-
There are two other ways to declare a return type:
254-
255-
sub foo() of Int { 1 };
256-
my Int sub bar { 1 };
257-
258-
C<of> is just the real name of the C<returns> keyword, and the
259-
prefix(C-like) form can be used too. Although all the ways are valid,
260-
the C<-->> form is preferred for several reasons:
241+
There are multiple ways to constrain return types on a sub or method. All versions below
242+
are currently valid and will force a type check on successful execution of a routine.
243+
244+
L<C<Nil>|/type/Nil> and L<C<Failure>|/type/Failure> are always allowed as return types,
245+
regardless of any type constraint. This allows L<Failure|/type/Failure> to be returned
246+
and passed on down the call chain.
247+
248+
sub foo(--> Int) { Nil };
249+
say foo.perl; # OUTPUT: «Nil␤»
250+
251+
Type captures and coercion types are not supported.
252+
253+
=item C<-->>
254+
255+
This form is preferred for several reasons:
261256
(1) it can handle constant values while the others can't;
262-
(2) for consistency, it is the only form accepted on this site; and
263-
(3) the C<returns> form is planned for future removal.
257+
(2) for consistency, it is the only form accepted on this site;
264258
265-
The following illustrates how to write a signature returning a constant value:
259+
The return type arrow has to be placed at the end of the parameter list, with
260+
or without a C<,> before it.
266261
267-
=begin code :skip-test
268-
my 42 sub bad-answer {}; # This will fail.
269-
sub bad-answer2 returns 42 {}; # This too.
270-
sub answer(--> 42) { return; } # This doesn't.
271-
=end code
262+
=begin code
263+
sub greeting(Str $name --> Str) { say "Hello, $name" } # Valid
264+
sub greeting(Str $name, --> Str) { say "Hello, $name" } # Valid
272265
266+
sub favorite-number(--> 42) { } # OUTPUT: 42
267+
sub favorite-number(--> 42) { return } # OUTPUT: 42
268+
=end code
269+
273270
If the type constraint is a constant expression, it is used as the return value
274271
of the routine. Any return statement in that routine has to be argumentless.
275272
276-
sub foo(--> 123) { return }
273+
=begin code :skip-test
274+
sub foo(Str $word --> 123) { say $word; return; }
275+
my $value = foo("hello"); # OUTPUT: hello
276+
say $value; # OUTPUT: 123
277+
278+
# The code below will not compile
279+
sub foo(Str $word --> 123) { say $word; return $word; }
280+
my $value = foo("hello");
281+
say $value;
282+
=end code
277283
278-
L<C<Nil>|/type/Nil> and L<C<Failure>|/type/Failure> are always allowed as return types,
279-
regardless of any type constraint.
284+
=item C<returns>
280285
281-
sub foo(--> Int) { Nil };
282-
say foo.perl; # OUTPUT: «Nil␤»
286+
The keyword C<returns> following a signature declaration
287+
has the same function as C<-->> with two caveats.
283288
284-
Type captures and coercion types are not supported.
289+
(1) This form is planned for future removal.
290+
(2) This form does not work with constant values
291+
292+
=begin code :skip-test
293+
sub greeting(Str $name) returns Str { say "Hello, $name" } # Valid
294+
295+
sub favorite-number returns 42 { } # This will fail.
296+
=end code
297+
298+
=item C<of>
299+
300+
C<of> is just the real name of the C<returns> keyword.
301+
302+
=begin code :skip-test
303+
sub foo() of Int { 42 }; # Valid
304+
305+
sub foo() of 42 { }; # This will fail.
306+
=end code
307+
308+
=item prefix(C-like) form
309+
310+
This is similar to placing type constraints on variables like C<my Type $var = 20;>,
311+
except the $var is a definition for a routine.
312+
313+
=begin code :skip-test
314+
my Int sub bar { 1 }; # Valid
315+
my 42 sub bad-answer {}; # This will fail.
316+
=end code
285317
286318
=head3 X<Coercion Type|coercion type (signature)>
287319

0 commit comments

Comments
 (0)