8

I came across this error message in another question and I would like to know what is the meaning of the $: part of the signature, please?

Cannot resolve caller index(Str: Str, Any); none of these signatures match:
      (Str:D $: Cool:D $needle, *%_)
      (Str:D $: Str:D $needle, *%_)
      (Str:D $: Cool:D $needle, Cool:D $pos, *%_)
      (Str:D $: Str:D $needle, Int:D $pos, *%_)
jjmerelo
  • 22,578
  • 8
  • 40
  • 86
librasteve
  • 6,832
  • 8
  • 30
  • 3
    Actually, I found this to be LTA: if you don't specify a name for the invocant of a method, you shouldn't be bothered by it in a `.perl` representation of the signature. So I changed this with https://github.com/rakudo/rakudo/commit/71159bedd7 , So in the future this will come out as `(Str:D: Cool:D $needle, *%_)`. – Elizabeth Mattijsen May 06 '18 at 19:19

2 Answers2

9

The $: is two distinct unrelated tokens, a $ and a :, that have been smooshed together.


The $ represents a single item1 aka a scalar2.

The single item / scalar hasn't been given a name, so there's no way to reference it. And there's already enough of a parameter (the Str:D) to let you and the compiler know that this parameter is a scalar (a single string). Either way, the $ is redundant and Elizabeth has made a related change.


The : is a special parameter separator. (The usual parameter separator is a comma ,.)

It may only be used immediately after the first parameter of a method or standalone signature. It may not be used in the signature of a routine that is not a method.

If used as a parameter separator after the first parameter in a signature, it marks that parameter as corresponding to a method's "invocant".

(If not used, the invocant parameter is implicit.)

The corresponding invocant argument will arrive anyway, and be aliased to self, whether or not the signature explicitly lists an invocant parameter. But if the invocant parameter is explicitly specified, it's possible to give it an additional/alternate name and/or explicitly constrain its type.


Crazy over-the-top footnotes for added entertainment. If they confuse you, just forget you ever read them.

1 A single item refers to data that is naturally a single thing, like the number 42, OR data that is naturally a composite thing (like an array) that is being treated like it's a single thing (like an array). (Did you see what I did there?) I like to point out the mnemonic that a $ symbol is like an S (for single) overlaid with an I (for item), or vice-versa. To me this represents the idea of emphasizing the single item nature of any data, hiding any plural aspect even if it's actually an array or other composite data item.

2 "scalar" is a traditional computing term. Wikipedia's Scalar disambiguation page lists "Variable (computing), or scalar, an atomic quantity that can hold only one value at a time" as a definition. Also, a single item aka scalar (all lowercase) is often/usually a Scalar (uppercase S), a special case of a single item that's a Single Item container that contains a Single Item (which can be composite data being treated as a single thing).

raiph
  • 31,607
  • 3
  • 62
  • 111
0

The : mark the first argument as an invocant.

my $word = "bananarama";
say $word.index( "r", 0 );

In this case, it indicates the invocant is going to be treated as an scalar, since it's constrained by a single $

jjmerelo
  • 22,578
  • 8
  • 40
  • 86
  • 1
    Invocant(s) are also described in the OO doc: https://docs.perl6.org/language/objects#Class_and_Instance_Methods – mr_ron May 06 '18 at 18:46
  • That's not quite right, index just happens to also exist as a sub, but nothing in the output in the OP tells you that; the output will be the same for things that only exist as methods, not as subs. – timotimo May 06 '18 at 21:16
  • 1
    Actually, that's also not accurate. You can bind to `$word` with `:=` in your example and it will still work fine, even though there is now no Scalar involved any more. In this case it would just mean that it will be treated as a scalar inside the method's implementation, which is less interesting for the user. – timotimo May 07 '18 at 11:16
  • @timotimo better now? – jjmerelo May 07 '18 at 12:24
  • that's better. i'm not sure if the `Str:D` in front should be mentioned in this answer or not, since the question is really about the `$:` part. – timotimo May 07 '18 at 14:15