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
signature.asc
Description: PGP signature