7stud has asked for the wisdom of the Perl Monks concerning the following question:
Dear Monks
In the Raku docs, I see things like the following:
method Capture(Mu:D: --> Capture:D)
What does Mu:D: mean? It looks like the docs are trying to say that Capture() takes an argument of type Mu:D: and returns a type Capture:D. What is D and what is D: ?
And, how would someone look up the syntax Mu:D:?
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Raku: Function Signatures
by choroba (Cardinal) on Feb 16, 2024 at 18:03 UTC | |
I guess the colon after D is the infix : operator, but I'm not 100% sure. Mu is the base class of the class hieararchy, see Mu.
map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
| [reply] [d/l] [select] |
by 7stud (Deacon) on Feb 17, 2024 at 16:33 UTC | |
Thanks for your answer. It helped me make progress in understanding the syntax. The following is what I figured out with your help. In Raku, you can specify a type for a parameter variable:
However, specifying the type Int will allow you to call the function with both integers and the type object itself Int
The syntax Int:D means you can call the function with instances of the Int class, but not the Int type object:
Similarly, you can disallow instances with the syntax Int:U, which only allows you to pass the Int type object:
I think the hint in the error message is asking whether you meant to do:
Next, I tried the syntax Int:D: to see what would happen:
Then I played around with classes and methods, and this is what I came up with:
And: In Operators, the colon is listed as a comma. It does act like a separator between the two parameter variables in bark(), but the colon does more than that. In Parameter Separators the docs call the colon an invocant marker, and the docs say: ...the first parameter may be followed by a colon instead of a comma to mark the invocant of a method. This is done in order to distinguish it from what would then be a regular positional parameter. The invocant is the object that was used to call the method, which is usually bound to self. By specifying it in the signature, you can change the variable name it is bound to. I was unable to actually write something like Dog:D: in my code. Trying different ways of specifying Dog:D: caused errors, for instance the following didn't work:
Okay, I was able to use the syntax Dog:D: in my code:
Specifying Dog:D: means that the invocant of the method (trailing :) has to be a Dog instance (Dog:D). This won't work:
Without the Dog:D:
As a result, it looks like you can specify Dog:D: to limit method calls to instances, but you can't use the syntax Dog:D: to change the name of self. Ahh. Here is the syntax which both limits the method call to instances of the class AND changes the name of self:
Therefore, when you read something like the following in the docs:
The first line describes a sub/function named chr() that takes one argument of type Int:D, which means an instance of the Int class. In rakudo (the REPL for raku):
The second line for chr() describes a method, whose invocant (trailing colon) must be an instance of the Int class (Int:D). The syntax Int:D: does NOT specify a positional parameter (even if followed by a variable name!), so the method takes no arguments. In rakudo:
The second example on the page class Method uses Int:D: in some code: Apparently, you can have a free floating method that is not part of a class, and you call it with .&. Then, as described above, Int:D: means the invocant (:) has to be of type Int:D, i.e. an instance of the Int class. And <a> is the way you "quote words", so the argument is 'a', which gets assigned to the parameter variable $b. That example seems to suggest that you can add functionality to any class with a free floating method that specifies the type of the invocant to be of that class. Cha-ching | [reply] [d/l] [select] |
by smokemachine (Hermit) on Feb 19, 2024 at 18:34 UTC | |
| [reply] [d/l] |
by 7stud (Deacon) on Feb 20, 2024 at 00:24 UTC | |