On 09/13/2017 01:36 PM, Trey Harris 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.

Hi Trey,

Thank you!  I just started to read it, but have to
come back later.  If yo manger to make me understand those
two line, you will be my hero!

-T

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Computers are like air conditioners.
They malfunction when you open windows
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Reply via email to