On 2020-06-07 14:20, Peter Pentchev wrote:
On Sun, Jun 07, 2020 at 12:28:33PM -0700, ToddAndMargo via perl6-users wrote:
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-users@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`

[snip]

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".

This is actually very, very common in object-oriented programming.
You create a new class, you have a couple of methods that you know will
be useful to others, so you declare them as multi in Raku or, say,
virtual in C++. Then you add a couple of other methods, and you stop and
think "hm, okay, so right now I don't have a need to use this method in
another way or override it in another class, but what it does is pretty
general, easily extensible, so, yeah, it is very much possible that
tomorrow I (or somebody else) will need to redefine or extend it" - and
that's why you put a "multi" on a method that *right now* has no real
use for it, but it will have one tomorrow.

I do not have an example in mind right now, but I bet that if I look
through some of the modules found at https://modules.raku.org/ I can
find classes that redefine or extend some really basic methods in
Raku's base classes. This is only possible because the developers of
Raku decided to declare them as "multi" even though they had no
immediate use for that right at that moment.

      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.

I wouldn't go that far. For the .starts-with() method, the three
signatures that Raku gives as possible candidates in the error message
that started this whole thing, one of them actually encompasses the
other two. The fact that the other two exist does not matter *at all* to
the person who uses the .starts-with() method, except in some very,
very, *very* weird cases that you and I will almost certainly not have
to write code for in the next five years.

Let's go back to that error message once more:

(Str:D: Str:D $needle, :i(:$ignorecase)!, :m(:$ignoremark), *%_ --> Bool)
(Str:D: Str:D $needle, :m(:$ignoremark)!, *%_ --> Bool)
(Str:D: Str:D $needle, *%_ --> Bool)

So what do we see here?

- first, we see a method that accepts a string parameter called "needle"
   and two optional boolean parameters, "ignorecase" that may be written
   as "i" and "ignoremark" that can be written as "m".

- second, we see a method that accepts a string parameter called
   "needle" and an optional boolean parameter "ignoremark" that may be
   written as "m"... but wait, how is that different from the one above
   if "ignorecase" is optional? For the programmer who uses these
   methods, it is not - it *does not matter at all*.

- third, we see a method that accepts a string parameter called "needle"
   and may possibly accept anything else you decide to pass to it.
   The thing is, you really don't need to know about this one at all -
   I *think* it is there to allow other classes derived from Str to pass
   more parameters, or to allow the .starts-with() method to be invoked
   for other invocants, for things that are not strings. But you and I
   will *never* need to know that, since we know that Str.starts-with()
   accepts a single positional and two optional named parameters, and
   that's all that we are going to pass to it in our programs.

So... the way the method is implemented in this particular compiler of
Raku allows the Raku developers to do some interesting things in other
classes and allows them to make the Raku compiler easier for you and me
to use. This *does not matter* for us, we *don't need to know* about it,
we need to know that we must pass the "needle" parameter and that we may
also, if we wish, pass "i" or "m" or "ignorecase" or "ignorematch" or
(almost) any combination of those.

"Implementation detail" is an important concept in programming. Many
languages have specifications (as Raku does), which allows people to
write *different* implementations of the language; I seem to remember
that there was, say, a Raku compiler written in Java. The specification
says "this class will have this method with these parameters, this other
method with these other parameters, and will implement this role".
The implementation *does not* (and *must not*) say "this class may not
possibly have any other methods, you are forbidden to make extensions
that may make your job easier or that may be tested and then one day
become standard in the next edition of this specification". You and I
need to know what the specification says. You and I do not need to know
most of the details about how the Raku developers decided to implement it.
So, if the Raku developers decide that some particular method is part of
their internal implementation, that's fine with me - I'll let them use
it to make their lives easier, I'll let them use it so that they can do
something else to make my life easier, and even if I notice it, I *will
not* use it if it is not documented, since I know that it is internal,
it does not concern me, it may disappear or change in the next version,
and that's completely fine with me.

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.

Yeah, well, no. All of this is *not needed*. The Cool class is a great
thing that *we don't need to know about* when we write programs that use
the classes that are derived from it. In the very rare case when we
decide to declare a class that is derived from Int and we wonder why it
has a .subst() method that treats it as a string, then we may
wonder and then we'll look at the Cool class's documentation and read
what it does. Until we do that, we don't care.

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...

As seen above, this is arguable.

often inaccurate...

"Often" might be a bit too much here.

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.

The current documentation is a combination of a reference manual that,
yes, does depend on the reader having some grasp of some basic concepts,
and some tutorials. More tutorials are being written as time passes.

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).

Well, as explained above, there are some cases when there really are
*not* any more (but there may be in some Raku module), and then there
are other cases when they *must not* be shown to the programmer, since
the programmer *must not* use them. So the documentation is correct in
its goal of documenting what the programmer is supposed to use.

Ironically, the people who should know about the internal methods,
the ones that were described as "implementation details", are... people
working on the Raku compiler themselves, those who are even a bit above
the experts :)

G'luck,
Peter



Hi Peter,

You make many wonderful points.

My criticism is

1) if you are finished with the development of a method
and it is a "only" document it as such.  If you later
change your mind and want to add something to it, then
update the manual to reflect your changes. It shuold
be all a part of the code check in process.  DO NOT
leave the reader of the manual wondering what is
missing.

2) in the case where things are part of the distribution,
put them in the manual.  For instance:


https://github.com/rakudo/rakudo/search?q=%22method+starts-with%22&unscoped_q=%22method+starts-with%22

If it is not internal or experimental (which are exempted),
it belongs in the manual.  Published parts of the distribution
should not be kept secret from the user.  Who the heck want
to go to github to find how to use a function?

3) the manual should respect who is reading it.  Currently
it is only a refresher for those who already know what is
going on.  It need to be both understandable by both beginners
and experts.

Currently it is like pulling teeth to get abetter wording
and/or examples added to the manual.  This is anti-kaisen.
Here is an example:

     RFE: add some links to Operators
     https://github.com/Raku/doc/issues/3175

The rejections was:
     " I don't really think we should go down to that level of detail.

Don't get me wrong.  I ADORE Raku.  The more I learn,
the more I adore it.  My only beef is with the documentation.
Raku's documentation should be to reach the eloquence of
Perl 5's PerlDocs: usable for both beginners and experts
and covers all published aspects of the functions it describes.

-T

Reply via email to