On 2020-06-07 08:19, Peter Pentchev wrote:
On Sun, Jun 07, 2020 at 09:04:45AM -0500, Brad Gilbert wrote:
On Sun, Jun 7, 2020 at 3:15 AM ToddAndMargo via perl6-users <
perl6-us...@perl.org> wrote:
Hi All,
Dumb question:
Does the "multi" in "multi method" mean there
is more than one way to address a method?
Or, are the all methods "multi methods".
If not and the method is a multi, should not the
documentation show all (more than one) the ways of
addressing a multi method?
There are four different types of a function. (both method and sub)
- `multi`
- `proto`
- `only`
- `anon`
A `proto` function is mainly just to declare there will be multiple
functions with same name.
`multi` is short for "multiple", meaning more than one.
`only` is the default, it means there is only one.
`anon` is for creating a lambda. (You only need it if you give the function
a name.)
Again this applies to both subs and methods.
(Also `regex`, `token`, and `rule`. As they are just special methods.)
only sub foo (){}
only sub foo (1){} # ERROR: redeclaration
# note that `only` is optional, as it is the default.
proto sub bar (|){*}
multi sub bar (){}
multi sub bar (1){}
# note that defining a `proto` function is optional
my $var = anon sub baz (){ 'fuzz' };
say baz(); # ERROR: can't find a sub named `baz`
say $var(); # fuzz
say $var.name; # baz
I believe, though I'm not sure, that Todd may be referring to one of
the questions that came up in a longish recent thread, namely the fact
that the documentation of Str.starts-with() seems to only document it as
a Str method, while Raku seems to disagree:
[roam@straylight ~]$ raku -e 'my Str $x; $x.starts-with("a")'
Cannot resolve caller starts-with(Str:U: Str:D); none of these signatures match:
(Cool:D: Cool:D $needle, :i(:$ignorecase)!, :m(:$ignoremark), *%_ --> Bool)
(Cool:D: Cool:D $needle, :m(:$ignoremark)!, *%_ --> Bool)
(Cool:D: Cool:D $needle, *%_ --> Bool)
(Str:D: Str:D $needle, :i(:$ignorecase)!, :m(:$ignoremark), *%_ --> Bool)
(Str:D: Str:D $needle, :m(:$ignoremark)!, *%_ --> Bool)
(Str:D: Str:D $needle, *%_ --> Bool)
in block <unit> at -e line 1
[roam@straylight ~]$
So it seems that Cool has a .starts-with() method too, and this is borne
out by a further experiment:
[roam@straylight ~]$ raku -e 'my Cool $x; $x.starts-with("a")'
Cannot resolve caller starts-with(Cool:U: Str:D); none of these signatures
match:
(Cool:D: Cool:D $needle, :i(:$ignorecase)!, :m(:$ignoremark), *%_ --> Bool)
(Cool:D: Cool:D $needle, :m(:$ignoremark)!, *%_ --> Bool)
(Cool:D: Cool:D $needle, *%_ --> Bool)
in block <unit> at -e line 1
[roam@straylight ~]$
So the truth is that I do not fully understand why the documentation
does not list .starts-with() as a method for Cool as well as Str: in
https://docs.raku.org/routine.html "starts-with" is listed as "from
Str", while there are other methods that are listed as "from Cool, Str",
e.g. "subst".
Now, yeah, I understand that Str.starts-with() defines a coercion for
its $needle argument that means that Cool.starts-with() will never be
called for an invocant that is either a Str or of any type derived from
Str, no matter what $needle is - if it is from another Cool-derived
type, it will be coerced to Str and Str.starts-with() will be called.
However, should the documentation not mention that another type derived
from Cool will also have a .starts-with() method?
Please note that I'm not criticizing the documentation,
That is all right. I will take up that job. I am
about to zinger it pretty good.
automatically
generated or not, or the efforts of everyone involved in producing it :)
I am under the impression that it is, at least to some extent,
automatically generated, so I'm genuinely curious what is it about
the .starts-with() method that has caused it to lose its Cool :)
...and, of course, it may turn out that Todd meant something completely
different in this particular message and I hijacked the thread...
G'luck,
Peter
Hi Peter,
Pretty close.
I do believe Brad answered the question. There are
multiple and only and some other types.
The reason why I ask is that I find the documentation
frustrating. Here is an example of a method I
have NO trouble with and use all the time:
https://docs.raku.org/type/Mu#method_defined
Declared as
multi method defined( --> Bool:D)
Returns False on a type object, and True otherwise.
It shows one method, but clearly defines it as a
"multi method". If it is indeed a multiple,
where are the other crypto lines? Or is it a
misprint and there is only one crypto line as
it is indeed an "only".
So I asked, are they ALL multi's. And the answer is "no".
Now when I opened a bug report on one of them:
Where is the multi in starts-with?
https://github.com/Raku/doc/issues/3456
JJ closed the ticket with the following answer:
Let me see how I explain this. It's a bit like
the American party primaries. Anyone can run,
right? Only in some cases (mainly when the incumbent
is there), nobody else bothers to. In this case, a
multi shows the possibility of declaring other
routines with the same name and different signature,
unlike only which says "Nope, you can't".
As a matter of fact, there are several of them.
https://github.com/rakudo/rakudo/search?q=%22method+starts-with%22&unscoped_q=%22method+starts-with%22
However, in this case we made the call of putting
them in a single definition, since the existence
of different ones is simply an implementation
detail.
So JJ confirmed that the method was indeed a multi method
but that he WOULD NOT include the other definitions
as it is an "implementation detail". This makes the
documentation "incomplete" and frustrating as it
is not apparent if it is just incomplete or is it
inaccurate.
Now I think he should have corrects the documentation
to make it complete or at least referenced the link he
included, which (to repeat) was
https://github.com/rakudo/rakudo/search?q=%22method+starts-with%22&unscoped_q=%22method+starts-with%22
proto method starts-with(|) {*}
multi method starts-with(Cool:D:
Cool:D $needle, :i(:$ignorecase)!, :m(:$ignoremark) --> Bool:D) {
self.Str.starts-with($needle.Str, :$ignorecase, :$ignoremark)
}
multi method starts-with(Cool:D:
Cool:D $needle, :m(:$ignoremark)! --> Bool:D) {
Now that would have documented the method properly.
And yes, we have a long way to go to gets our documentation
to the elegance of Perl 5's PerlDocs, but it should be our
goal.
Our documentation right now is incomplete, often inaccurate,
and targets the wrong audience -- those who already know
what they are doing and do not need the documentation.
The documentation targets experts and not beginners.
It needs to target both.
So basically, my gripe here is the with the documentation.
If you state "multi method", SHOW ALL OF THEM, not just
the easy one(s).
-T