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