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-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`
> > > 
[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

-- 
Peter Pentchev  r...@ringlet.net r...@debian.org p...@storpool.com
PGP key:        http://people.FreeBSD.org/~roam/roam.key.asc
Key fingerprint 2EE7 A7A5 17FC 124C F115  C354 651E EFB0 2527 DF13

Attachment: signature.asc
Description: PGP signature

Reply via email to