Skip to content

Commit 6a8d9de

Browse files
authored
In signatures.rakudoc: Complete overhaul regarding double semicolon (;;) for controlling signature precedence (#4648)
* Complete overhaul of section on double semicolon (;;) parameter separator in file Language/signatures.rakudoc * fix semicolons * correct backtick to rakudoc syntax for code
1 parent 22cc614 commit 6a8d9de

File tree

1 file changed

+48
-6
lines changed

1 file changed

+48
-6
lines changed

doc/Language/signatures.rakudoc

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ change the variable name it is bound to.
133133
}
134134
say Foo.whoami; # OUTPUT: «Well I'm class Foo, of course!␤»
135135

136+
A further exception is the L<double semicolon C<;;>|/language/Signatures#The_;;_separator>,
137+
which can be used in L<multi|/language/functions#Multi-dispatch> signatures to declare that all subsequent parameters should not
138+
contribute to its precedence under multiple dispatch.
139+
136140
X<|Language,type constraint>
137141
X<|Language,Constraint>
138142
=head1 Type constraints
@@ -1125,14 +1129,52 @@ indicate that the routine's L<C<multi> definitions|/syntax/multi> can have any L
11251129
constraints|#Type_constraints>. See L<proto|/language/functions#proto> for an
11261130
example.
11271131

1128-
=head1 X<Long names|Language,Long names>
1132+
=head1 X<The C«;;» separator|Syntax,double-semicolon;Language,Long names>
1133+
1134+
In L<multiple dispatch|/language/Functions#Multi-dispatch>, when more than one multi signature matches
1135+
the given input parameters, the narrowest signature wins.
1136+
1137+
When a double semicolon C<;;> is present in a signature,
1138+
only parameters to the left of the C<;;> are considered in this narrowness analysis.
1139+
It can take the place of a comma, or be at the very beginning:
1140+
1141+
multi foo (;; Numeric $a) { say "numeric" };
1142+
multi foo (;; Int $a) { say "int" };
1143+
foo(42);
1144+
# OUTPUT: «Ambiguous call to 'foo(Int)'; these signatures all match:
1145+
# (;; Numeric $a) from <unknown file> line 1
1146+
# (;; Int $a) from <unknown file> line 1␤...»
1147+
# (Without the ;; the output would have been «int».)
1148+
1149+
This can be useful when the usual order of precedence is undesired.
1150+
Consider this example with a named parameter:
1151+
1152+
multi bar(Int $i) { say "just $i" };
1153+
multi bar(Int $i, Str :$s) { say "both $i and 「$s.raku」" };
1154+
bar(42);
1155+
# OUTPUT: «Use of uninitialized value of type Str in string context.␤(...)
1156+
# both 42 and 「」␤ in sub e at <tmp> line 1␤»
1157+
1158+
Here it was the I<second> multi that got executed,
1159+
because its signature is narrower than the first and does in fact match C<bar(42)>, even though $s then stays undefined.
1160+
By adding C<;;>, we can lower its precedence:
1161+
1162+
multi f(Int $i) { say "just $i" };
1163+
multi f(Int $i;; Str :$s) { say "both $i and 「$s」" };
1164+
f(42);
1165+
# OUTPUT: «Ambiguous call to 'e(Int)'; these signatures all match:
1166+
# (Int $i) from <tmp> line 1␤ (Int $i;; Str :$s) from <tmp> line 1␤ ...»
1167+
1168+
One could then give the first multi the trait L<C<is default>|/type/Routine#trait_is_default>, whose exact effect is
1169+
to break a tie between multiple signatures of the same precedence.
11291170

1130-
To exclude certain parameters from being considered in multiple dispatch,
1131-
separate them with a double semicolon.
1171+
There is more than one way to control the narrowness
1172+
(and thereby, precedence) of signatures. Other options include
1173+
making parameters optional via C<?> or required via C<!>.
11321174

1133-
multi f(Int $i, Str $s;; :$b) { say "$i, $s, {$b.raku}" };
1134-
f(10, 'answer');
1135-
# OUTPUT: «10, answer, Any␤»
1175+
The double semicolon C<;;> can also be used in signatures of L<parameterized Roles|/language/Typesystem#Parameterized>.
1176+
Parameterized roles have a so-called "long name" generated from their signature, which can be used for introspection.
1177+
Only parameters to the left of C<;;> contribute to it.
11361178

11371179
=head1 Parameter traits and modifiers
11381180

0 commit comments

Comments
 (0)