Thanks for that Trey! Previously I would just glance at those definitions and move straight to the examples. Now I can read them!
Something like this explanation should be on a docs.perl6.org page. Maybe it is and I've just not found it. On 14 September 2017 at 06:36, Trey Harris <t...@lopsa.org> wrote: > On Sat, Sep 9, 2017 at 3:55 PM ToddAndMargo toddandma...@zoho.com > <http://mailto:toddandma...@zoho.com> wrote: > > On 09/09/2017 07:00 AM, Timo Paulssen wrote: >> > This should be enlightening: https://docs.perl6.org/routine/getc >> > >> >> Problem: also from the link: >> >> method getc(IO::Handle:D: --> Str:D) >> multi sub getc (IO::Handle $fh = $*ARGFILES --> Str:D) >> >> This is very frustrating to me as it mean ABSOLUTELY NOTHING >> to me. Without an example, which the link does not provide, >> I have not the slightest idea what they are talking about. >> > So excuse my going off-topic here, but I hear your frustration and think > you’ll find it valuable to learn what you need to know to not be frustrated > rather than hoping the docs will over time get more verbose with sundry > examples for each possible use of language features (it probably won’t, for > the most part). > > If you’re coming from Perl 5, which is mostly an explicit-type-less > language, or many other minimally or dynamically-typed languages, these > cryptic lines *can* be frustrating; learning-by-example is usually the > best way to “grok” a feature intuitively. > > I think it’s important to learn to read them, rather than simply ask for > examples (as drove most of the P5 perldoc for builtins). To explain why: in > Haskell, a language which greatly influenced Perl 6, the type declarations > alone are often all the Haskell programmer needs to fully understand a > function; prose or examples are entirely superfluous. The power of well- > and expressively-typed routines for documentation is inarguable in > efficiency, precision, and concision. The downside is the necessary > investment in overcoming the learning curve required to read them. > > To return to the lines that frustrated you, let’s try to make them > understandable—or, at least, make them mean more to you than “ABSOLUTELY > NOTHING”. :-) > > Let’s start at a high level: > > method getc(IO::Handle:D: --> Str:D) # L1 > multi sub getc (IO::Handle $fh = $*ARGFILES --> Str:D) # L2 > > You see getc defined twice here; they’re each distinct code (that are > documented once because they do much the same thing) due to their > *declarators*. > > L1 is an “ordinary method” (denoted, obviously enough, with the declarator > method), which as described in the Typesystem > <https://docs.perl6.org/language/typesystem#Methods> doc, “defines > objects of type Method <https://docs.perl6.org/type/Method> and binds > them to the provided name in the scope of a class.” An ordinary method is > usually called using dot syntax, i.e., $object.getc(...). > > L2 is a “multisub”, that is, a sub handled via “multi-dispatch” (in most > languages with the concept, called multimethod dispatch). Multi-dispatch > allows a single routine name to refer to different code (“polymorphism”) on > axes other than the traditional object-oriented paradigm of “invocant” to > include number, type, definedness, and even value of arguments at call > time. (In this case, there being only one, it may seem superfluous, but it > allows for other modules to introduce getc variants of their own without > having to invent new names or muck about with namespaces.) Being a sub, it > will be called most often using normal sub-calling syntax, such as > getc($x). > > Now let’s turn to the *return values,* which are what functional > programmers are usually looking at first. They’re marked by --> (though > some old documentation may use returns). Conveniently, both variants L1 > and L2 return the same thing (not uncommon, for multi routines): Str:D. > The Str part is a reference to the string type Str > <https://docs.perl6.org/type/Str>. The :D suffix says that the value is > *defined*; in other words, getc will never return the undefined value. (A > :U suffix would indicate that the return is always *undefined*; the > default, a lack of any suffix, can be made explicit with :_, and means—as > in Perl 5—that the return might or might not be defined.) > > That gets you to the *arguments* of the two variants. Each are *unary;* > they take just one argument. > > (In the case of the method, its arity depends on your definition of the > invocant being an argument; if you subscribe to the view that a method’s > invocant doesn’t count, then method getc is a nullary, taking no > argument. But the view that the invocant counts as an argument is useful > here, so let’s use that definition, making the two both unary routines.) > > Both routines’ single argument is of type IO::Handle. They also both > require definedness, but in different ways. The method uses the :D suffix > we’ve already seen; in effect, that allows $my-handle.getc to work > provided $my-handle has been set to a defined IO::Handle object. But if > the variable was declared with my IO::Handle $my-handle; but never > assigned to, $my-handle.getc will not work; neither will IO::Handle.getc > (which would work if :D weren’t included in the signature; one way of > getting “class methods” in Perl 6 is to create methods with :U invocants). > > The multisub L2 also requires definedness, but does it in a different way. > The IO::Handle $fh, by itself, doesn’t rule out an undefined argument > being assigned to the $fh parameter, but the *default value* expressed by = > $*ARGFILES ensures that an omitted or undefined argument will cause $fh > to be assigned the value $*ARGFILES. (The $* notation is used to refer to > global variables; you can look up the definition of $*ARGFILES > <https://docs.perl6.org/language/variables#index-entry-%24%2AARGFILES> to > see it is > > An IO::CatHandle that uses @*ARGS as source files, if it contains any > files, or $*IN otherwise > > and you can also look up IO::CatHandle > <https://docs.perl6.org/type/IO::CatHandle> and $*IN > <https://docs.perl6.org/language/variables#index-entry-%24%2AIN> in the > docs if you want to know more). > > The point of all this is to not require exhaustive examples to show you > possible ways of calling getc; you just need to know how to unlock the > code. > > Putting it all together, it tells you that these are valid examples: > > my Str $chr = getc($*IN); # insist on STDIN, even if file arguments were > given on the command line > $chr = "/dev/tty".IO.open.getc; # Insist not just on STDIN, but on the POSIX > tty > > Learning to read the Perl 6 doc <https://docs.perl6.org/> signatures may > be frustrating at first, but it’s well worth it, and pays dividends. > > -- Norman Gaywood, Computer Systems Officer School of Science and Technology University of New England Armidale NSW 2351, Australia ngayw...@une.edu.au http://turing.une.edu.au/~ngaywood Phone: +61 (0)2 6773 2412 Mobile: +61 (0)4 7862 0062 Please avoid sending me Word or Power Point attachments. See http://www.gnu.org/philosophy/no-word-attachments.html